github.com/nutsdb/nutsdb@v1.0.4/utils.go (about) 1 // Copyright 2019 The nutsdb Author. All rights reserved. 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 nutsdb 16 17 import ( 18 "bytes" 19 "encoding/binary" 20 "errors" 21 "io" 22 "os" 23 "path/filepath" 24 "strings" 25 26 "github.com/xujiajun/utils/strconv2" 27 ) 28 29 // Truncate changes the size of the file. 30 func Truncate(path string, capacity int64, f *os.File) error { 31 fileInfo, _ := os.Stat(path) 32 if fileInfo.Size() < capacity { 33 if err := f.Truncate(capacity); err != nil { 34 return err 35 } 36 } 37 return nil 38 } 39 40 func ConvertBigEndianBytesToUint64(data []byte) uint64 { 41 return binary.BigEndian.Uint64(data) 42 } 43 44 func ConvertUint64ToBigEndianBytes(value uint64) []byte { 45 b := make([]byte, 8) 46 binary.BigEndian.PutUint64(b, value) 47 return b 48 } 49 50 func MarshalInts(ints []int) ([]byte, error) { 51 buffer := bytes.NewBuffer([]byte{}) 52 for _, x := range ints { 53 if err := binary.Write(buffer, binary.LittleEndian, int64(x)); err != nil { 54 return nil, err 55 } 56 } 57 return buffer.Bytes(), nil 58 } 59 60 func UnmarshalInts(data []byte) ([]int, error) { 61 var ints []int 62 buffer := bytes.NewBuffer(data) 63 for { 64 var i int64 65 err := binary.Read(buffer, binary.LittleEndian, &i) 66 if errors.Is(err, io.EOF) { 67 break 68 } else if err != nil { 69 return nil, err 70 } 71 ints = append(ints, int(i)) 72 } 73 return ints, nil 74 } 75 76 func MatchForRange(pattern, bucket string, f func(bucket string) bool) (end bool, err error) { 77 match, err := filepath.Match(pattern, bucket) 78 if err != nil { 79 return true, err 80 } 81 if match && !f(bucket) { 82 return true, nil 83 } 84 return false, nil 85 } 86 87 // getDataPath returns the data path for the given file ID. 88 func getDataPath(fID int64, dir string) string { 89 separator := string(filepath.Separator) 90 return dir + separator + strconv2.Int64ToStr(fID) + DataSuffix 91 } 92 93 func OneOfUint16Array(value uint16, array []uint16) bool { 94 for _, v := range array { 95 if v == value { 96 return true 97 } 98 } 99 return false 100 } 101 102 func splitIntStringStr(str, separator string) (int, string) { 103 strList := strings.Split(str, separator) 104 firstItem, _ := strconv2.StrToInt(strList[0]) 105 secondItem := strList[1] 106 return firstItem, secondItem 107 } 108 109 func splitStringIntStr(str, separator string) (string, int) { 110 strList := strings.Split(str, separator) 111 firstItem := strList[0] 112 secondItem, _ := strconv2.StrToInt(strList[1]) 113 return firstItem, secondItem 114 } 115 116 func splitIntIntStr(str, separator string) (int, int) { 117 strList := strings.Split(str, separator) 118 firstItem, _ := strconv2.StrToInt(strList[0]) 119 secondItem, _ := strconv2.StrToInt(strList[1]) 120 return firstItem, secondItem 121 } 122 123 func encodeListKey(key []byte, seq uint64) []byte { 124 buf := make([]byte, len(key)+8) 125 binary.LittleEndian.PutUint64(buf[:8], seq) 126 copy(buf[8:], key[:]) 127 return buf 128 } 129 130 func decodeListKey(buf []byte) ([]byte, uint64) { 131 seq := binary.LittleEndian.Uint64(buf[:8]) 132 key := make([]byte, len(buf[8:])) 133 copy(key[:], buf[8:]) 134 return key, seq 135 } 136 137 func splitStringFloat64Str(str, separator string) (string, float64) { 138 strList := strings.Split(str, separator) 139 firstItem := strList[0] 140 secondItem, _ := strconv2.StrToFloat64(strList[1]) 141 return firstItem, secondItem 142 } 143 144 func getFnv32(value []byte) (uint32, error) { 145 _, err := fnvHash.Write(value) 146 if err != nil { 147 return 0, err 148 } 149 hash := fnvHash.Sum32() 150 fnvHash.Reset() 151 return hash, nil 152 } 153 154 func generateSeq(seq *HeadTailSeq, isLeft bool) uint64 { 155 var res uint64 156 if isLeft { 157 res = seq.Head 158 seq.Head-- 159 } else { 160 res = seq.Tail 161 seq.Tail++ 162 } 163 164 return res 165 } 166 167 func createNewBufferWithSize(size int) *bytes.Buffer { 168 buf := new(bytes.Buffer) 169 buf.Grow(int(size)) 170 return buf 171 } 172 173 func UvarintSize(x uint64) int { 174 i := 0 175 for x >= 0x80 { 176 x >>= 7 177 i++ 178 } 179 return i + 1 180 }