SerializeHLL allocates buffer based on the metadata and then serializes hll data into the buffer.
(dataTypes []memCom.DataType, enumDicts map[int][]string, timeDimensions []int)
| 26 | |
| 27 | // SerializeHLL allocates buffer based on the metadata and then serializes hll data into the buffer. |
| 28 | func (qc *AQLQueryContext) SerializeHLL(dataTypes []memCom.DataType, |
| 29 | enumDicts map[int][]string, timeDimensions []int) ([]byte, error) { |
| 30 | oopkContext := qc.OOPK |
| 31 | paddedRawDimValuesVectorLength := (uint32(queryCom.DimValResVectorSize(oopkContext.ResultSize, oopkContext.NumDimsPerDimWidth)) + 7) / 8 * 8 |
| 32 | paddedCountLength := uint32(2*oopkContext.ResultSize+7) / 8 * 8 |
| 33 | paddedHLLVectorLength := (qc.OOPK.hllVectorSize + 7) / 8 * 8 |
| 34 | builder := queryCom.HLLDataWriter{ |
| 35 | HLLData: queryCom.HLLData{ |
| 36 | ResultSize: uint32(oopkContext.ResultSize), |
| 37 | NumDimsPerDimWidth: oopkContext.NumDimsPerDimWidth, |
| 38 | DimIndexes: oopkContext.DimensionVectorIndex, |
| 39 | DataTypes: dataTypes, |
| 40 | EnumDicts: enumDicts, |
| 41 | PaddedRawDimValuesVectorLength: paddedRawDimValuesVectorLength, |
| 42 | PaddedHLLVectorLength: paddedHLLVectorLength, |
| 43 | }, |
| 44 | } |
| 45 | |
| 46 | headerSize, totalSize := builder.CalculateSizes() |
| 47 | builder.Buffer = make([]byte, totalSize) |
| 48 | if err := builder.SerializeHeader(); err != nil { |
| 49 | return nil, err |
| 50 | } |
| 51 | |
| 52 | // Copy dim values vector from device. |
| 53 | dimVectorH := unsafe.Pointer(&builder.Buffer[headerSize]) |
| 54 | asyncCopyDimensionVector(dimVectorH, oopkContext.currentBatch.dimensionVectorD[0].getPointer(), |
| 55 | oopkContext.ResultSize, 0, oopkContext.NumDimsPerDimWidth, oopkContext.ResultSize, oopkContext.currentBatch.resultCapacity, |
| 56 | cgoutils.AsyncCopyDeviceToHost, qc.cudaStreams[0], qc.Device) |
| 57 | |
| 58 | cgoutils.AsyncCopyDeviceToHost(unsafe.Pointer(&builder.Buffer[headerSize+paddedRawDimValuesVectorLength]), |
| 59 | oopkContext.hllDimRegIDCountD.getPointer(), oopkContext.ResultSize*2, qc.cudaStreams[0], qc.Device) |
| 60 | |
| 61 | cgoutils.AsyncCopyDeviceToHost(unsafe.Pointer(&builder.Buffer[headerSize+paddedRawDimValuesVectorLength+paddedCountLength]), |
| 62 | oopkContext.hllVectorD.getPointer(), int(qc.OOPK.hllVectorSize), qc.cudaStreams[0], qc.Device) |
| 63 | cgoutils.WaitForCudaStream(qc.cudaStreams[0], qc.Device) |
| 64 | |
| 65 | // Fix time dimension by substracting the timezone. |
| 66 | if len(timeDimensions) > 0 && qc.fixedTimezone.String() != time.UTC.String() { |
| 67 | // length is equal to length of timeDimensions |
| 68 | dimPtrs := make([][2]unsafe.Pointer, len(timeDimensions)) |
| 69 | |
| 70 | for i := 0; i < len(timeDimensions); i++ { |
| 71 | dimIndex := timeDimensions[i] |
| 72 | dimVectorIndex := qc.OOPK.DimensionVectorIndex[dimIndex] |
| 73 | valueOffset, nullOffset := queryCom.GetDimensionStartOffsets(oopkContext.NumDimsPerDimWidth, dimVectorIndex, int(qc.OOPK.ResultSize)) |
| 74 | dimPtrs[i] = [2]unsafe.Pointer{utils.MemAccess(dimVectorH, valueOffset), utils.MemAccess(dimVectorH, nullOffset)} |
| 75 | } |
| 76 | |
| 77 | for rowNumber := 0; rowNumber < oopkContext.ResultSize; rowNumber++ { |
| 78 | for i := 0; i < len(timeDimensions); i++ { |
| 79 | valueStart, nullStart := dimPtrs[i][0], dimPtrs[i][1] |
| 80 | // We don't need to do anything for null. |
| 81 | if *(*uint8)(utils.MemAccess(nullStart, rowNumber)) == 0 { |
| 82 | continue |
| 83 | } |
| 84 | |
| 85 | valuePtr := (*uint32)(utils.MemAccess(valueStart, rowNumber*4)) |
no test coverage detected