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  }