-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshard.go
78 lines (67 loc) · 1.87 KB
/
shard.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package atomiccache
import (
"sync"
)
// Shard structure contains multiple slots for records.
type Shard struct {
sync.RWMutex
slotAvail []int
slots []*Record
}
// NewShard initialize list of records with specified size. List is stored
// in property records and every record has it's own unique id (id is not
// propagated to record instance). Argument slotCount represents number of
// records in shard and slotSize represents size of one record.
func NewShard(slotCount, slotSize int) *Shard {
shard := &Shard{}
// Initialize available slots stack
for i := 0; i < slotCount; i++ {
shard.slotAvail = append(shard.slotAvail, i)
}
// Initialize record list
for i := 0; i < slotCount; i++ {
shard.slots = append(shard.slots, NewRecord(slotSize))
}
return shard
}
// Set store data as a record and decrease slotAvail count. On output it return
// index of used slot.
func (s *Shard) Set(data []byte) (i int) {
s.Lock() // Lock for writing and reading
i, s.slotAvail = s.slotAvail[0], s.slotAvail[1:]
s.slots[i].Set(data)
s.Unlock() // Unlock for writing and reading
return
}
// Get returns bytes from shard memory based on index. If array on output is
// empty, then record is not exists.
func (s *Shard) Get(index int) (v []byte) {
s.RLock()
v = s.slots[index].Get()
s.RUnlock()
return
}
// Free empty memory specified by index on input and increase slot counter.
func (s *Shard) Free(index int) {
s.Lock()
s.slots[index].Free()
s.slotAvail = append(s.slotAvail, index)
s.Unlock()
}
// GetSlotsAvail returns number of available memory slots of shard.
func (s *Shard) GetSlotsAvail() (cnt int) {
s.RLock()
cnt = len(s.slotAvail)
s.RUnlock()
return
}
// IsEmpty return true if shard has no record registered. Otherwise return
// false.
func (s *Shard) IsEmpty() (result bool) {
s.RLock()
if len(s.slotAvail) == len(s.slots) {
result = true
}
s.RUnlock()
return
}