github.com/duomi520/utils@v0.0.0-20240430123446-e03a4cddd6ec/dict.go (about) 1 package utils 2 3 import ( 4 "encoding/binary" 5 ) 6 7 type ky struct { 8 key uint64 9 value string 10 } 11 12 // MetaDict 非线程安全,key数量超过5个后,效率低于map 13 type MetaDict []ky 14 15 // GetAll 16 func (d MetaDict) GetAll() (s []string) { 17 for _, k := range d { 18 s = append(s, k.value) 19 } 20 return s 21 } 22 23 func (d MetaDict) findIndex(hash uint64) int { 24 for i, k := range d { 25 if k.key == hash { 26 return i 27 } 28 } 29 return -1 30 } 31 32 // Set 设置给定键的值,如果该键已存在,则更新值;如果不存在,则添加新的键值对。 33 func (d MetaDict) Set(key, value string) (new MetaDict) { 34 hash := Hash64FNV1A(key) 35 if idx := d.findIndex(hash); idx != -1 { 36 d[idx].value = value 37 return d 38 } 39 new = append(d, ky{hash, value}) 40 return new 41 } 42 43 // Get 根据给定的键返回相应的值。如果键存在,则返回对应的值和true;如果键不存在,则返回空字符串和false。 44 func (d MetaDict) Get(key string) (string, bool) { 45 hash := Hash64FNV1A(key) 46 if idx := d.findIndex(hash); idx != -1 { 47 return d[idx].value, true 48 } 49 return "", false 50 } 51 52 // Del 根据给定的键删除相应的键值对。 53 func (d MetaDict) Del(key string) (new MetaDict) { 54 hash := Hash64FNV1A(key) 55 if idx := d.findIndex(hash); idx != -1 { 56 if idx < (len(d) - 1) { 57 copy(d[idx:], d[idx+1:]) 58 } 59 return d[:len(d)-1] 60 } 61 return d 62 } 63 64 /* 65 +-------+-------+-------+-------+-------+-------+ 66 | len(8)| key (64) | value | ... 67 +-------+-------+-------+-------+-------+-------+ 68 */ 69 70 // Encode 编码 将字典编码为字节切片。 71 func MetaDictEncode(d MetaDict) []byte { 72 size := len(d) 73 if size == 0 { 74 return nil 75 } 76 n := 0 77 for i := 0; i < size; i++ { 78 n += 1 + 8 + len(d[i].value) 79 } 80 buf := make([]byte, n) 81 idx := 0 82 for i := 0; i < size; i++ { 83 buf[idx] = byte(1 + 8 + len(d[i].value)) 84 idx++ 85 binary.LittleEndian.PutUint64(buf[idx:], d[i].key) 86 idx += 8 87 copy(buf[idx:], StringToBytes(d[i].value)) 88 idx += len(d[i].value) 89 } 90 return buf 91 } 92 93 // Decode 解码 将字节切片解码为字典。 94 func MetaDictDecode(data []byte) (d MetaDict) { 95 idx := 0 96 for len(data) > idx { 97 n := int(data[idx]) 98 d = append(d, ky{binary.LittleEndian.Uint64(data[idx+1 : idx+1+8]), string(data[idx+1+8 : idx+n])}) 99 idx += n 100 } 101 return d 102 }