github.com/scottcagno/storage@v1.8.0/pkg/lsmt/mtbl/rbtree_test.go (about)

     1  package mtbl
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/scottcagno/storage/pkg/lsmt/binary"
     7  	"github.com/scottcagno/storage/pkg/util"
     8  	"log"
     9  	"strconv"
    10  	"testing"
    11  )
    12  
    13  const (
    14  	thousand = 1000
    15  	n        = 1
    16  )
    17  
    18  func NewEntry(k, v string) *binary.Entry {
    19  	if v == "" {
    20  		return &binary.Entry{
    21  			Key: []byte(k),
    22  		}
    23  	}
    24  	return &binary.Entry{
    25  		Key:   []byte(k),
    26  		Value: []byte(v),
    27  	}
    28  }
    29  
    30  func TestFindNearest(t *testing.T) {
    31  	tree := NewRBTree()
    32  	// insert A, E, J, O, T, Z
    33  
    34  	tree.Put(NewEntry("e", "e"))
    35  	tree.Put(NewEntry("a", "a"))
    36  	tree.Put(NewEntry("t", "t"))
    37  	tree.Put(NewEntry("z", "z"))
    38  	tree.Put(NewEntry("j", "j"))
    39  	tree.Put(NewEntry("o", "o"))
    40  
    41  	// print tree
    42  	tree.Scan(func(e *binary.Entry) bool {
    43  		fmt.Printf("%s\n", e)
    44  		return true
    45  	})
    46  
    47  	// find O
    48  	key := NewEntry("o", "")
    49  	a, b, c, d := tree.GetApproxPrevNext(key)
    50  	fmt.Printf("find-%s: a=%s, b=%s, c=%s, d=%v\n", key, a, b, c, d)
    51  
    52  	// find K
    53  	key = NewEntry("k", "")
    54  	a, b, c, d = tree.GetApproxPrevNext(key)
    55  	fmt.Printf("find-%s: a=%q, b=%q, c=%q, d=%v\n", key, a, b, c, d)
    56  
    57  	// find F
    58  	key = NewEntry("f", "")
    59  	a, b, c, d = tree.GetApproxPrevNext(key)
    60  	fmt.Printf("find-%s: a=%q, b=%q, c=%q, d=%v\n", key, a, b, c, d)
    61  
    62  	tree.Close()
    63  }
    64  
    65  func TestNewRBTree(t *testing.T) {
    66  	var tree *RBTree
    67  	tree = NewRBTree()
    68  	util.AssertNotNil(t, tree)
    69  	tree.Close()
    70  }
    71  
    72  func makeKey(i int) *binary.Entry {
    73  	return &binary.Entry{
    74  		Key:   []byte(strconv.Itoa(i)),
    75  		Value: []byte(strconv.Itoa(i)),
    76  	}
    77  }
    78  
    79  // signature: Has(key string) (bool, int64)
    80  func TestRbTree_Has(t *testing.T) {
    81  	tree := NewRBTree()
    82  	util.AssertLen(t, 0, tree.Len())
    83  	for i := 0; i < n*thousand; i++ {
    84  		tree.Put(makeKey(i))
    85  	}
    86  	for i := 0; i < n*thousand; i++ {
    87  		ok := tree.Has(makeKey(i))
    88  		if !ok { // existing=updated
    89  			t.Errorf("has: %v", ok)
    90  		}
    91  	}
    92  	util.AssertLen(t, n*thousand, tree.Len())
    93  	tree.Close()
    94  }
    95  
    96  // signature: Put(key string, val []byte) ([]byte, bool)
    97  func TestRbTree_Put(t *testing.T) {
    98  	tree := NewRBTree()
    99  	util.AssertLen(t, 0, tree.Len())
   100  	for i := 0; i < n*thousand; i++ {
   101  		_, existing := tree.Put(makeKey(i))
   102  		if existing { // existing=updated
   103  			t.Errorf("putting: %v", existing)
   104  		}
   105  	}
   106  	util.AssertLen(t, n*thousand, tree.Len())
   107  	tree.Close()
   108  }
   109  
   110  // signature: Get(key string) ([]byte, bool)
   111  func TestRbTree_Get(t *testing.T) {
   112  	tree := NewRBTree()
   113  	for i := 0; i < n*thousand; i++ {
   114  		tree.Put(makeKey(i))
   115  	}
   116  	util.AssertLen(t, n*thousand, tree.Len())
   117  	for i := 0; i < n*thousand; i++ {
   118  		val, ok := tree.Get(makeKey(i))
   119  		if !ok {
   120  			t.Errorf("getting: %v", ok)
   121  		}
   122  		util.AssertEqual(t, makeKey(i), val)
   123  	}
   124  	tree.Close()
   125  }
   126  
   127  // signature: Del(key string) ([]byte, bool)
   128  func TestRbTree_Del(t *testing.T) {
   129  	tree := NewRBTree()
   130  	for i := 0; i < n*thousand; i++ {
   131  		tree.Put(makeKey(i))
   132  	}
   133  	util.AssertLen(t, n*thousand, tree.Len())
   134  	for i := 0; i < n*thousand; i++ {
   135  		_, ok := tree.Del(makeKey(i))
   136  		if !ok {
   137  			t.Errorf("delete: %v", ok)
   138  		}
   139  	}
   140  	util.AssertLen(t, 0, tree.Len())
   141  	tree.Close()
   142  }
   143  
   144  // signature: Len() int
   145  func TestRbTree_Len(t *testing.T) {
   146  	tree := NewRBTree()
   147  	for i := 0; i < n*thousand; i++ {
   148  		tree.Put(makeKey(i))
   149  	}
   150  	util.AssertLen(t, n*thousand, tree.Len())
   151  	tree.Close()
   152  }
   153  
   154  // signature: Size() int64
   155  func TestRbTree_Size(t *testing.T) {
   156  	tree := NewRBTree()
   157  	var numBytes int64
   158  	for i := 0; i < n*thousand; i++ {
   159  		key := makeKey(i)
   160  		numBytes += int64(key.Size())
   161  		tree.Put(key)
   162  	}
   163  	util.AssertLen(t, numBytes, tree.Size())
   164  	log.Printf("size=%d\n", numBytes)
   165  	tree.Close()
   166  }
   167  
   168  // signature: Min() (string, []byte, bool)
   169  func TestRbTree_Min(t *testing.T) {
   170  	tree := NewRBTree()
   171  	for i := 0; i < n*thousand; i++ {
   172  		tree.Put(makeKey(i))
   173  	}
   174  	util.AssertLen(t, n*thousand, tree.Len())
   175  	k, ok := tree.Min()
   176  	if !ok {
   177  		t.Errorf("min: %v", tree)
   178  	}
   179  	util.AssertEqual(t, makeKey(0), k)
   180  	tree.Close()
   181  }
   182  
   183  // signature: Max() (string, []byte, bool)
   184  func TestRbTree_Max(t *testing.T) {
   185  	tree := NewRBTree()
   186  	for i := 0; i < n*thousand; i++ {
   187  		tree.Put(makeKey(i))
   188  	}
   189  	util.AssertLen(t, n*thousand, tree.Len())
   190  	k, ok := tree.Max()
   191  	if !ok {
   192  		t.Errorf("min: %v", tree)
   193  	}
   194  	util.AssertEqual(t, makeKey(n*thousand-1), k)
   195  	tree.Close()
   196  }
   197  
   198  // signature: ScanFront(iter Iterator)
   199  func TestRbTree_ScanFront(t *testing.T) {
   200  	tree := NewRBTree()
   201  	for i := 0; i < n*thousand; i++ {
   202  		tree.Put(makeKey(i))
   203  	}
   204  	util.AssertLen(t, n*thousand, tree.Len())
   205  
   206  	printInfo := true
   207  
   208  	// do scan front
   209  	tree.Scan(func(e *binary.Entry) bool {
   210  		if e.Key == nil {
   211  			t.Errorf("scan front, issue with key: %s", e)
   212  			return false
   213  		}
   214  		if printInfo {
   215  			log.Printf("entry: %s\n", e)
   216  		}
   217  		return true
   218  	})
   219  
   220  	tree.Close()
   221  }
   222  
   223  // signature: ScanRange(start Entry, end Entry, iter Iterator)
   224  func TestRbTree_ScanRange(t *testing.T) {
   225  	tree := NewRBTree()
   226  	for i := 0; i < n*thousand; i++ {
   227  		tree.Put(makeKey(i))
   228  	}
   229  	util.AssertLen(t, n*thousand, tree.Len())
   230  
   231  	printInfo := true
   232  
   233  	start, stop := makeKey(300), makeKey(700)
   234  	tree.ScanRange(start, stop, func(e *binary.Entry) bool {
   235  		if e.Key == nil && bytes.Compare(e.Key, start.Key) == -1 && bytes.Compare(e.Key, stop.Key) == 1 {
   236  			t.Errorf("scan range, issue with key: %s", e)
   237  			return false
   238  		}
   239  		if printInfo {
   240  			log.Printf("entry: %s\n", e)
   241  		}
   242  		return true
   243  	})
   244  
   245  	tree.Close()
   246  }
   247  
   248  // signature: Close()
   249  func TestRbTree_Close(t *testing.T) {
   250  	var tree *RBTree
   251  	tree = NewRBTree()
   252  	tree.Close()
   253  }