github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/memstore/common/upsert_batch_builder_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 common 16 17 import ( 18 "github.com/onsi/ginkgo" 19 . "github.com/onsi/gomega" 20 "github.com/uber/aresdb/utils" 21 "time" 22 "unsafe" 23 ) 24 25 var _ = ginkgo.Describe("upsert batch builder", func() { 26 27 ginkgo.BeforeEach(func() { 28 utils.SetCurrentTime(time.Unix(10, 0)) 29 }) 30 31 ginkgo.AfterEach(func() { 32 utils.ResetClockImplementation() 33 }) 34 35 ginkgo.It("works for empty batch", func() { 36 builder := NewUpsertBatchBuilder() 37 // write with new version 38 bufferNew, err := builder.ToByteArray() 39 Ω(err).Should(BeNil()) 40 Ω(bufferNew).Should(Equal([]byte{1, 0, 237, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0})) 41 }) 42 43 ginkgo.It("works for empty row", func() { 44 builder := NewUpsertBatchBuilder() 45 builder.AddColumn(123, Uint8) 46 buffer, err := builder.ToByteArray() 47 Ω(err).Should(BeNil()) 48 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 123, 0, 0, 0, 0, 0, 0, 0})) 49 }) 50 51 ginkgo.It("works for empty column", func() { 52 builder := NewUpsertBatchBuilder() 53 builder.AddRow() 54 buffer, err := builder.ToByteArray() 55 Ω(err).Should(BeNil()) 56 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0})) 57 }) 58 59 ginkgo.It("works for one row, one col, no value", func() { 60 builder := NewUpsertBatchBuilder() 61 builder.AddRow() 62 err := builder.AddColumn(123, Uint8) 63 Ω(err).Should(BeNil()) 64 buffer, err := builder.ToByteArray() 65 Ω(err).Should(BeNil()) 66 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 123, 0, 0, 0, 0, 0, 0, 0})) 67 }) 68 69 ginkgo.It("works for one row, one col, one value", func() { 70 builder := NewUpsertBatchBuilder() 71 builder.AddRow() 72 err := builder.AddColumn(123, Uint8) 73 builder.SetValue(0, 0, uint8(135)) 74 buffer, err := builder.ToByteArray() 75 Ω(err).Should(BeNil()) 76 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 123, 0, 1, 0, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0})) 77 }) 78 79 ginkgo.It("reset row works", func() { 80 builder := NewUpsertBatchBuilder() 81 builder.AddRow() 82 err := builder.AddColumn(123, Uint8) 83 builder.SetValue(0, 0, uint8(135)) 84 builder.ResetRows() 85 buffer, err := builder.ToByteArray() 86 Ω(err).Should(BeNil()) 87 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 123, 0, 0, 0, 0, 0, 0, 0})) 88 }) 89 90 ginkgo.It("raises error when setting wrong value type", func() { 91 builder := NewUpsertBatchBuilder() 92 builder.AddRow() 93 builder.AddColumn(123, Uint8) 94 err := builder.SetValue(0, 0, "a") 95 Ω(err).ShouldNot(BeNil()) 96 buffer, err := builder.ToByteArray() 97 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 2, 0, 123, 0, 0, 0, 0, 0, 0, 0})) 98 }) 99 100 ginkgo.It("last value wins", func() { 101 builder := NewUpsertBatchBuilder() 102 builder.AddRow() 103 builder.AddRow() 104 builder.AddColumn(123, Bool) 105 err := builder.SetValue(0, 0, false) 106 Ω(err).Should(BeNil()) 107 108 buffer, err := builder.ToByteArray() 109 Ω(err).Should(BeNil()) 110 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 123, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})) 111 112 buffer, err = builder.ToByteArray() 113 Ω(err).Should(BeNil()) 114 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 123, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})) 115 116 err = builder.SetValue(0, 0, nil) 117 Ω(err).Should(BeNil()) 118 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 123, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})) 119 120 buffer, err = builder.ToByteArray() 121 Ω(err).Should(BeNil()) 122 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 51, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0})) 123 }) 124 125 ginkgo.It("works for bool type", func() { 126 builder := NewUpsertBatchBuilder() 127 128 // All null bools. 129 err := builder.AddColumn(123, Bool) 130 Ω(err).Should(BeNil()) 131 132 // Half valid bools. 133 err = builder.AddColumn(456, Bool) 134 builder.AddRow() 135 Ω(err).Should(BeNil()) 136 err = builder.SetValue(0, 1, true) 137 138 // All valid bools. 139 err = builder.AddColumn(789, Bool) 140 builder.AddRow() 141 Ω(err).Should(BeNil()) 142 err = builder.SetValue(0, 2, true) 143 Ω(err).Should(BeNil()) 144 err = builder.SetValue(1, 2, false) 145 Ω(err).Should(BeNil()) 146 147 buffer, err := builder.ToByteArray() 148 Ω(err).Should(BeNil()) 149 Ω(buffer).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 89, 0, 0, 0, 89, 0, 0, 0, 97, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 123, 0, 200, 1, 21, 3, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0})) 150 }) 151 152 ginkgo.It("UpdateOverWrite add column ex fail", func() { 153 builder := NewUpsertBatchBuilder() 154 err := builder.AddColumn(1, Uint8) 155 Ω(err).Should(BeNil()) 156 err = builder.AddColumnWithUpdateMode(2, Uint8, UpdateWithAddition) 157 Ω(err).Should(BeNil()) 158 err = builder.AddColumnWithUpdateMode(2, Uint8, MaxColumnUpdateMode) 159 Ω(err).ShouldNot(BeNil()) 160 }) 161 162 ginkgo.It("AdditionUpdate should work", func() { 163 // big enough to hold all numeric types 164 var oldValue int64 165 var newValue int64 166 *(*int8)(unsafe.Pointer(&oldValue)) = -1 167 *(*int8)(unsafe.Pointer(&newValue)) = 1 168 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int8) 169 Ω(*(*int8)(unsafe.Pointer(&oldValue))).Should(Equal(int8(0))) 170 171 *(*uint8)(unsafe.Pointer(&oldValue)) = 1 172 *(*uint8)(unsafe.Pointer(&newValue)) = 1 173 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint8) 174 Ω(*(*uint8)(unsafe.Pointer(&oldValue))).Should(Equal(uint8(2))) 175 176 *(*int16)(unsafe.Pointer(&oldValue)) = -256 177 *(*int16)(unsafe.Pointer(&newValue)) = 256 178 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int16) 179 Ω(*(*int16)(unsafe.Pointer(&oldValue))).Should(Equal(int16(0))) 180 181 *(*uint16)(unsafe.Pointer(&oldValue)) = 1 182 *(*uint16)(unsafe.Pointer(&newValue)) = 256 183 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint16) 184 Ω(*(*uint16)(unsafe.Pointer(&oldValue))).Should(Equal(uint16(257))) 185 186 *(*int32)(unsafe.Pointer(&oldValue)) = -65536 187 *(*int32)(unsafe.Pointer(&newValue)) = 65536 188 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int32) 189 Ω(*(*int32)(unsafe.Pointer(&oldValue))).Should(Equal(int32(0))) 190 191 *(*uint32)(unsafe.Pointer(&oldValue)) = 1 192 *(*uint32)(unsafe.Pointer(&newValue)) = 65536 193 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint32) 194 Ω(*(*uint32)(unsafe.Pointer(&oldValue))).Should(Equal(uint32(65537))) 195 196 *(*float32)(unsafe.Pointer(&oldValue)) = -1.0 197 *(*float32)(unsafe.Pointer(&newValue)) = 1.0 198 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Float32) 199 Ω(*(*float32)(unsafe.Pointer(&oldValue))).Should(Equal(float32(0.0))) 200 201 *(*int64)(unsafe.Pointer(&oldValue)) = -(1 << 31) - 1 202 *(*int64)(unsafe.Pointer(&newValue)) = (1 << 31) + 1 203 AdditionUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int64) 204 Ω(*(*int64)(unsafe.Pointer(&oldValue))).Should(Equal(int64(0))) 205 }) 206 207 ginkgo.It("MinMaxUpdate should work", func() { 208 // big enough to hold all numeric types 209 var oldValue int64 210 var newValue int64 211 *(*int8)(unsafe.Pointer(&oldValue)) = -1 212 *(*int8)(unsafe.Pointer(&newValue)) = 1 213 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int8, CompareInt8, 1) 214 Ω(*(*int8)(unsafe.Pointer(&oldValue))).Should(Equal(int8(-1))) 215 216 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int8, CompareInt8, -1) 217 Ω(*(*int8)(unsafe.Pointer(&oldValue))).Should(Equal(int8(1))) 218 219 *(*uint8)(unsafe.Pointer(&oldValue)) = 0 220 *(*uint8)(unsafe.Pointer(&newValue)) = 1 221 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint8, CompareUint8, 1) 222 Ω(*(*uint8)(unsafe.Pointer(&oldValue))).Should(Equal(uint8(0))) 223 224 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint8, CompareUint8, -1) 225 Ω(*(*uint8)(unsafe.Pointer(&oldValue))).Should(Equal(uint8(1))) 226 227 *(*int16)(unsafe.Pointer(&oldValue)) = -256 228 *(*int16)(unsafe.Pointer(&newValue)) = 256 229 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int16, CompareInt16, 1) 230 Ω(*(*int16)(unsafe.Pointer(&oldValue))).Should(Equal(int16(-256))) 231 232 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int16, CompareInt16, -1) 233 Ω(*(*int16)(unsafe.Pointer(&oldValue))).Should(Equal(int16(256))) 234 235 *(*uint16)(unsafe.Pointer(&oldValue)) = 0 236 *(*uint16)(unsafe.Pointer(&newValue)) = 256 237 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint16, CompareUint16, 1) 238 Ω(*(*uint16)(unsafe.Pointer(&oldValue))).Should(Equal(uint16(0))) 239 240 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint16, CompareUint16, -1) 241 Ω(*(*uint16)(unsafe.Pointer(&oldValue))).Should(Equal(uint16(256))) 242 243 *(*int32)(unsafe.Pointer(&oldValue)) = -65536 244 *(*int32)(unsafe.Pointer(&newValue)) = 65536 245 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int32, CompareInt32, 1) 246 Ω(*(*int32)(unsafe.Pointer(&oldValue))).Should(Equal(int32(-65536))) 247 248 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int32, CompareInt32, -1) 249 Ω(*(*int32)(unsafe.Pointer(&oldValue))).Should(Equal(int32(65536))) 250 251 *(*uint32)(unsafe.Pointer(&oldValue)) = 0 252 *(*uint32)(unsafe.Pointer(&newValue)) = 65536 253 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint32, CompareUint32, 1) 254 Ω(*(*uint32)(unsafe.Pointer(&oldValue))).Should(Equal(uint32(0))) 255 256 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Uint32, CompareUint32, -1) 257 Ω(*(*uint32)(unsafe.Pointer(&oldValue))).Should(Equal(uint32(65536))) 258 259 *(*int64)(unsafe.Pointer(&oldValue)) = -(1 << 31) - 1 260 *(*int64)(unsafe.Pointer(&newValue)) = (1 << 31) + 1 261 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int64, CompareInt64, 1) 262 Ω(*(*int64)(unsafe.Pointer(&oldValue))).Should(Equal(int64(-(1 << 31) - 1))) 263 264 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Int64, CompareInt64, -1) 265 Ω(*(*int64)(unsafe.Pointer(&oldValue))).Should(Equal(int64((1 << 31) + 1))) 266 267 *(*float32)(unsafe.Pointer(&oldValue)) = -1.0 268 *(*float32)(unsafe.Pointer(&newValue)) = 1.0 269 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Float32, CompareFloat32, 1) 270 Ω(*(*float32)(unsafe.Pointer(&oldValue))).Should(Equal(float32(-1.0))) 271 272 MinMaxUpdate(unsafe.Pointer(&oldValue), unsafe.Pointer(&newValue), Float32, CompareFloat32, -1) 273 Ω(*(*float32)(unsafe.Pointer(&oldValue))).Should(Equal(float32(1.0))) 274 }) 275 276 ginkgo.It("set enum as string directly", func() { 277 builder := NewUpsertBatchBuilder() 278 err := builder.AddColumn(0, SmallEnum) 279 Ω(err).Should(BeNil()) 280 err = builder.AddColumn(1, BigEnum) 281 Ω(err).Should(BeNil()) 282 283 builder.AddRow() 284 builder.SetValue(0, 0, "s1") 285 builder.SetValue(0, 1, "b1") 286 builder.AddRow() 287 builder.SetValue(1, 0, "s2") 288 builder.SetValue(1, 1, "b2") 289 290 byts, err := builder.ToByteArray() 291 Ω(err).Should(BeNil()) 292 Ω(byts).Should(Equal([]byte{1, 0, 237, 254, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 70, 0, 0, 0, 82, 0, 0, 0, 100, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 0, 16, 0, 9, 0, 0, 0, 1, 0, 1, 1, 1, 115, 49, 0, 10, 115, 50, 0, 0, 0, 0, 1, 1, 98, 49, 0, 10, 98, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0})) 293 }) 294 })