github.com/coocood/badger@v1.5.1-0.20200528065104-c02ac3616d04/table/sstable/hash_index.go (about) 1 package sstable 2 3 import ( 4 "encoding/binary" 5 ) 6 7 const ( 8 resultNoEntry = 65535 9 resultFallback = 65534 10 maxBlockCnt = 65533 11 ) 12 13 type hashEntry struct { 14 entryPosition 15 hash uint64 16 } 17 18 type entryPosition struct { 19 // blockIdx is the index of block which contains this key. 20 blockIdx uint16 21 22 // offset is the index of this key in block. 23 offset uint8 24 } 25 26 func (e *entryPosition) encode() []byte { 27 b := make([]byte, 3) 28 binary.LittleEndian.PutUint16(b, e.blockIdx) 29 b[2] = e.offset 30 return b 31 } 32 33 func (e *entryPosition) decode(b []byte) { 34 e.blockIdx = binary.LittleEndian.Uint16(b) 35 e.offset = b[2] 36 } 37 38 func buildHashIndex(hashEntries []hashEntry, hashUtilRatio float32) []byte { 39 if len(hashEntries) == 0 { 40 return u32ToBytes(0) 41 } 42 43 numBuckets := uint32(float32(len(hashEntries)) / hashUtilRatio) 44 buf := make([]byte, numBuckets*3+4) 45 copy(buf, u32ToBytes(numBuckets)) 46 buckets := buf[4:] 47 for i := 0; i < int(numBuckets); i++ { 48 binary.LittleEndian.PutUint16(buckets[i*3:], resultNoEntry) 49 } 50 51 for _, h := range hashEntries { 52 idx := h.hash % uint64(numBuckets) 53 bucket := buckets[idx*3 : (idx+1)*3] 54 blkIdx := binary.LittleEndian.Uint16(bucket[:2]) 55 if blkIdx == resultNoEntry { 56 binary.LittleEndian.PutUint16(bucket[:2], h.blockIdx) 57 bucket[2] = h.offset 58 } else if blkIdx != h.blockIdx { 59 binary.LittleEndian.PutUint16(bucket[:2], resultFallback) 60 } 61 } 62 63 return buf 64 } 65 66 type hashIndex struct { 67 buckets []byte 68 numBuckets int 69 } 70 71 func (i *hashIndex) readIndex(buf []byte) { 72 i.numBuckets = int(bytesToU32(buf[:4])) 73 i.buckets = buf[4:] 74 } 75 76 func (i *hashIndex) lookup(keyHash uint64) (uint32, uint8) { 77 if i.buckets == nil { 78 return resultFallback, 0 79 } 80 idx := keyHash % uint64(i.numBuckets) 81 buf := i.buckets[idx*3:] 82 blkIdx := binary.LittleEndian.Uint16(buf) 83 return uint32(blkIdx), uint8(buf[2]) 84 }