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  }