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  }