Skip to content

Commit e25a42e

Browse files
committed
Back to BTree with some minor changes
1 parent 16ec488 commit e25a42e

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

cache.go

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"sync"
66
"sync/atomic"
77
"time"
8+
9+
"github.com/emirpasic/gods/trees/btree"
810
)
911

1012
// Internal cache errors
@@ -31,8 +33,8 @@ type AtomicCache struct {
3133
// Deadlock mutex for debugging purpose.
3234
// deadlock.RWMutex
3335

34-
// Lookup structure used for global index. It is based on hashtable structure.
35-
lookup map[string]LookupRecord
36+
// Lookup structure used for global index. It is based on BTree structure.
37+
lookup *btree.Tree
3638

3739
// Shards lookup tables which contains information about shards sections.
3840
smallShards, mediumShards, largeShards ShardsLookup
@@ -86,7 +88,7 @@ type LookupRecord struct {
8688
}
8789

8890
// BufferItem is used for buffer, which contains all unattended cache set
89-
// requrest.
91+
// request.
9092
type BufferItem struct {
9193
Key []byte
9294
Data []byte
@@ -103,7 +105,7 @@ func New(opts ...Option) *AtomicCache {
103105
MaxShardsSmall: 256,
104106
MaxShardsMedium: 128,
105107
MaxShardsLarge: 64,
106-
GcStarter: 5000,
108+
GcStarter: 25000,
107109
}
108110

109111
for _, opt := range opts {
@@ -114,7 +116,7 @@ func New(opts ...Option) *AtomicCache {
114116
cache := &AtomicCache{}
115117

116118
// Init lookup table
117-
cache.lookup = make(map[string]LookupRecord)
119+
cache.lookup = btree.NewWithStringComparator(3)
118120

119121
// Init small shards section
120122
initShardsSection(&cache.smallShards, options.MaxShardsSmall, options.MaxRecords, options.RecordSizeSmall)
@@ -163,15 +165,15 @@ func (a *AtomicCache) Set(key []byte, data []byte, expire time.Duration) error {
163165
shardSection, shardSectionID := a.getShardsSectionBySize(len(data))
164166

165167
a.Lock()
166-
if ival, ok := a.lookup[string(key)]; !ok {
168+
if ival, ok := a.lookup.Get(string(key)); !ok {
167169
new = true
168170
} else {
169-
val := ival
171+
val := ival.(LookupRecord)
170172

171173
if val.ShardSection != shardSectionID {
172174
shardSection.shards[val.ShardIndex].Free(val.RecordIndex)
173175
val.RecordIndex = shardSection.shards[val.ShardIndex].Set(data)
174-
a.lookup[string(key)] = LookupRecord{ShardIndex: val.ShardIndex, ShardSection: shardSectionID, RecordIndex: val.RecordIndex, Expiration: a.getExprTime(expire)}
176+
a.lookup.Put(string(key), LookupRecord{ShardIndex: val.ShardIndex, ShardSection: shardSectionID, RecordIndex: val.RecordIndex, Expiration: a.getExprTime(expire)})
175177
} else {
176178
prevShardSection := a.getShardsSectionByID(val.ShardSection)
177179
prevShardSection.shards[val.ShardIndex].Free(val.RecordIndex)
@@ -182,11 +184,11 @@ func (a *AtomicCache) Set(key []byte, data []byte, expire time.Duration) error {
182184
if new {
183185
if si, ok := a.getShard(shardSectionID); ok {
184186
ri := shardSection.shards[si].Set(data)
185-
a.lookup[string(key)] = LookupRecord{ShardIndex: si, ShardSection: shardSectionID, RecordIndex: ri, Expiration: a.getExprTime(expire)}
187+
a.lookup.Put(string(key), LookupRecord{ShardIndex: si, ShardSection: shardSectionID, RecordIndex: ri, Expiration: a.getExprTime(expire)})
186188
} else if si, ok := a.getEmptyShard(shardSectionID); ok {
187189
shardSection.shards[si] = NewShard(a.MaxRecords, a.getRecordSizeByShardSectionID(shardSectionID))
188190
ri := shardSection.shards[si].Set(data)
189-
a.lookup[string(key)] = LookupRecord{ShardIndex: si, ShardSection: shardSectionID, RecordIndex: ri, Expiration: a.getExprTime(expire)}
191+
a.lookup.Put(string(key), LookupRecord{ShardIndex: si, ShardSection: shardSectionID, RecordIndex: ri, Expiration: a.getExprTime(expire)})
190192
} else {
191193
if len(a.buffer) <= int(a.MaxRecords) {
192194
a.buffer = append(a.buffer, BufferItem{Key: key, Data: data, Expire: expire})
@@ -215,7 +217,8 @@ func (a *AtomicCache) Get(key []byte) ([]byte, error) {
215217
var hit = false
216218

217219
a.RLock()
218-
if val, ok := a.lookup[string(key)]; ok {
220+
if ival, ok := a.lookup.Get(string(key)); ok {
221+
val := ival.(LookupRecord)
219222
shardSection := a.getShardsSectionByID(val.ShardSection)
220223

221224
if shardSection.shards[val.ShardIndex] != nil && time.Now().Before(val.Expiration) {
@@ -355,14 +358,16 @@ func (a *AtomicCache) getExprTime(expire time.Duration) time.Time {
355358
// active shard).
356359
func (a *AtomicCache) collectGarbage() {
357360
a.Lock()
358-
for k, v := range a.lookup {
361+
for _, k := range a.lookup.Keys() {
362+
iv, _ := a.lookup.Get(k.(string)) // get record
363+
v := iv.(LookupRecord) // convert record from interface to LookupRecord
359364
shardSection := a.getShardsSectionByID(v.ShardSection) // get shard section
360365
if time.Now().After(v.Expiration) {
361366
shardSection.shards[v.ShardIndex].Free(v.RecordIndex)
362367
if len(shardSection.shardsActive) > 1 {
363368
a.releaseShard(v.ShardSection, v.ShardIndex)
364369
}
365-
delete(a.lookup, k)
370+
a.lookup.Remove(k)
366371
}
367372
}
368373

0 commit comments

Comments
 (0)