github.com/leslie-fei/fastcache@v0.0.0-20240520092641-b7a9eb05711f/hashmap.go (about) 1 package fastcache 2 3 import ( 4 "errors" 5 "unsafe" 6 ) 7 8 var ( 9 ErrNotFound = errors.New("key not found") 10 ErrValueTooLarge = errors.New("value too large") 11 ErrKeyTooLarge = errors.New("key too large") 12 ) 13 14 // hashMap fixed size of hashmap 15 type hashMap struct { 16 len uint32 17 bucketLen uint32 18 } 19 20 func (m *hashMap) Get(base uintptr, hash uint64, key string) (*DataNode, []byte, error) { 21 item := m.bucket(base, hash) 22 _, findNode, findEl := item.FindNode(base, key) 23 if findEl == nil { 24 return nil, nil, ErrNotFound 25 } 26 value := findEl.Value() 27 return findNode, value, nil 28 } 29 30 func (m *hashMap) Add(base uintptr, hash uint64, node *DataNode) { 31 item := m.bucket(base, hash) 32 // 更新list链表, 头插法 33 item.Add(base, node) 34 m.len++ 35 } 36 37 func (m *hashMap) Del(base uintptr, hash uint64, prev *DataNode, node *DataNode) (err error) { 38 item := m.bucket(base, hash) 39 if err = item.Del(prev, node); err != nil { 40 return 41 } 42 m.len-- 43 return 44 } 45 46 func (m *hashMap) FindNode(base uintptr, hash uint64, key string) (prevNode *DataNode, findNode *DataNode, findEl *hashMapBucketElement) { 47 item := m.bucket(base, hash) 48 return item.FindNode(base, key) 49 } 50 51 func (m *hashMap) bucket(base uintptr, hash uint64) *hashMapBucket { 52 index := hash % uint64(m.bucketLen) 53 headPtr := uintptr(unsafe.Pointer(m)) + sizeOfHashmap 54 bucketPtr := uintptr(index*uint64(sizeOfHashmapBucket)) + headPtr 55 return (*hashMapBucket)(unsafe.Pointer(bucketPtr)) 56 }