github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/strategies_roaring_set_integration_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 //go:build integrationTest 13 // +build integrationTest 14 15 package lsmkv 16 17 import ( 18 "context" 19 "testing" 20 21 "github.com/stretchr/testify/assert" 22 "github.com/stretchr/testify/require" 23 "github.com/weaviate/weaviate/entities/cyclemanager" 24 ) 25 26 func TestRoaringSetStrategy(t *testing.T) { 27 ctx := testCtx() 28 tests := bucketIntegrationTests{ 29 { 30 name: "roaringsetInsertAndSetAdd", 31 f: roaringsetInsertAndSetAdd, 32 opts: []BucketOption{ 33 WithStrategy(StrategyRoaringSet), 34 }, 35 }, 36 } 37 tests.run(ctx, t) 38 } 39 40 func roaringsetInsertAndSetAdd(ctx context.Context, t *testing.T, opts []BucketOption) { 41 dirName := t.TempDir() 42 43 t.Run("memtable-only", func(t *testing.T) { 44 b, err := NewBucket(ctx, dirName, "", nullLogger(), nil, 45 cyclemanager.NewCallbackGroupNoop(), cyclemanager.NewCallbackGroupNoop(), opts...) 46 require.Nil(t, err) 47 48 // so big it effectively never triggers as part of this test 49 b.SetMemtableThreshold(1e9) 50 51 key1 := []byte("test1-key-1") 52 key2 := []byte("test1-key-2") 53 key3 := []byte("test1-key-3") 54 55 t.Run("set original values and verify", func(t *testing.T) { 56 orig1 := []uint64{1, 2} 57 orig2 := []uint64{3, 4} 58 orig3 := []uint64{5, 6} 59 60 err = b.RoaringSetAddList(key1, orig1) 61 require.Nil(t, err) 62 err = b.RoaringSetAddList(key2, orig2) 63 require.Nil(t, err) 64 err = b.RoaringSetAddList(key3, orig3) 65 require.Nil(t, err) 66 67 res, err := b.RoaringSetGet(key1) 68 require.Nil(t, err) 69 for _, testVal := range orig1 { 70 assert.True(t, res.Contains(testVal)) 71 } 72 73 res, err = b.RoaringSetGet(key2) 74 require.Nil(t, err) 75 for _, testVal := range orig2 { 76 assert.True(t, res.Contains(testVal)) 77 } 78 79 res, err = b.RoaringSetGet(key3) 80 require.Nil(t, err) 81 for _, testVal := range orig3 { 82 assert.True(t, res.Contains(testVal)) 83 } 84 }) 85 86 t.Run("extend some, delete some, keep some", func(t *testing.T) { 87 additions2 := []uint64{5} 88 removal3 := uint64(5) 89 90 err = b.RoaringSetAddList(key2, additions2) 91 require.Nil(t, err) 92 err = b.RoaringSetRemoveOne(key3, removal3) 93 require.Nil(t, err) 94 95 res, err := b.RoaringSetGet(key1) 96 require.Nil(t, err) 97 for _, testVal := range []uint64{1, 2} { // unchanged values 98 assert.True(t, res.Contains(testVal)) 99 } 100 101 res, err = b.RoaringSetGet(key2) 102 require.Nil(t, err) 103 for _, testVal := range []uint64{3, 4, 5} { // extended with 5 104 assert.True(t, res.Contains(testVal)) 105 } 106 107 res, err = b.RoaringSetGet(key3) 108 require.Nil(t, err) 109 for _, testVal := range []uint64{6} { // fewer remain 110 assert.True(t, res.Contains(testVal)) 111 } 112 for _, testVal := range []uint64{5} { // no longer contained 113 assert.False(t, res.Contains(testVal)) 114 } 115 }) 116 }) 117 118 t.Run("with a single flush in between updates", func(t *testing.T) { 119 b, err := NewBucket(ctx, dirName, "", nullLogger(), nil, 120 cyclemanager.NewCallbackGroupNoop(), cyclemanager.NewCallbackGroupNoop(), opts...) 121 require.Nil(t, err) 122 123 // so big it effectively never triggers as part of this test 124 b.SetMemtableThreshold(1e9) 125 126 key1 := []byte("test1-key-1") 127 key2 := []byte("test1-key-2") 128 key3 := []byte("test1-key-3") 129 130 t.Run("set original values and verify", func(t *testing.T) { 131 orig1 := []uint64{1, 2} 132 orig2 := []uint64{3, 4} 133 orig3 := []uint64{5, 6} 134 135 err = b.RoaringSetAddList(key1, orig1) 136 require.Nil(t, err) 137 err = b.RoaringSetAddList(key2, orig2) 138 require.Nil(t, err) 139 err = b.RoaringSetAddList(key3, orig3) 140 require.Nil(t, err) 141 142 res, err := b.RoaringSetGet(key1) 143 require.Nil(t, err) 144 for _, testVal := range orig1 { 145 assert.True(t, res.Contains(testVal)) 146 } 147 148 res, err = b.RoaringSetGet(key2) 149 require.Nil(t, err) 150 for _, testVal := range orig2 { 151 assert.True(t, res.Contains(testVal)) 152 } 153 154 res, err = b.RoaringSetGet(key3) 155 require.Nil(t, err) 156 for _, testVal := range orig3 { 157 assert.True(t, res.Contains(testVal)) 158 } 159 }) 160 161 t.Run("flush to disk", func(t *testing.T) { 162 require.Nil(t, b.FlushAndSwitch()) 163 }) 164 165 t.Run("extend some, delete some, keep some", func(t *testing.T) { 166 additions2 := []uint64{5} 167 removal3 := uint64(5) 168 169 err = b.RoaringSetAddList(key2, additions2) 170 require.Nil(t, err) 171 err = b.RoaringSetRemoveOne(key3, removal3) 172 require.Nil(t, err) 173 174 res, err := b.RoaringSetGet(key1) 175 require.Nil(t, err) 176 for _, testVal := range []uint64{1, 2} { // unchanged values 177 assert.True(t, res.Contains(testVal)) 178 } 179 180 res, err = b.RoaringSetGet(key2) 181 require.Nil(t, err) 182 for _, testVal := range []uint64{3, 4, 5} { // extended with 5 183 assert.True(t, res.Contains(testVal)) 184 } 185 186 res, err = b.RoaringSetGet(key3) 187 require.Nil(t, err) 188 for _, testVal := range []uint64{6} { // fewer remain 189 assert.True(t, res.Contains(testVal)) 190 } 191 for _, testVal := range []uint64{5} { // no longer contained 192 assert.False(t, res.Contains(testVal)) 193 } 194 }) 195 }) 196 }