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  }