github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/writer/columnencoding.go (about) 1 /* 2 Copyright 2023. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package writer 18 19 import ( 20 segutils "github.com/siglens/siglens/pkg/segment/utils" 21 "github.com/siglens/siglens/pkg/utils" 22 log "github.com/sirupsen/logrus" 23 ) 24 25 func EncodeDictionaryColumn(columnValueMap map[segutils.CValueDictEnclosure][]uint16, colRis map[string]*RangeIndex, recNum uint16) ([]byte, uint32) { 26 columnValueSummary := make([]byte, segutils.WIP_SIZE) 27 var idx uint32 = 0 28 29 noOfColumnValues := uint16(len(columnValueMap)) 30 copy(columnValueSummary[idx:], utils.Uint16ToBytesLittleEndian(noOfColumnValues)) 31 idx += 2 32 33 for key, val := range columnValueMap { 34 switch key.Dtype { 35 case segutils.SS_DT_STRING: 36 columnValueSummary[idx] = byte(segutils.SS_DT_STRING) 37 idx += 1 38 colValue, err := key.GetValue() 39 if err != nil { 40 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 41 continue 42 } 43 n := uint16(len(colValue.(string))) 44 45 copy(columnValueSummary[idx:], utils.Uint16ToBytesLittleEndian(n)) 46 idx += 2 47 48 copy(columnValueSummary[idx:], colValue.(string)) 49 idx += uint32(n) 50 51 case segutils.SS_DT_BOOL: 52 columnValueSummary[idx] = byte(segutils.SS_DT_BOOL) 53 idx += 1 54 colValue, err := key.GetValue() 55 if err != nil { 56 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 57 continue 58 } 59 60 copy(columnValueSummary[idx:], utils.BoolToBytesLittleEndian(colValue.(bool))) 61 idx += 1 62 63 case segutils.SS_DT_UNSIGNED_NUM: 64 columnValueSummary[idx] = byte(segutils.SS_DT_UNSIGNED_NUM) 65 idx += 1 66 colValue, err := key.GetValue() 67 if err != nil { 68 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 69 continue 70 } 71 72 copy(columnValueSummary[idx:], utils.Uint64ToBytesLittleEndian(colValue.(uint64))) 73 idx += 8 74 75 case segutils.SS_DT_SIGNED_NUM: 76 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_NUM) 77 idx += 1 78 colValue, err := key.GetValue() 79 if err != nil { 80 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 81 continue 82 } 83 84 copy(columnValueSummary[idx:], utils.Int64ToBytesLittleEndian(colValue.(int64))) 85 idx += 8 86 87 case segutils.SS_DT_FLOAT: 88 columnValueSummary[idx] = byte(segutils.SS_DT_FLOAT) 89 idx += 1 90 colValue, err := key.GetValue() 91 if err != nil { 92 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 93 continue 94 } 95 96 copy(columnValueSummary[idx:], utils.Float64ToBytesLittleEndian(colValue.(float64))) 97 idx += 8 98 case segutils.SS_DT_USIGNED_32_NUM: 99 columnValueSummary[idx] = byte(segutils.SS_DT_USIGNED_32_NUM) 100 idx += 1 101 colValue, err := key.GetValue() 102 if err != nil { 103 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 104 continue 105 } 106 107 copy(columnValueSummary[idx:], utils.Uint32ToBytesLittleEndian(colValue.(uint32))) 108 idx += 4 109 case segutils.SS_DT_SIGNED_32_NUM: 110 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_32_NUM) 111 idx += 1 112 colValue, err := key.GetValue() 113 if err != nil { 114 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 115 continue 116 } 117 118 copy(columnValueSummary[idx:], utils.Int32ToBytesLittleEndian(colValue.(int32))) 119 idx += 4 120 case segutils.SS_DT_USIGNED_16_NUM: 121 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_32_NUM) 122 idx += 1 123 colValue, err := key.GetValue() 124 if err != nil { 125 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 126 continue 127 } 128 129 copy(columnValueSummary[idx:], utils.Uint16ToBytesLittleEndian(colValue.(uint16))) 130 idx += 2 131 case segutils.SS_DT_SIGNED_16_NUM: 132 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_32_NUM) 133 idx += 1 134 colValue, err := key.GetValue() 135 if err != nil { 136 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 137 continue 138 } 139 140 copy(columnValueSummary[idx:], utils.Int16ToBytesLittleEndian(colValue.(int16))) 141 idx += 2 142 case segutils.SS_DT_USIGNED_8_NUM: 143 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_8_NUM) 144 idx += 1 145 colValue, err := key.GetValue() 146 if err != nil { 147 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 148 continue 149 } 150 151 copy(columnValueSummary[idx:], []byte{colValue.(uint8)}) 152 idx += 1 153 case segutils.SS_DT_SIGNED_8_NUM: 154 columnValueSummary[idx] = byte(segutils.SS_DT_SIGNED_8_NUM) 155 idx += 1 156 colValue, err := key.GetValue() 157 if err != nil { 158 log.Errorf("EncodeDictionaryColumn: Failed to get value of %v; err: %v", key, err) 159 continue 160 } 161 162 copy(columnValueSummary[idx:], []byte{byte(colValue.(int8))}) 163 idx += 1 164 } 165 copy(columnValueSummary[idx:], utils.Uint16ToBytesLittleEndian(uint16(len(val)))) 166 idx += 2 167 168 for _, value := range val { 169 copy(columnValueSummary[idx:], utils.Uint16ToBytesLittleEndian(value)) 170 idx += 2 171 } 172 } 173 174 compressed := encoder.EncodeAll(columnValueSummary[0:idx], make([]byte, 0, idx)) 175 return compressed, idx 176 } 177 178 func DecodeDictionaryColumn(encodedBytes []byte) map[segutils.CValueDictEnclosure][]uint16 { 179 180 encodedBytes, err := decoder.DecodeAll(encodedBytes, make([]byte, 0, len(encodedBytes))) 181 182 if err != nil { 183 log.Errorf("DecodeDictionaryColumn: Failed to decompress, error: %+v", err) 184 } 185 186 columnValueMap := make(map[segutils.CValueDictEnclosure][]uint16) 187 var idx uint32 = 0 188 189 noOfColumnValues := utils.BytesToUint16LittleEndian(encodedBytes[0:2]) 190 idx += 2 191 192 for noOfColumnValues > 0 { 193 var colCVEnclosure segutils.CValueDictEnclosure 194 colCVEnclosure.Dtype = segutils.SS_DTYPE(encodedBytes[idx]) 195 idx += 1 196 switch colCVEnclosure.Dtype { 197 case segutils.SS_DT_STRING: 198 strLen := uint32(utils.BytesToUint16LittleEndian(encodedBytes[idx:(idx + 2)])) 199 idx += 2 200 colCVEnclosure.CValString = string(encodedBytes[idx:(idx + strLen)]) 201 idx += strLen 202 case segutils.SS_DT_BOOL: 203 colCVEnclosure.CValBool = utils.BytesToBoolLittleEndian([]byte{encodedBytes[idx]}) 204 idx += 1 205 case segutils.SS_DT_UNSIGNED_NUM: 206 colCVEnclosure.CValUInt64 = utils.BytesToUint64LittleEndian(encodedBytes[idx:(idx + 8)]) 207 idx += 8 208 case segutils.SS_DT_SIGNED_NUM: 209 colCVEnclosure.CValInt64 = utils.BytesToInt64LittleEndian(encodedBytes[idx:(idx + 8)]) 210 idx += 8 211 case segutils.SS_DT_FLOAT: 212 colCVEnclosure.CValFloat64 = utils.BytesToFloat64LittleEndian(encodedBytes[idx:(idx + 8)]) 213 idx += 8 214 case segutils.SS_DT_USIGNED_32_NUM: 215 colCVEnclosure.CValUInt32 = utils.BytesToUint32LittleEndian(encodedBytes[idx:(idx + 4)]) 216 idx += 4 217 case segutils.SS_DT_SIGNED_32_NUM: 218 colCVEnclosure.CValInt32 = utils.BytesToInt32LittleEndian(encodedBytes[idx:(idx + 4)]) 219 idx += 4 220 case segutils.SS_DT_USIGNED_16_NUM: 221 colCVEnclosure.CValUInt16 = utils.BytesToUint16LittleEndian(encodedBytes[idx:(idx + 2)]) 222 idx += 2 223 case segutils.SS_DT_SIGNED_16_NUM: 224 colCVEnclosure.CValInt16 = utils.BytesToInt16LittleEndian(encodedBytes[idx:(idx + 2)]) 225 idx += 2 226 case segutils.SS_DT_USIGNED_8_NUM: 227 colCVEnclosure.CValUInt = encodedBytes[idx+1] 228 idx += 1 229 case segutils.SS_DT_SIGNED_8_NUM: 230 colCVEnclosure.CValInt = int8(encodedBytes[idx+1]) 231 idx += 1 232 } 233 234 valuesLen := utils.BytesToUint16LittleEndian(encodedBytes[idx:(idx + 2)]) 235 idx += 2 236 237 valSlice := make([]uint16, valuesLen) 238 for id := 0; valuesLen > 0; id++ { 239 valSlice[id] = utils.BytesToUint16LittleEndian(encodedBytes[idx:(idx + 2)]) 240 idx += 2 241 valuesLen -= 1 242 } 243 244 columnValueMap[colCVEnclosure] = valSlice 245 noOfColumnValues -= 1 246 } 247 248 return columnValueMap 249 }