github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/lsmkv/segmentindex/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 segmentindex
    13  
    14  import (
    15  	"testing"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  	"github.com/weaviate/weaviate/entities/lsmkv"
    20  )
    21  
    22  func TestTree(t *testing.T) {
    23  	type elem struct {
    24  		key   []byte
    25  		start uint64
    26  		end   uint64
    27  	}
    28  
    29  	tree := NewTree(4)
    30  
    31  	elements := []elem{
    32  		{
    33  			key:   []byte("foobar"),
    34  			start: 17,
    35  			end:   18,
    36  		},
    37  		{
    38  			key:   []byte("abc"),
    39  			start: 4,
    40  			end:   5,
    41  		},
    42  		{
    43  			key:   []byte("zzz"),
    44  			start: 34,
    45  			end:   35,
    46  		},
    47  		{
    48  			key:   []byte("aaa"),
    49  			start: 1,
    50  			end:   2,
    51  		},
    52  		{
    53  			// makes the tree slightly imbalanced to the right, which in turn assures
    54  			// that we have a nil node in between
    55  			key:   []byte("zzzz"),
    56  			start: 100,
    57  			end:   102,
    58  		},
    59  	}
    60  
    61  	t.Run("inserting", func(t *testing.T) {
    62  		for _, elem := range elements {
    63  			tree.Insert(elem.key, elem.start, elem.end)
    64  		}
    65  	})
    66  
    67  	t.Run("exact get", func(t *testing.T) {
    68  		key, start, end := tree.Get([]byte("foobar"))
    69  		assert.Equal(t, []byte("foobar"), key)
    70  		assert.Equal(t, uint64(17), start)
    71  		assert.Equal(t, uint64(18), end)
    72  
    73  		key, start, end = tree.Get([]byte("abc"))
    74  		assert.Equal(t, []byte("abc"), key)
    75  		assert.Equal(t, uint64(4), start)
    76  		assert.Equal(t, uint64(5), end)
    77  
    78  		key, start, end = tree.Get([]byte("zzz"))
    79  		assert.Equal(t, []byte("zzz"), key)
    80  		assert.Equal(t, uint64(34), start)
    81  		assert.Equal(t, uint64(35), end)
    82  
    83  		key, start, end = tree.Get([]byte("aaa"))
    84  		assert.Equal(t, []byte("aaa"), key)
    85  		assert.Equal(t, uint64(1), start)
    86  		assert.Equal(t, uint64(2), end)
    87  
    88  		key, start, end = tree.Get([]byte("zzzz"))
    89  		assert.Equal(t, []byte("zzzz"), key)
    90  		assert.Equal(t, uint64(100), start)
    91  		assert.Equal(t, uint64(102), end)
    92  	})
    93  
    94  	t.Run("marshalling and then reading the byte representation", func(t *testing.T) {
    95  		bytes, err := tree.MarshalBinary()
    96  		require.Nil(t, err)
    97  
    98  		dTree := NewDiskTree(bytes)
    99  
   100  		t.Run("get", func(t *testing.T) {
   101  			n, err := dTree.Get([]byte("foobar"))
   102  			assert.Nil(t, err)
   103  			assert.Equal(t, []byte("foobar"), n.Key)
   104  			assert.Equal(t, uint64(17), n.Start)
   105  			assert.Equal(t, uint64(18), n.End)
   106  
   107  			n, err = dTree.Get([]byte("abc"))
   108  			assert.Nil(t, err)
   109  			assert.Equal(t, []byte("abc"), n.Key)
   110  			assert.Equal(t, uint64(4), n.Start)
   111  			assert.Equal(t, uint64(5), n.End)
   112  
   113  			n, err = dTree.Get([]byte("zzz"))
   114  			assert.Nil(t, err)
   115  			assert.Equal(t, []byte("zzz"), n.Key)
   116  			assert.Equal(t, uint64(34), n.Start)
   117  			assert.Equal(t, uint64(35), n.End)
   118  
   119  			n, err = dTree.Get([]byte("aaa"))
   120  			assert.Nil(t, err)
   121  			assert.Equal(t, []byte("aaa"), n.Key)
   122  			assert.Equal(t, uint64(1), n.Start)
   123  			assert.Equal(t, uint64(2), n.End)
   124  
   125  			n, err = dTree.Get([]byte("zzzz"))
   126  			assert.Nil(t, err)
   127  			assert.Equal(t, []byte("zzzz"), n.Key)
   128  			assert.Equal(t, uint64(100), n.Start)
   129  			assert.Equal(t, uint64(102), n.End)
   130  		})
   131  
   132  		t.Run("seek", func(t *testing.T) {
   133  			n, err := dTree.Seek([]byte("foobar"))
   134  			assert.Nil(t, err)
   135  			assert.Equal(t, []byte("foobar"), n.Key)
   136  			assert.Equal(t, uint64(17), n.Start)
   137  			assert.Equal(t, uint64(18), n.End)
   138  
   139  			n, err = dTree.Seek([]byte("f"))
   140  			assert.Nil(t, err)
   141  			assert.Equal(t, []byte("foobar"), n.Key)
   142  			assert.Equal(t, uint64(17), n.Start)
   143  			assert.Equal(t, uint64(18), n.End)
   144  
   145  			n, err = dTree.Seek([]byte("abc"))
   146  			assert.Nil(t, err)
   147  			assert.Equal(t, []byte("abc"), n.Key)
   148  			assert.Equal(t, uint64(4), n.Start)
   149  			assert.Equal(t, uint64(5), n.End)
   150  
   151  			n, err = dTree.Seek([]byte("ab"))
   152  			assert.Nil(t, err)
   153  			assert.Equal(t, []byte("abc"), n.Key)
   154  			assert.Equal(t, uint64(4), n.Start)
   155  			assert.Equal(t, uint64(5), n.End)
   156  
   157  			n, err = dTree.Seek([]byte("zzz"))
   158  			assert.Nil(t, err)
   159  			assert.Equal(t, []byte("zzz"), n.Key)
   160  			assert.Equal(t, uint64(34), n.Start)
   161  			assert.Equal(t, uint64(35), n.End)
   162  
   163  			n, err = dTree.Seek([]byte("z"))
   164  			assert.Nil(t, err)
   165  			assert.Equal(t, []byte("zzz"), n.Key)
   166  			assert.Equal(t, uint64(34), n.Start)
   167  			assert.Equal(t, uint64(35), n.End)
   168  
   169  			n, err = dTree.Seek([]byte("aaa"))
   170  			assert.Nil(t, err)
   171  			assert.Equal(t, []byte("aaa"), n.Key)
   172  			assert.Equal(t, uint64(1), n.Start)
   173  			assert.Equal(t, uint64(2), n.End)
   174  
   175  			n, err = dTree.Seek([]byte("a"))
   176  			assert.Nil(t, err)
   177  			assert.Equal(t, []byte("aaa"), n.Key)
   178  			assert.Equal(t, uint64(1), n.Start)
   179  			assert.Equal(t, uint64(2), n.End)
   180  
   181  			n, err = dTree.Seek([]byte("zzzz"))
   182  			assert.Nil(t, err)
   183  			assert.Equal(t, []byte("zzzz"), n.Key)
   184  			assert.Equal(t, uint64(100), n.Start)
   185  			assert.Equal(t, uint64(102), n.End)
   186  
   187  			n, err = dTree.Seek([]byte("zzza"))
   188  			assert.Nil(t, err)
   189  			assert.Equal(t, []byte("zzzz"), n.Key)
   190  			assert.Equal(t, uint64(100), n.Start)
   191  			assert.Equal(t, uint64(102), n.End)
   192  
   193  			n, err = dTree.Seek([]byte("zzzzz"))
   194  			assert.Equal(t, lsmkv.NotFound, err)
   195  		})
   196  
   197  		t.Run("get all keys (for building bloom filters at segment init time)", func(t *testing.T) {
   198  			expected := [][]byte{
   199  				[]byte("aaa"),
   200  				[]byte("abc"),
   201  				[]byte("foobar"),
   202  				[]byte("zzz"),
   203  				[]byte("zzzz"),
   204  			}
   205  
   206  			keys, err := dTree.AllKeys()
   207  
   208  			require.Nil(t, err)
   209  			assert.ElementsMatch(t, expected, keys)
   210  		})
   211  	})
   212  }