github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/segment/utils/segutils.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 utils 18 19 import ( 20 "encoding/json" 21 "errors" 22 "fmt" 23 "regexp" 24 "strconv" 25 "strings" 26 "time" 27 28 dtu "github.com/siglens/siglens/pkg/common/dtypeutils" 29 toputils "github.com/siglens/siglens/pkg/utils" 30 log "github.com/sirupsen/logrus" 31 ) 32 33 func IsNumeric(exp interface{}) bool { 34 str := fmt.Sprint(exp) 35 _, err := strconv.ParseFloat(str, 64) 36 return err == nil 37 38 } 39 40 func GetCurrentTimeMillis() uint64 { 41 return uint64(time.Now().UTC().UnixNano()) / uint64(time.Millisecond) 42 } 43 44 func GetLiteralFromString(identifier string) (v interface{}) { 45 numericVal := strings.Replace(identifier, ",", "", -1) 46 pInt, err := strconv.ParseInt(numericVal, 10, 64) 47 if err == nil { 48 return pInt 49 } 50 f, err := strconv.ParseFloat(numericVal, 64) 51 if err == nil { 52 return f 53 } 54 pBool, err := strconv.ParseBool(identifier) 55 if err == nil { 56 return pBool 57 } 58 return identifier 59 } 60 61 func CreateDtypeEnclosure(inVal interface{}, qid uint64) (*DtypeEnclosure, error) { 62 var dte DtypeEnclosure 63 64 //todo check for float convert errors and return them 65 switch inVal := inVal.(type) { 66 case string: 67 dte.Dtype = SS_DT_STRING 68 dte.StringVal = inVal 69 70 if strings.Contains(inVal, "*") { 71 rawRegex := dtu.ReplaceWildcardStarWithRegex(inVal) 72 compiledRegex, err := regexp.Compile(rawRegex) 73 if err != nil { 74 log.Errorf("CreateDtypeEnclosure: Failed to compile regex for %s. This may cause search failures. Err: %v", rawRegex, err) 75 } 76 dte.SetRegexp(compiledRegex) 77 } 78 case *regexp.Regexp: 79 if inVal == nil { 80 return nil, errors.New("CreateDtypeEnclosure: inVal is nil Regexp") 81 } 82 dte.Dtype = SS_DT_STRING 83 dte.StringVal = inVal.String() 84 dte.SetRegexp(inVal) 85 case bool: 86 dte.Dtype = SS_DT_BOOL 87 bVal := inVal 88 if bVal { 89 dte.BoolVal = 1 90 } else { 91 dte.BoolVal = 0 92 } 93 dte.StringVal = fmt.Sprint(inVal) 94 case uint8: 95 dte.Dtype = SS_DT_UNSIGNED_NUM 96 dte.UnsignedVal = uint64(inVal) 97 dte.SignedVal = int64(inVal) 98 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.UnsignedVal, 64) 99 case uint16: 100 dte.Dtype = SS_DT_UNSIGNED_NUM 101 dte.UnsignedVal = uint64(inVal) 102 dte.SignedVal = int64(inVal) 103 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.UnsignedVal, 64) 104 case uint32: 105 dte.Dtype = SS_DT_UNSIGNED_NUM 106 dte.UnsignedVal = uint64(inVal) 107 dte.SignedVal = int64(inVal) 108 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.UnsignedVal, 64) 109 case uint: 110 dte.Dtype = SS_DT_UNSIGNED_NUM 111 dte.UnsignedVal = uint64(inVal) 112 dte.SignedVal = int64(inVal) 113 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.UnsignedVal, 64) 114 case uint64: 115 dte.Dtype = SS_DT_UNSIGNED_NUM 116 dte.UnsignedVal = uint64(inVal) 117 dte.SignedVal = int64(inVal) 118 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.UnsignedVal, 64) 119 case int8: 120 dte.Dtype = SS_DT_SIGNED_NUM 121 dte.SignedVal = int64(inVal) 122 dte.UnsignedVal = uint64(dte.SignedVal) 123 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.SignedVal, 64) 124 case int16: 125 dte.Dtype = SS_DT_SIGNED_NUM 126 dte.SignedVal = int64(inVal) 127 dte.UnsignedVal = uint64(dte.SignedVal) 128 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.SignedVal, 64) 129 case int32: 130 dte.Dtype = SS_DT_SIGNED_NUM 131 dte.SignedVal = int64(inVal) 132 dte.UnsignedVal = uint64(dte.SignedVal) 133 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.SignedVal, 64) 134 case int: 135 dte.Dtype = SS_DT_SIGNED_NUM 136 dte.SignedVal = int64(inVal) 137 dte.UnsignedVal = uint64(dte.SignedVal) 138 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.SignedVal, 64) 139 case int64: 140 dte.Dtype = SS_DT_SIGNED_NUM 141 dte.SignedVal = int64(inVal) 142 dte.UnsignedVal = uint64(dte.SignedVal) 143 dte.FloatVal, dte.StringVal, _ = dtu.ConvertToFloatAndReturnString(dte.SignedVal, 64) 144 case float64: 145 dte.Dtype = SS_DT_FLOAT 146 dte.FloatVal = inVal 147 dte.StringVal = fmt.Sprint(inVal) 148 case json.Number: 149 enclosureFromJsonNumber(inVal, &dte) 150 default: 151 log.Errorf("qid=%d, CreateDtypeEnclosure: could not convert unknown type=%T", qid, inVal) 152 return &dte, errors.New("could not convert unknown type") 153 } 154 155 return &dte, nil 156 } 157 158 func enclosureFromJsonNumber(num json.Number, dte *DtypeEnclosure) { 159 160 numstr := string(num) 161 dte.StringVal = numstr 162 numType, intVal, uintVal, fltVal := GetNumberTypeAndVal(numstr) 163 164 switch numType { 165 case SS_INT8, SS_INT16, SS_INT32, SS_INT64: 166 dte.Dtype = SS_DT_SIGNED_NUM 167 dte.SignedVal = intVal 168 dte.UnsignedVal = uint64(intVal) 169 dte.FloatVal = float64(intVal) 170 case SS_UINT8, SS_UINT16, SS_UINT32, SS_UINT64: 171 dte.Dtype = SS_DT_UNSIGNED_NUM 172 dte.UnsignedVal = uintVal 173 dte.SignedVal = int64(uintVal) 174 dte.FloatVal = float64(uintVal) 175 case SS_FLOAT64: 176 dte.Dtype = SS_DT_FLOAT 177 dte.SignedVal = int64(fltVal) 178 dte.UnsignedVal = uint64(fltVal) 179 dte.FloatVal = fltVal 180 } 181 } 182 183 func ConvertUintBytesToMB(bytes uint64) uint64 { 184 return bytes / 1048576 185 } 186 187 func ConvertIntBytesToMB(bytes int64) int64 { 188 return bytes / 1048576 189 } 190 191 func ConvertFloatBytesToMB(bytes float64) float64 { 192 return bytes / 1048576 193 } 194 195 func MinUint64(a1 uint64, b1 uint64) uint64 { 196 if a1 < b1 { 197 return a1 198 } 199 return b1 200 } 201 202 func MaxUint64(a1 uint64, b1 uint64) uint64 { 203 if a1 < b1 { 204 return b1 205 } 206 return a1 207 } 208 209 func MinInt64(a1 int64, b1 int64) int64 { 210 if a1 < b1 { 211 return a1 212 } 213 return b1 214 } 215 216 func MaxInt64(a1 int64, b1 int64) int64 { 217 if a1 < b1 { 218 return b1 219 } 220 return a1 221 } 222 223 func MaxUint16(a1 uint16, b1 uint16) uint16 { 224 if a1 < b1 { 225 return b1 226 } 227 return a1 228 } 229 230 // converts the input byte slice to a string representation of all read values 231 // returns array of strings with groupBy values 232 func ConvertGroupByKey(rec []byte) ([]string, error) { 233 var strArr []string 234 idx := 0 235 for idx < len(rec) { 236 var str strings.Builder 237 switch rec[idx] { 238 case VALTYPE_ENC_SMALL_STRING[0]: 239 idx += 1 240 len := int(toputils.BytesToUint16LittleEndian(rec[idx:])) 241 idx += 2 242 str.WriteString(string(rec[idx : idx+len])) 243 idx += len 244 case VALTYPE_ENC_BOOL[0]: 245 str.WriteString(fmt.Sprintf("%+v", rec[idx+1])) 246 idx += 2 247 case VALTYPE_ENC_INT8[0]: 248 str.WriteString(fmt.Sprintf("%+v", int8(rec[idx+1:][0]))) 249 idx += 2 250 case VALTYPE_ENC_INT16[0]: 251 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToInt16LittleEndian(rec[idx+1:]))) 252 idx += 3 253 case VALTYPE_ENC_INT32[0]: 254 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToInt32LittleEndian(rec[idx+1:]))) 255 idx += 5 256 case VALTYPE_ENC_INT64[0]: 257 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToInt64LittleEndian(rec[idx+1:]))) 258 idx += 9 259 case VALTYPE_ENC_UINT8[0]: 260 str.WriteString(fmt.Sprintf("%+v", uint8((rec[idx+1:])[0]))) 261 idx += 2 262 case VALTYPE_ENC_UINT16[0]: 263 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToUint16LittleEndian(rec[idx+1:]))) 264 idx += 3 265 case VALTYPE_ENC_UINT32[0]: 266 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToUint32LittleEndian(rec[idx+1:]))) 267 idx += 5 268 case VALTYPE_ENC_UINT64[0]: 269 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToUint64LittleEndian(rec[idx+1:]))) 270 idx += 9 271 case VALTYPE_ENC_FLOAT64[0]: 272 str.WriteString(fmt.Sprintf("%+v", toputils.BytesToFloat64LittleEndian(rec[idx+1:]))) 273 idx += 9 274 case VALTYPE_ENC_BACKFILL[0]: 275 str.WriteString("") 276 idx += 1 277 default: 278 log.Errorf("ConvertRowEncodingToString: dont know how to convert type=%v, idx: %v", rec[idx], idx) 279 return nil, fmt.Errorf("ConvertRowEncodingToString: dont know how to convert type=%v, idx: %v", 280 rec[idx], idx) 281 } 282 283 strArr = append(strArr, str.String()) 284 285 } 286 return strArr, nil 287 }