Skip to content

Commit

Permalink
avoid an extra lookup in delEntryPtr.
Browse files Browse the repository at this point in the history
  • Loading branch information
coocood committed Feb 26, 2019
1 parent 9c54a22 commit 8ff04dc
Showing 1 changed file with 23 additions and 23 deletions.
46 changes: 23 additions & 23 deletions segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ func (seg *segment) set(key, value []byte, hashVal uint64, expireSeconds int) (e
var hdrBuf [ENTRY_HDR_SIZE]byte
hdr := (*entryHdr)(unsafe.Pointer(&hdrBuf[0]))

slotOff := int32(slotId) * seg.slotCap
slot := seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
idx, match := seg.lookup(slot, hash16, key)
if match {
matchedPtr := &slot[idx]
Expand All @@ -107,8 +106,7 @@ func (seg *segment) set(key, value []byte, hashVal uint64, expireSeconds int) (e
return
}
// avoid unnecessary memory copy.
seg.delEntryPtr(slotId, hash16, slot[idx].offset)
//seg.delEntryPtr(slotId, hash16, seg.slotsData[idx].offset)
seg.delEntryPtr(slotId, slot, idx)
match = false
// increase capacity and limit entry len.
for hdr.valCap < hdr.valLen {
Expand All @@ -135,7 +133,7 @@ func (seg *segment) set(key, value []byte, hashVal uint64, expireSeconds int) (e
if slotModified {
// the slot has been modified during evacuation, we need to looked up for the 'idx' again.
// otherwise there would be index out of bound error.
slot = seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot = seg.getSlot(slotId)
idx, match = seg.lookup(slot, hash16, key)
// assert(match == false)
}
Expand Down Expand Up @@ -169,7 +167,7 @@ func (seg *segment) evacuate(entryLen int64, slotId uint8, now uint32) (slotModi
expired := oldHdr.expireAt != 0 && oldHdr.expireAt < now
leastRecentUsed := int64(oldHdr.accessTime)*atomic.LoadInt64(&seg.totalCount) <= atomic.LoadInt64(&seg.totalTime)
if expired || leastRecentUsed || consecutiveEvacuate > 5 {
seg.delEntryPtr(oldHdr.slotId, oldHdr.hash16, oldOff)
seg.delEntryPtrByOffset(oldHdr.slotId, oldHdr.hash16, oldOff)
if oldHdr.slotId == slotId {
slotModified = true
}
Expand All @@ -194,8 +192,7 @@ func (seg *segment) evacuate(entryLen int64, slotId uint8, now uint32) (slotModi
func (seg *segment) get(key []byte, hashVal uint64) (value []byte, expireAt uint32, err error) {
slotId := uint8(hashVal >> 8)
hash16 := uint16(hashVal >> 16)
slotOff := int32(slotId) * seg.slotCap
var slot = seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
idx, match := seg.lookup(slot, hash16, key)
if !match {
err = ErrNotFound
Expand All @@ -211,7 +208,7 @@ func (seg *segment) get(key []byte, hashVal uint64) (value []byte, expireAt uint
expireAt = hdr.expireAt

if hdr.expireAt != 0 && hdr.expireAt <= now {
seg.delEntryPtr(slotId, hash16, ptr.offset)
seg.delEntryPtr(slotId, slot, idx)
atomic.AddInt64(&seg.totalExpired, 1)
err = ErrNotFound
atomic.AddInt64(&seg.missCount, 1)
Expand All @@ -230,22 +227,19 @@ func (seg *segment) get(key []byte, hashVal uint64) (value []byte, expireAt uint
func (seg *segment) del(key []byte, hashVal uint64) (affected bool) {
slotId := uint8(hashVal >> 8)
hash16 := uint16(hashVal >> 16)
slotOff := int32(slotId) * seg.slotCap
slot := seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
idx, match := seg.lookup(slot, hash16, key)
if !match {
return false
}
ptr := &slot[idx]
seg.delEntryPtr(slotId, hash16, ptr.offset)
seg.delEntryPtr(slotId, slot, idx)
return true
}

func (seg *segment) ttl(key []byte, hashVal uint64) (timeLeft uint32, err error) {
slotId := uint8(hashVal >> 8)
hash16 := uint16(hashVal >> 16)
slotOff := int32(slotId) * seg.slotCap
var slot = seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
idx, match := seg.lookup(slot, hash16, key)
if !match {
err = ErrNotFound
Expand Down Expand Up @@ -280,8 +274,7 @@ func (seg *segment) expand() {
}

func (seg *segment) updateEntryPtr(slotId uint8, hash16 uint16, oldOff, newOff int64) {
slotOff := int32(slotId) * seg.slotCap
slot := seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
idx, match := seg.lookupByOff(slot, hash16, oldOff)
if !match {
return
Expand All @@ -291,27 +284,29 @@ func (seg *segment) updateEntryPtr(slotId uint8, hash16 uint16, oldOff, newOff i
}

func (seg *segment) insertEntryPtr(slotId uint8, hash16 uint16, offset int64, idx int, keyLen uint16) {
slotOff := int32(slotId) * seg.slotCap
if seg.slotLens[slotId] == seg.slotCap {
seg.expand()
slotOff *= 2
}
seg.slotLens[slotId]++
atomic.AddInt64(&seg.entryCount, 1)
slot := seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
slot := seg.getSlot(slotId)
copy(slot[idx+1:], slot[idx:])
slot[idx].offset = offset
slot[idx].hash16 = hash16
slot[idx].keyLen = keyLen
}

func (seg *segment) delEntryPtr(slotId uint8, hash16 uint16, offset int64) {
slotOff := int32(slotId) * seg.slotCap
slot := seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
func (seg *segment) delEntryPtrByOffset(slotId uint8, hash16 uint16, offset int64) {
slot := seg.getSlot(slotId)
idx, match := seg.lookupByOff(slot, hash16, offset)
if !match {
return
}
seg.delEntryPtr(slotId, slot, idx)
}

func (seg *segment) delEntryPtr(slotId uint8, slot []entryPtr, idx int) {
offset := slot[idx].offset
var entryHdrBuf [ENTRY_HDR_SIZE]byte
seg.rb.ReadAt(entryHdrBuf[:], offset)
entryHdr := (*entryHdr)(unsafe.Pointer(&entryHdrBuf[0]))
Expand Down Expand Up @@ -395,3 +390,8 @@ func (seg *segment) clear() {
atomic.StoreInt64(&seg.totalExpired, 0)
atomic.StoreInt64(&seg.overwrites, 0)
}

func (seg *segment) getSlot(slotId uint8) []entryPtr {
slotOff := int32(slotId) * seg.slotCap
return seg.slotsData[slotOff : slotOff+seg.slotLens[slotId] : slotOff+seg.slotCap]
}

0 comments on commit 8ff04dc

Please sign in to comment.