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

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