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  })