package spanpool import "core:slice" Element :: struct($E: typeid) { value: $T, gen: i32, } Span :: struct { first, len: i32, } Span_Pool :: struct($E: typeid) { elems: [dynamic]Element(E), free_spans: [dynamic]Span, } Handle :: struct { first: i32, len: i32, gen: i32, } allocate :: proc(s: ^$T/Span_Pool($E), elems: []T) -> (handle: Handle) { handle = _allocate(s, len(elems)) for i in 0.. (handle: Handle) { handle.len = count maybe_existing_span: Maybe(i32) for span, i in s.free_spans { if span.len >= count { maybe_existing_span = i break } } existing_span, ok := maybe_existing_span.? if ok { span := s.free_spans[existing_span] handle.first = span.first new_len := span.len - count if new_len == 0 { ordered_remove(&s.free_spans, existing_span) } else { s.free_spans[existing_span].first += count s.free_spans[existing_span].len = new_len } } else { handle.first = len(s.elems) resize(&s.elems, len(s.elems) + count) } // Now figure out the generation index max_gen := 0 for i in handle.first..