github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/compaction_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 "os" 20 "path/filepath" 21 "testing" 22 23 "github.com/sirupsen/logrus" 24 "github.com/sirupsen/logrus/hooks/test" 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 ) 28 29 func testCtx() context.Context { 30 return context.Background() 31 } 32 33 type bucketIntegrationTest struct { 34 name string 35 f func(context.Context, *testing.T, []BucketOption) 36 opts []BucketOption 37 } 38 39 type bucketIntegrationTests []bucketIntegrationTest 40 41 func (tests bucketIntegrationTests) run(ctx context.Context, t *testing.T) { 42 for _, test := range tests { 43 t.Run(test.name, func(t *testing.T) { 44 t.Run("mmap", func(t *testing.T) { 45 test.f(ctx, t, test.opts) 46 }) 47 t.Run("pread", func(t *testing.T) { 48 test.f(ctx, t, append([]BucketOption{WithPread(true)}, test.opts...)) 49 }) 50 }) 51 } 52 } 53 54 func TestCompaction(t *testing.T) { 55 ctx := testCtx() 56 tests := bucketIntegrationTests{ 57 { 58 name: "compactionReplaceStrategy", 59 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 60 compactionReplaceStrategy(ctx, t, opts, 12116, 12116) 61 }, 62 opts: []BucketOption{ 63 WithStrategy(StrategyReplace), 64 }, 65 }, 66 { 67 name: "compactionReplaceStrategy_KeepTombstones", 68 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 69 compactionReplaceStrategy(ctx, t, opts, 15266, 15266) 70 }, 71 opts: []BucketOption{ 72 WithStrategy(StrategyReplace), 73 WithKeepTombstones(true), 74 }, 75 }, 76 { 77 name: "compactionReplaceStrategy_WithSecondaryKeys", 78 f: compactionReplaceStrategy_WithSecondaryKeys, 79 opts: []BucketOption{ 80 WithStrategy(StrategyReplace), 81 WithSecondaryIndices(1), 82 }, 83 }, 84 { 85 name: "compactionReplaceStrategy_WithSecondaryKeys_KeepTombstones", 86 f: compactionReplaceStrategy_WithSecondaryKeys, 87 opts: []BucketOption{ 88 WithStrategy(StrategyReplace), 89 WithSecondaryIndices(1), 90 WithKeepTombstones(true), 91 }, 92 }, 93 { 94 name: "compactionReplaceStrategy_RemoveUnnecessaryDeletes", 95 f: compactionReplaceStrategy_RemoveUnnecessaryDeletes, 96 opts: []BucketOption{ 97 WithStrategy(StrategyReplace), 98 }, 99 }, 100 { 101 name: "compactionReplaceStrategy_RemoveUnnecessaryDeletes_KeepTombstones", 102 f: compactionReplaceStrategy_RemoveUnnecessaryDeletes, 103 opts: []BucketOption{ 104 WithStrategy(StrategyReplace), 105 WithKeepTombstones(true), 106 }, 107 }, 108 { 109 name: "compactionReplaceStrategy_RemoveUnnecessaryUpdates", 110 f: compactionReplaceStrategy_RemoveUnnecessaryUpdates, 111 opts: []BucketOption{ 112 WithStrategy(StrategyReplace), 113 }, 114 }, 115 { 116 name: "compactionReplaceStrategy_RemoveUnnecessaryUpdates_KeepTombstones", 117 f: compactionReplaceStrategy_RemoveUnnecessaryUpdates, 118 opts: []BucketOption{ 119 WithStrategy(StrategyReplace), 120 WithKeepTombstones(true), 121 }, 122 }, 123 { 124 name: "compactionReplaceStrategy_FrequentPutDeleteOperations", 125 f: compactionReplaceStrategy_FrequentPutDeleteOperations, 126 opts: []BucketOption{ 127 WithStrategy(StrategyReplace), 128 }, 129 }, 130 { 131 name: "compactionReplaceStrategy_FrequentPutDeleteOperations_KeepTombstones", 132 f: compactionReplaceStrategy_FrequentPutDeleteOperations, 133 opts: []BucketOption{ 134 WithStrategy(StrategyReplace), 135 WithKeepTombstones(true), 136 }, 137 }, 138 { 139 name: "compactionReplaceStrategy_FrequentPutDeleteOperations_WithSecondaryKeys", 140 f: compactionReplaceStrategy_FrequentPutDeleteOperations_WithSecondaryKeys, 141 opts: []BucketOption{ 142 WithStrategy(StrategyReplace), 143 WithSecondaryIndices(1), 144 }, 145 }, 146 { 147 name: "compactionReplaceStrategy_FrequentPutDeleteOperations_WithSecondaryKeys_KeepTombstones", 148 f: compactionReplaceStrategy_FrequentPutDeleteOperations_WithSecondaryKeys, 149 opts: []BucketOption{ 150 WithStrategy(StrategyReplace), 151 WithSecondaryIndices(1), 152 WithKeepTombstones(true), 153 }, 154 }, 155 156 { 157 name: "compactionSetStrategy", 158 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 159 compactionSetStrategy(ctx, t, opts, 6836, 6836) 160 }, 161 opts: []BucketOption{ 162 WithStrategy(StrategySetCollection), 163 }, 164 }, 165 { 166 name: "compactionSetStrategy_KeepTombstones", 167 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 168 compactionSetStrategy(ctx, t, opts, 9756, 9756) 169 }, 170 opts: []BucketOption{ 171 WithStrategy(StrategySetCollection), 172 WithKeepTombstones(true), 173 }, 174 }, 175 { 176 name: "compactionSetStrategy_RemoveUnnecessary", 177 f: compactionSetStrategy_RemoveUnnecessary, 178 opts: []BucketOption{ 179 WithStrategy(StrategySetCollection), 180 }, 181 }, 182 { 183 name: "compactionSetStrategy_RemoveUnnecessary_KeepTombstones", 184 f: compactionSetStrategy_RemoveUnnecessary, 185 opts: []BucketOption{ 186 WithStrategy(StrategySetCollection), 187 WithKeepTombstones(true), 188 }, 189 }, 190 { 191 name: "compactionSetStrategy_FrequentPutDeleteOperations", 192 f: compactionSetStrategy_FrequentPutDeleteOperations, 193 opts: []BucketOption{ 194 WithStrategy(StrategySetCollection), 195 }, 196 }, 197 { 198 name: "compactionSetStrategy_FrequentPutDeleteOperations_KeepTombstones", 199 f: compactionSetStrategy_FrequentPutDeleteOperations, 200 opts: []BucketOption{ 201 WithStrategy(StrategySetCollection), 202 WithKeepTombstones(true), 203 }, 204 }, 205 206 { 207 name: "compactionMapStrategy", 208 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 209 compactionMapStrategy(ctx, t, opts, 10676, 10676) 210 }, 211 opts: []BucketOption{ 212 WithStrategy(StrategyMapCollection), 213 }, 214 }, 215 { 216 name: "compactionMapStrategy_KeepTombstones", 217 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 218 compactionMapStrategy(ctx, t, opts, 13416, 13416) 219 }, 220 opts: []BucketOption{ 221 WithStrategy(StrategyMapCollection), 222 WithKeepTombstones(true), 223 }, 224 }, 225 { 226 name: "compactionMapStrategy_RemoveUnnecessary", 227 f: compactionMapStrategy_RemoveUnnecessary, 228 opts: []BucketOption{ 229 WithStrategy(StrategyMapCollection), 230 }, 231 }, 232 { 233 name: "compactionMapStrategy_RemoveUnnecessary_KeepTombstones", 234 f: compactionMapStrategy_RemoveUnnecessary, 235 opts: []BucketOption{ 236 WithStrategy(StrategyMapCollection), 237 WithKeepTombstones(true), 238 }, 239 }, 240 { 241 name: "compactionMapStrategy_FrequentPutDeleteOperations", 242 f: compactionMapStrategy_FrequentPutDeleteOperations, 243 opts: []BucketOption{ 244 WithStrategy(StrategyMapCollection), 245 }, 246 }, 247 { 248 name: "compactionMapStrategy_FrequentPutDeleteOperations_KeepTombstones", 249 f: compactionMapStrategy_FrequentPutDeleteOperations, 250 opts: []BucketOption{ 251 WithStrategy(StrategyMapCollection), 252 WithKeepTombstones(true), 253 }, 254 }, 255 256 { 257 name: "compactionRoaringSetStrategy_Random", 258 f: compactionRoaringSetStrategy_Random, 259 opts: []BucketOption{ 260 WithStrategy(StrategyRoaringSet), 261 }, 262 }, 263 { 264 name: "compactionRoaringSetStrategy_Random_KeepTombstones", 265 f: compactionRoaringSetStrategy_Random, 266 opts: []BucketOption{ 267 WithStrategy(StrategyRoaringSet), 268 WithKeepTombstones(true), 269 }, 270 }, 271 { 272 name: "compactionRoaringSetStrategy", 273 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 274 compactionRoaringSetStrategy(ctx, t, opts, 19168, 19168) 275 }, 276 opts: []BucketOption{ 277 WithStrategy(StrategyRoaringSet), 278 }, 279 }, 280 { 281 name: "compactionRoaringSetStrategy_KeepTombstones", 282 f: func(ctx context.Context, t *testing.T, opts []BucketOption) { 283 compactionRoaringSetStrategy(ctx, t, opts, 29792, 29792) 284 }, 285 opts: []BucketOption{ 286 WithStrategy(StrategyRoaringSet), 287 WithKeepTombstones(true), 288 }, 289 }, 290 { 291 name: "compactionRoaringSetStrategy_RemoveUnnecessary", 292 f: compactionRoaringSetStrategy_RemoveUnnecessary, 293 opts: []BucketOption{ 294 WithStrategy(StrategyRoaringSet), 295 }, 296 }, 297 { 298 name: "compactionRoaringSetStrategy_RemoveUnnecessary_KeepTombstones", 299 f: compactionRoaringSetStrategy_RemoveUnnecessary, 300 opts: []BucketOption{ 301 WithStrategy(StrategyRoaringSet), 302 WithKeepTombstones(true), 303 }, 304 }, 305 { 306 name: "compactionRoaringSetStrategy_FrequentPutDeleteOperations", 307 f: compactionRoaringSetStrategy_FrequentPutDeleteOperations, 308 opts: []BucketOption{ 309 WithStrategy(StrategyRoaringSet), 310 }, 311 }, 312 { 313 name: "compactionRoaringSetStrategy_FrequentPutDeleteOperations_KeepTombstones", 314 f: compactionRoaringSetStrategy_FrequentPutDeleteOperations, 315 opts: []BucketOption{ 316 WithStrategy(StrategyRoaringSet), 317 WithKeepTombstones(true), 318 }, 319 }, 320 } 321 tests.run(ctx, t) 322 } 323 324 func nullLogger() logrus.FieldLogger { 325 log, _ := test.NewNullLogger() 326 return log 327 } 328 329 func copyByteSlice(src []byte) []byte { 330 dst := make([]byte, len(src)) 331 copy(dst, src) 332 return dst 333 } 334 335 func assertSingleSegmentOfSize(t *testing.T, bucket *Bucket, expectedMinSize, expectedMaxSize int64) { 336 files, err := bucket.ListFiles(context.Background(), bucket.dir) 337 require.NoError(t, err) 338 339 dbFiles := make([]string, 0, len(files)) 340 for _, f := range files { 341 if filepath.Ext(f) == ".db" { 342 dbFiles = append(dbFiles, f) 343 } 344 } 345 require.Len(t, dbFiles, 1) 346 347 fi, err := os.Stat(dbFiles[0]) 348 require.NoError(t, err) 349 assert.LessOrEqual(t, expectedMinSize, fi.Size()) 350 assert.GreaterOrEqual(t, expectedMaxSize, fi.Size()) 351 } 352 353 func assertSecondSegmentOfSize(t *testing.T, bucket *Bucket, expectedMinSize, expectedMaxSize int64) { 354 files, err := bucket.ListFiles(context.Background(), bucket.dir) 355 require.NoError(t, err) 356 357 dbFiles := make([]string, 0, len(files)) 358 for _, f := range files { 359 if filepath.Ext(f) == ".db" { 360 dbFiles = append(dbFiles, f) 361 } 362 } 363 require.Len(t, dbFiles, 2) 364 365 fi, err := os.Stat(dbFiles[1]) 366 require.NoError(t, err) 367 assert.LessOrEqual(t, expectedMinSize, fi.Size()) 368 assert.GreaterOrEqual(t, expectedMaxSize, fi.Size()) 369 }