Skip to content

Commit

Permalink
bucket: inplace update without key comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
qianbin committed May 22, 2022
1 parent 0f08945 commit cb00f51
Showing 1 changed file with 15 additions and 11 deletions.
26 changes: 15 additions & 11 deletions bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,22 @@ func (b *bucket) Set(key []byte, keyHash uint64, val []byte) bool {
b.lock.Lock()
defer b.lock.Unlock()

entrySize := entrySize(len(key), len(val), 0)
if entrySize > b.q.Cap() {
return false
}

if offset, found := b.m[keyHash]; found {
ent := b.entryAt(offset)
if bytes.Equal(ent.Key(), key) && ent.UpdateValue(val) { // in-place update
ent.AddFlag(recentlyUsedFlag)
if spare := ent.BodySize() - len(key) - len(val); spare >= 0 { // in-place update
ent.Init(key, val, spare)
ent.AddFlag(recentlyUsedFlag) // avoid evicted too early
return true
}
// key not matched or in-place update failed
ent.AddFlag(deletedFlag)
}
// insert new entry
b.m[keyHash] = b.insertEntry(key, val, 0, entrySize)
return true
if offset, ok := b.insertEntry(key, val, 0); ok {
b.m[keyHash] = offset
return true
}
return false
}

// Del deletes the key.
Expand Down Expand Up @@ -100,13 +99,18 @@ func (b *bucket) entryAt(offset int) entry {

// insertEntry insert a new entry and returns its offset.
// Old entries are evicted like LRU strategy if no enough space.
func (b *bucket) insertEntry(key, val []byte, spare, entrySize int) int {
func (b *bucket) insertEntry(key, val []byte, spare int) (int, bool) {
entrySize := entrySize(len(key), len(val), spare)
if entrySize > b.q.Cap() {
return 0, false
}

pushLimit := 8
for {
// have a try
if offset, ok := b.q.Push(nil, entrySize); ok {
entry(b.q.Slice(offset)).Init(key, val, spare)
return offset
return offset, true
}

// no space
Expand Down

0 comments on commit cb00f51

Please sign in to comment.