github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/hll_test.go (about) 1 // Copyright (c) 2017-2018 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package query 16 17 import ( 18 "github.com/onsi/ginkgo" 19 memCom "github.com/uber/aresdb/memstore/common" 20 queryCom "github.com/uber/aresdb/query/common" 21 "unsafe" 22 23 "errors" 24 . "github.com/onsi/gomega" 25 "time" 26 ) 27 28 var _ = ginkgo.Describe("hll", func() { 29 dimensionData := []byte{ 30 0, 0, 0, 0, 31 1, 0, 0, 0, 32 0xFF, 0xFF, 0xFF, 0xFF, // dim0 33 0, 0, 0, 0, 34 0, 0, 0, 0, 35 0, 0, 0, 0, // res cap. 36 0, 0, 37 2, 0, 38 2, 2, // dim1 39 0, 0, 40 0, 0, 41 0, 0, // res cap 42 0, 2, 3, // dim2 43 0, 0, 0, // res cap 44 0, 1, 1, // dim0 45 0, 0, 0, // res cap 46 0, 1, 1, // dim1 47 0, 0, 0, // res cap 48 0, 1, 1, // dim2 49 0, 0, 0, // res cap 50 } 51 52 measureData := [3]uint32{} 53 counts := []uint16{3, queryCom.DenseDataLength, 4} 54 hllData := [queryCom.DenseDataLength + 28]byte{} 55 *(*uint32)(unsafe.Pointer(&hllData[0])) = 0X00FF0001 56 *(*uint32)(unsafe.Pointer(&hllData[4])) = 0X00FE0002 57 *(*uint32)(unsafe.Pointer(&hllData[8])) = 0X00FD0003 58 59 hllData[12] = 1 60 hllData[13] = 1 61 62 *(*uint32)(unsafe.Pointer(&hllData[12+queryCom.DenseDataLength])) = 0X000100FF 63 *(*uint32)(unsafe.Pointer(&hllData[16+queryCom.DenseDataLength])) = 0X000200FE 64 *(*uint32)(unsafe.Pointer(&hllData[20+queryCom.DenseDataLength])) = 0X000300FD 65 *(*uint32)(unsafe.Pointer(&hllData[24+queryCom.DenseDataLength])) = 0X000400FC 66 67 qc := AQLQueryContext{ 68 OOPK: OOPKContext{ 69 currentBatch: oopkBatchContext{ 70 resultCapacity: 6, 71 dimensionVectorD: [2]devicePointer{{pointer: unsafe.Pointer(&dimensionData[0])}, nullDevicePointer}, 72 measureVectorD: [2]devicePointer{{pointer: unsafe.Pointer(&measureData[0])}, nullDevicePointer}, 73 }, 74 hllVectorD: devicePointer{pointer: unsafe.Pointer(&hllData[0])}, 75 hllVectorSize: queryCom.DenseDataLength + 28, 76 hllDimRegIDCountD: devicePointer{pointer: unsafe.Pointer(&counts[0])}, 77 ResultSize: 3, 78 NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 1, 1, 1}, 79 DimensionVectorIndex: []int{0, 2, 1}, 80 }, 81 } 82 83 ginkgo.It("SerializeHLL should work", func() { 84 dataTypes := []memCom.DataType{memCom.Uint32, memCom.Uint8, memCom.Int16} 85 enumReverseDict := map[int][]string{1: {"a", "b", "c"}} 86 data, err := qc.SerializeHLL(dataTypes, enumReverseDict, nil) 87 Ω(err).Should(BeNil()) 88 Ω(len(data)).Should(Equal(104 + queryCom.DenseDataLength + 32)) 89 Ω(data[64:94]).Should(Equal([]byte{ 90 0, 0, 0, 0, 91 1, 0, 0, 0, 92 0xFF, 0xFF, 0xFF, 0xFF, // dim0 93 0, 0, 94 2, 0, 95 2, 2, // dim1 96 0, 2, 3, // dim2 97 0, 1, 1, // dim0 98 0, 1, 1, // dim1 99 0, 1, 1, // dim2 100 })) 101 Ω(data[96:102]).Should(Equal((*(*[6]byte)(unsafe.Pointer(&counts[0])))[:])) 102 Ω(data[104 : 104+queryCom.DenseDataLength+28]).Should(Equal(hllData[:])) 103 }) 104 105 ginkgo.It("Should work with timezone", func() { 106 timeDimensionData := []byte{ 107 0, 0, 0, 0, 108 1, 0, 0, 0, 109 2, 0, 0, 0, // dim0 110 0, 0, 0, 0, 111 0, 0, 0, 0, 112 0, 0, 0, 0, // res cap. 113 0, 0, 114 2, 0, 115 2, 2, // dim1 116 0, 0, 117 0, 0, 118 0, 0, // res cap 119 0, 2, 3, // dim2 120 0, 0, 0, // res cap 121 0, 1, 1, // dim0 122 0, 0, 0, // res cap 123 0, 1, 1, // dim1 124 0, 0, 0, // res cap 125 0, 1, 1, // dim2 126 0, 0, 0, // res cap 127 } 128 129 measureData := [3]uint32{} 130 counts := []uint16{3, queryCom.DenseDataLength, 4} 131 hllData := [queryCom.DenseDataLength + 28]byte{} 132 *(*uint32)(unsafe.Pointer(&hllData[0])) = 0X00FF0001 133 *(*uint32)(unsafe.Pointer(&hllData[4])) = 0X00FE0002 134 *(*uint32)(unsafe.Pointer(&hllData[8])) = 0X00FD0003 135 136 hllData[12] = 1 137 hllData[13] = 1 138 139 *(*uint32)(unsafe.Pointer(&hllData[12+queryCom.DenseDataLength])) = 0X000100FF 140 *(*uint32)(unsafe.Pointer(&hllData[16+queryCom.DenseDataLength])) = 0X000200FE 141 *(*uint32)(unsafe.Pointer(&hllData[20+queryCom.DenseDataLength])) = 0X000300FD 142 *(*uint32)(unsafe.Pointer(&hllData[24+queryCom.DenseDataLength])) = 0X000400FC 143 144 loc, _ := time.LoadLocation("Africa/Algiers") 145 qc := AQLQueryContext{ 146 OOPK: OOPKContext{ 147 currentBatch: oopkBatchContext{ 148 resultCapacity: 6, 149 dimensionVectorD: [2]devicePointer{{pointer: unsafe.Pointer(&timeDimensionData[0])}, nullDevicePointer}, 150 measureVectorD: [2]devicePointer{{pointer: unsafe.Pointer(&measureData[0])}, nullDevicePointer}, 151 }, 152 hllVectorD: devicePointer{pointer: unsafe.Pointer(&hllData[0])}, 153 hllVectorSize: queryCom.DenseDataLength + 28, 154 hllDimRegIDCountD: devicePointer{pointer: unsafe.Pointer(&counts[0])}, 155 ResultSize: 3, 156 NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 1, 1, 1}, 157 DimensionVectorIndex: []int{0, 2, 1}, 158 }, 159 fixedTimezone: loc, 160 fromTime: &alignedTime{Time: time.Now().In(loc), Unit: "week"}, 161 toTime: &alignedTime{Time: time.Now().In(loc), Unit: "week"}, 162 } 163 164 dataTypes := []memCom.DataType{memCom.Uint32, memCom.Uint8, memCom.Int16} 165 enumReverseDict := map[int][]string{1: {"a", "b", "c", "d"}} 166 data, err := qc.SerializeHLL(dataTypes, enumReverseDict, []int{0}) 167 Ω(err).Should(BeNil()) 168 Ω(len(data)).Should(Equal(104 + queryCom.DenseDataLength + 32)) 169 Ω(data[64:94]).Should(Equal([]byte{ 170 0, 0, 0, 0, 171 0, 0, 0, 0, 172 0, 0, 0, 0, // dim0 173 0, 0, 174 2, 0, 175 2, 2, // dim1 176 0, 2, 3, // dim2 177 0, 1, 1, // dim0 178 0, 1, 1, // dim1 179 0, 1, 1, // dim2 180 })) 181 Ω(data[96:102]).Should(Equal((*(*[6]byte)(unsafe.Pointer(&counts[0])))[:])) 182 Ω(data[104 : 104+queryCom.DenseDataLength+28]).Should(Equal(hllData[:])) 183 184 // Then we deserialize it. 185 res, err := queryCom.NewTimeSeriesHLLResult(data, queryCom.HLLDataHeader) 186 Ω(err).Should(BeNil()) 187 Ω(res).Should(Equal(queryCom.AQLQueryResult{ 188 "NULL": map[string]interface{}{ 189 "NULL": map[string]interface{}{ 190 "NULL": queryCom.HLL{NonZeroRegisters: 3, 191 SparseData: []queryCom.HLLRegister{{Index: 1, Rho: 255}, {Index: 2, Rho: 254}, {Index: 3, Rho: 253}}, 192 }, 193 }}, 194 "0": map[string]interface{}{ 195 "c": map[string]interface{}{ 196 "2": queryCom.HLL{NonZeroRegisters: 2, DenseData: hllData[12 : 12+queryCom.DenseDataLength]}, 197 }, 198 "d": map[string]interface{}{ 199 "514": queryCom.HLL{NonZeroRegisters: 4, SparseData: []queryCom.HLLRegister{{Index: 255, Rho: 1}, {Index: 254, Rho: 2}, {Index: 253, Rho: 3}, {Index: 252, Rho: 4}}}, 200 }, 201 }, 202 })) 203 }) 204 205 ginkgo.It("Serialize and then deserialize should work", func() { 206 dataTypes := []memCom.DataType{memCom.Uint32, memCom.Uint8, memCom.Int16} 207 enumReverseDict := map[int][]string{1: {"a", "b", "c", "d"}} 208 data, err := qc.SerializeHLL(dataTypes, enumReverseDict, nil) 209 Ω(err).Should(BeNil()) 210 //ioutil.WriteFile("../testing/data/query/hll", data, 0644) 211 res, err := queryCom.NewTimeSeriesHLLResult(data, queryCom.HLLDataHeader) 212 Ω(err).Should(BeNil()) 213 Ω(res).Should(Equal(queryCom.AQLQueryResult{ 214 "NULL": map[string]interface{}{ 215 "NULL": map[string]interface{}{ 216 "NULL": queryCom.HLL{NonZeroRegisters: 3, 217 SparseData: []queryCom.HLLRegister{{Index: 1, Rho: 255}, {Index: 2, Rho: 254}, {Index: 3, Rho: 253}}, 218 }, 219 }}, 220 "1": map[string]interface{}{ 221 "c": map[string]interface{}{ 222 "2": queryCom.HLL{NonZeroRegisters: 2, DenseData: hllData[12 : 12+queryCom.DenseDataLength]}, 223 }, 224 }, 225 "4294967295": map[string]interface{}{ 226 "d": map[string]interface{}{ 227 "514": queryCom.HLL{NonZeroRegisters: 4, SparseData: []queryCom.HLLRegister{{Index: 255, Rho: 1}, {Index: 254, Rho: 2}, {Index: 253, Rho: 3}, {Index: 252, Rho: 4}}}, 228 }, 229 }})) 230 }) 231 232 ginkgo.It("write HLLQueryResults should work", func() { 233 dataTypes := []memCom.DataType{memCom.Uint32, memCom.Uint8, memCom.Int16} 234 enumReverseDict := map[int][]string{1: {"a", "b", "c", "d"}} 235 236 //queryE := NewHLLQueryResults() 237 //queryE.WriteResult([]byte{}) 238 //err := ioutil.WriteFile("../testing/data/query/hll_empty_results", queryE.GetBytes(), 0644) 239 240 queryResults := NewHLLQueryResults() 241 data, err := qc.SerializeHLL(dataTypes, enumReverseDict, nil) 242 Ω(err).Should(BeNil()) 243 244 queryResults.WriteResult(data) 245 246 results, errs, err := queryCom.ParseHLLQueryResults(queryResults.GetBytes()) 247 Ω(err).Should(BeNil()) 248 Ω(errs).Should(HaveLen(1)) 249 Ω(errs[0]).Should(BeNil()) 250 Ω(results).Should(HaveLen(1)) 251 Ω(results[0]).Should(Equal(queryCom.AQLQueryResult{ 252 "NULL": map[string]interface{}{ 253 "NULL": map[string]interface{}{ 254 "NULL": queryCom.HLL{NonZeroRegisters: 3, 255 SparseData: []queryCom.HLLRegister{{Index: 1, Rho: 255}, {Index: 2, Rho: 254}, {Index: 3, Rho: 253}}, 256 }, 257 }}, 258 "1": map[string]interface{}{ 259 "c": map[string]interface{}{ 260 "2": queryCom.HLL{NonZeroRegisters: 2, DenseData: hllData[12 : 12+queryCom.DenseDataLength]}, 261 }, 262 }, 263 "4294967295": map[string]interface{}{ 264 "d": map[string]interface{}{ 265 "514": queryCom.HLL{NonZeroRegisters: 4, SparseData: []queryCom.HLLRegister{{Index: 255, Rho: 1}, {Index: 254, Rho: 2}, {Index: 253, Rho: 3}, {Index: 252, Rho: 4}}}, 266 }, 267 }})) 268 269 queryResults.WriteError(errors.New("test")) 270 bs := queryResults.GetBytes() 271 //ioutil.WriteFile("../testing/data/query/hll_query_results", bs, 0644) 272 273 results, errs, err = queryCom.ParseHLLQueryResults(bs) 274 Ω(err).Should(BeNil()) 275 Ω(errs).Should(HaveLen(2)) 276 Ω(results).Should(HaveLen(2)) 277 Ω(errs[1].Error()).Should(Equal("test")) 278 }) 279 })