github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/internal/cache/lrucache/lrucache.go (about) 1 // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package lrucache 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 21 "github.com/zuoyebang/bitalosdb/internal/cache" 22 "github.com/zuoyebang/bitalosdb/internal/hash" 23 "github.com/zuoyebang/bitalosdb/internal/options" 24 ) 25 26 var _ cache.ICache = (*LruCache)(nil) 27 28 func New(opts *options.CacheOptions) cache.ICache { 29 return newShards(opts) 30 } 31 32 func NewLrucache(opts *options.CacheOptions) *LruCache { 33 return newShards(opts) 34 } 35 36 func (lrc *LruCache) decodeValue(key, eval []byte) []byte { 37 cLen := len(eval) 38 if eval == nil || cLen <= 4 { 39 return nil 40 } 41 42 kLen := int(binary.BigEndian.Uint32(eval[0:4])) 43 vPos := 4 + kLen 44 if cLen <= vPos || !bytes.Equal(key, eval[4:vPos]) { 45 return nil 46 } 47 48 return eval[vPos:] 49 } 50 51 func (lrc *LruCache) GetKeyHash(_ []byte) uint32 { 52 return 0 53 } 54 55 func (lrc *LruCache) ExistAndDelete(key []byte, _ uint32) error { 56 return lrc.Delete(key, 0) 57 } 58 59 func (lrc *LruCache) Get(key []byte, _ uint32) ([]byte, func(), bool) { 60 keyID, keyHash := hash.MD5Uint64(key) 61 hd := lrc.getShardByHashId(keyHash).Get(keyID, keyHash) 62 value := hd.Get() 63 if value == nil { 64 hd.Release() 65 return nil, nil, false 66 } 67 68 return value, func() { hd.Release() }, true 69 } 70 71 func (lrc *LruCache) Set(key, value []byte, _ uint32) error { 72 if len(key) == 0 || len(value) == 0 { 73 return nil 74 } 75 76 keyID, keyHash := hash.MD5Uint64(key) 77 78 vLen := len(value) 79 v := lrc.Alloc(vLen) 80 buf := v.Buf() 81 copy(buf[0:vLen], value) 82 83 lrc.getShardByHashId(keyHash).Set(keyID, keyHash, v).Release() 84 return nil 85 } 86 87 func (lrc *LruCache) Delete(key []byte, _ uint32) error { 88 if key == nil { 89 return nil 90 } 91 92 keyID, keyHash := hash.MD5Uint64(key) 93 94 lrc.getShardByHashId(keyHash).Delete(keyID, keyHash) 95 return nil 96 } 97 98 func (lrc *LruCache) GetBlock(keyID uint64, keyHash uint64) ([]byte, func(), bool) { 99 hd := lrc.getShardByHashId(keyHash).Get(keyID, keyHash) 100 value := hd.Get() 101 if value == nil { 102 hd.Release() 103 return nil, nil, false 104 } 105 106 return value, func() { hd.Release() }, true 107 } 108 109 func (lrc *LruCache) SetBlock(keyID uint64, keyHash uint64, value []byte) error { 110 vLen := len(value) 111 v := lrc.Alloc(vLen) 112 buf := v.Buf() 113 copy(buf[0:vLen], value) 114 115 lrc.getShardByHashId(keyHash).Set(keyID, keyHash, v).Release() 116 return nil 117 } 118 119 func (lrc *LruCache) DeleteBlock(keyID uint64, keyHash uint64) error { 120 lrc.getShardByHashId(keyHash).Delete(keyID, keyHash) 121 return nil 122 } 123 124 func (lrc *LruCache) Close() { 125 lrc.Unref() 126 }