1package slab
2
3type slabEntry struct {
4	Value interface{}
5	Index uintptr
6}
7
8func (entry slabEntry) IsValid() bool {
9	return entry.Value != nil
10}
11
12// Slab is an implementation of the internal registry free list. A zero-value
13// instance is a valid instance. This data structure is not thread-safe.
14type Slab struct {
15	entries []slabEntry
16	free    uintptr
17}
18
19func (s *Slab) Put(entry interface{}) uintptr {
20	if s.free == uintptr(len(s.entries)) {
21		index := uintptr(len(s.entries))
22		s.entries = append(s.entries, slabEntry{entry, 0})
23		s.free++
24		return index
25	}
26
27	index := s.free
28
29	s.free = s.entries[index].Index
30	s.entries[index] = slabEntry{entry, 0}
31
32	return index
33}
34
35func (s *Slab) Get(i uintptr) interface{} {
36	// Perform bound check.
37	if i >= uintptr(len(s.entries)) {
38		return nil
39	}
40	// Perform validity check in case of invalid ID.
41	if entry := s.entries[i]; entry.IsValid() {
42		return entry.Value
43	}
44	return nil
45}
46
47func (s *Slab) Pop(i uintptr) interface{} {
48	popped := s.entries[i].Value
49	s.entries[i] = slabEntry{nil, s.free}
50	s.free = i
51	return popped
52}
53