github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/binary_search_tree_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package lsmkv 13 14 import ( 15 "crypto/rand" 16 "testing" 17 18 "github.com/google/uuid" 19 "github.com/stretchr/testify/require" 20 ) 21 22 // This test asserts that the *binarySearchTree.insert 23 // method properly calculates the net additions of a 24 // new node into the tree 25 func TestInsertNetAdditions_Replace(t *testing.T) { 26 t.Run("single node entry", func(t *testing.T) { 27 tree := &binarySearchTree{} 28 29 key := make([]byte, 8) 30 val := make([]byte, 8) 31 32 rand.Read(key) 33 rand.Read(val) 34 35 n, _ := tree.insert(key, val, nil) 36 require.Equal(t, len(key)+len(val), n) 37 }) 38 39 t.Run("multiple unique node entries", func(t *testing.T) { 40 tree := &binarySearchTree{} 41 42 amount := 100 43 size := 8 44 45 var n int 46 for i := 0; i < amount; i++ { 47 key := make([]byte, size) 48 val := make([]byte, size) 49 50 rand.Read(key) 51 rand.Read(val) 52 53 newAdditions, _ := tree.insert(key, val, nil) 54 n += newAdditions 55 } 56 57 require.Equal(t, amount*size*2, n) 58 }) 59 60 t.Run("multiple non-unique node entries", func(t *testing.T) { 61 tree := &binarySearchTree{} 62 63 var ( 64 amount = 100 65 keySize = 100 66 origValSize = 100 67 newValSize = origValSize * 100 68 keys = make([][]byte, amount) 69 vals = make([][]byte, amount) 70 71 netAdditions int 72 ) 73 74 // write the keys and original values 75 for i := range keys { 76 key := make([]byte, keySize) 77 rand.Read(key) 78 79 val := make([]byte, origValSize) 80 rand.Read(val) 81 82 keys[i], vals[i] = key, val 83 } 84 85 // make initial inserts 86 for i := range keys { 87 currentNetAddition, _ := tree.insert(keys[i], vals[i], nil) 88 netAdditions += currentNetAddition 89 } 90 91 // change the values of the existing keys 92 // with new values of different length 93 for i := 0; i < amount; i++ { 94 val := make([]byte, newValSize) 95 rand.Read(val) 96 97 vals[i] = val 98 } 99 100 for i := 0; i < amount; i++ { 101 currentNetAddition, _ := tree.insert(keys[i], vals[i], nil) 102 netAdditions += currentNetAddition 103 } 104 105 // Formulas for calculating the total net additions after 106 // updating the keys with differently sized values 107 expectedFirstNetAdd := amount * (keySize + origValSize) 108 expectedSecondNetAdd := (amount * (keySize + newValSize)) - (amount * keySize) - (amount * origValSize) 109 expectedNetAdditions := expectedFirstNetAdd + expectedSecondNetAdd 110 111 require.Equal(t, expectedNetAdditions, netAdditions) 112 }) 113 114 // test to assure multiple tombstone nodes are not created when same value is added and deleted multiple times 115 // https://semi-technology.atlassian.net/browse/WEAVIATE-31 116 t.Run("consecutive adding and deleting value does not multiply nodes", func(t *testing.T) { 117 tree := &binarySearchTree{} 118 119 key := []byte(uuid.New().String()) 120 value := make([]byte, 100) 121 rand.Read(value) 122 123 for i := 0; i < 10; i++ { 124 tree.insert(key, value, nil) 125 tree.setTombstone(key, nil) 126 } 127 128 flat := tree.flattenInOrder() 129 130 require.Equal(t, 1, len(flat)) 131 require.True(t, flat[0].tombstone) 132 }) 133 }