in query/common/hll.go [364:500]
func parseTimeseriesHLLResult(buffer []byte, ignoreEnum bool) (AQLQueryResult, error) {
// empty result buffer
if len(buffer) == 0 {
return AQLQueryResult{}, nil
}
reader := utils.NewStreamDataReader(bytes.NewBuffer(buffer))
numEnumColumns, err := reader.ReadUint8()
if err != nil {
return nil, err
}
var numDimsPerDimWidth DimCountsPerDimWidth
err = reader.Read([]byte(numDimsPerDimWidth[:]))
if err != nil {
return AQLQueryResult{}, nil
}
totalDims := 0
for _, dimCount := range numDimsPerDimWidth {
totalDims += int(dimCount)
}
err = reader.ReadPadding(int(reader.GetBytesRead()), 8)
if err != nil {
return nil, err
}
resultSize, err := reader.ReadUint32()
if err != nil {
return nil, err
}
paddedRawDimValuesVectorLength, err := reader.ReadUint32()
if err != nil {
return nil, err
}
dimIndexes := make([]uint8, totalDims)
for i := range dimIndexes {
dimIndexes[i], err = reader.ReadUint8()
if err != nil {
return nil, err
}
}
if err = reader.ReadPadding(int(totalDims), 8); err != nil {
return nil, err
}
dataTypes := make([]memCom.DataType, totalDims)
for i := range dataTypes {
rawDataType, err := reader.ReadUint32()
if err != nil {
return nil, err
}
dataType, err := memCom.NewDataType(rawDataType)
if err != nil {
return nil, err
}
dataTypes[i] = dataType
}
if err = reader.ReadPadding(int(totalDims)*4, 8); err != nil {
return nil, err
}
enumDicts := make(map[int][]string)
var i uint8
for ; i < numEnumColumns; i++ {
enumCasesBytes, err := reader.ReadUint32()
if err != nil {
return nil, err
}
dimIdx, err := reader.ReadUint16()
if err != nil {
return nil, err
}
reader.SkipBytes(2)
rawEnumCases := make([]byte, enumCasesBytes)
if err = reader.Read(rawEnumCases); err != nil {
return nil, err
}
enumCases := strings.Split(string(rawEnumCases), EnumDelimiter)
// remove last empty element.
enumCases = enumCases[:len(enumCases)-1]
enumDicts[int(dimIdx)] = enumCases
}
headerSize := reader.GetBytesRead()
result := make(AQLQueryResult)
paddedCountLength := uint32(2*resultSize+7) / 8 * 8
dimValuesVector := unsafe.Pointer(&buffer[headerSize])
countVector := unsafe.Pointer(&buffer[headerSize+paddedRawDimValuesVectorLength])
hllVector := unsafe.Pointer(&buffer[headerSize+paddedRawDimValuesVectorLength+paddedCountLength])
dimOffsets := make([][2]int, totalDims)
dimValues := make([]*string, totalDims)
for i := 0; i < totalDims; i++ {
dimIndex := int(dimIndexes[i])
valueOffset, nullOffset := GetDimensionStartOffsets(numDimsPerDimWidth, dimIndex, int(resultSize))
dimOffsets[i] = [2]int{valueOffset, nullOffset}
}
var currentOffset int64
for i := 0; i < int(resultSize); i++ {
for dimIndex := 0; dimIndex < totalDims; dimIndex++ {
offsets := dimOffsets[dimIndex]
valueOffset, nullOffset := offsets[0], offsets[1]
valuePtr, nullPtr := memAccess(dimValuesVector, valueOffset), memAccess(dimValuesVector, nullOffset)
enumDict := []string{}
if !ignoreEnum {
enumDict = enumDicts[dimIndex]
}
dimValues[dimIndex] = ReadDimension(valuePtr, nullPtr, i, dataTypes[dimIndex], enumDict, nil, nil)
}
count := *(*uint16)(memAccess(countVector, int(2*i)))
hll := readHLL(hllVector, count, ¤tOffset)
result.SetHLL(dimValues, hll)
}
return result, nil
}