github.com/zuoyebang/bitalosdb@v1.1.1-0.20240516111551-79a8c4d8ce20/bitree/bdb/node_test.go (about)

     1  // Copyright 2021 The Bitalosdb author(hustxrb@163.com) and other contributors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package bdb
    16  
    17  import (
    18  	"testing"
    19  	"unsafe"
    20  )
    21  
    22  func TestNode_put(t *testing.T) {
    23  	n := &node{inodes: make(inodes, 0), bucket: &Bucket{tx: &Tx{meta: &meta{pgid: 1}}}}
    24  	n.put([]byte("baz"), []byte("baz"), []byte("2"), 0, 0)
    25  	n.put([]byte("foo"), []byte("foo"), []byte("0"), 0, 0)
    26  	n.put([]byte("bar"), []byte("bar"), []byte("1"), 0, 0)
    27  	n.put([]byte("foo"), []byte("foo"), []byte("3"), 0, leafPageFlag)
    28  
    29  	if len(n.inodes) != 3 {
    30  		t.Fatalf("exp=3; got=%d", len(n.inodes))
    31  	}
    32  	if k, v := n.inodes[0].key, n.inodes[0].value; string(k) != "bar" || string(v) != "1" {
    33  		t.Fatalf("exp=<bar,1>; got=<%s,%s>", k, v)
    34  	}
    35  	if k, v := n.inodes[1].key, n.inodes[1].value; string(k) != "baz" || string(v) != "2" {
    36  		t.Fatalf("exp=<baz,2>; got=<%s,%s>", k, v)
    37  	}
    38  	if k, v := n.inodes[2].key, n.inodes[2].value; string(k) != "foo" || string(v) != "3" {
    39  		t.Fatalf("exp=<foo,3>; got=<%s,%s>", k, v)
    40  	}
    41  	if n.inodes[2].flags != uint32(leafPageFlag) {
    42  		t.Fatalf("not a leaf: %d", n.inodes[2].flags)
    43  	}
    44  }
    45  
    46  func TestNode_read_LeafPage(t *testing.T) {
    47  	var buf [4096]byte
    48  	page := (*page)(unsafe.Pointer(&buf[0]))
    49  	page.flags = leafPageFlag
    50  	page.count = 2
    51  
    52  	nodes := (*[3]leafPageElement)(unsafe.Pointer(uintptr(unsafe.Pointer(page)) + unsafe.Sizeof(*page)))
    53  	nodes[0] = leafPageElement{flags: 0, pos: 32, ksize: 3, vsize: 4}
    54  	nodes[1] = leafPageElement{flags: 0, pos: 23, ksize: 10, vsize: 3}
    55  
    56  	const s = "barfoozhelloworldbye"
    57  	data := unsafeByteSlice(unsafe.Pointer(&nodes[2]), 0, 0, len(s))
    58  	copy(data, s)
    59  
    60  	n := &node{}
    61  	n.read(page)
    62  
    63  	if !n.isLeaf {
    64  		t.Fatal("expected leaf")
    65  	}
    66  	if len(n.inodes) != 2 {
    67  		t.Fatalf("exp=2; got=%d", len(n.inodes))
    68  	}
    69  	if k, v := n.inodes[0].key, n.inodes[0].value; string(k) != "bar" || string(v) != "fooz" {
    70  		t.Fatalf("exp=<bar,fooz>; got=<%s,%s>", k, v)
    71  	}
    72  	if k, v := n.inodes[1].key, n.inodes[1].value; string(k) != "helloworld" || string(v) != "bye" {
    73  		t.Fatalf("exp=<helloworld,bye>; got=<%s,%s>", k, v)
    74  	}
    75  }
    76  
    77  func TestNode_write_LeafPage(t *testing.T) {
    78  	n := &node{isLeaf: true, inodes: make(inodes, 0), bucket: &Bucket{tx: &Tx{db: &DB{}, meta: &meta{pgid: 1}}}}
    79  	n.put([]byte("susy"), []byte("susy"), []byte("que"), 0, 0)
    80  	n.put([]byte("ricki"), []byte("ricki"), []byte("lake"), 0, 0)
    81  	n.put([]byte("john"), []byte("john"), []byte("johnson"), 0, 0)
    82  
    83  	var buf [4096]byte
    84  	p := (*page)(unsafe.Pointer(&buf[0]))
    85  	n.write(p)
    86  
    87  	n2 := &node{}
    88  	n2.read(p)
    89  
    90  	if len(n2.inodes) != 3 {
    91  		t.Fatalf("exp=3; got=%d", len(n2.inodes))
    92  	}
    93  	if k, v := n2.inodes[0].key, n2.inodes[0].value; string(k) != "john" || string(v) != "johnson" {
    94  		t.Fatalf("exp=<john,johnson>; got=<%s,%s>", k, v)
    95  	}
    96  	if k, v := n2.inodes[1].key, n2.inodes[1].value; string(k) != "ricki" || string(v) != "lake" {
    97  		t.Fatalf("exp=<ricki,lake>; got=<%s,%s>", k, v)
    98  	}
    99  	if k, v := n2.inodes[2].key, n2.inodes[2].value; string(k) != "susy" || string(v) != "que" {
   100  		t.Fatalf("exp=<susy,que>; got=<%s,%s>", k, v)
   101  	}
   102  }
   103  
   104  func TestNode_split(t *testing.T) {
   105  	n := &node{inodes: make(inodes, 0), bucket: &Bucket{tx: &Tx{db: &DB{}, meta: &meta{pgid: 1}}}}
   106  	n.put([]byte("00000001"), []byte("00000001"), []byte("0123456701234567"), 0, 0)
   107  	n.put([]byte("00000002"), []byte("00000002"), []byte("0123456701234567"), 0, 0)
   108  	n.put([]byte("00000003"), []byte("00000003"), []byte("0123456701234567"), 0, 0)
   109  	n.put([]byte("00000004"), []byte("00000004"), []byte("0123456701234567"), 0, 0)
   110  	n.put([]byte("00000005"), []byte("00000005"), []byte("0123456701234567"), 0, 0)
   111  
   112  	n.split(100)
   113  
   114  	var parent = n.parent
   115  	if len(parent.children) != 2 {
   116  		t.Fatalf("exp=2; got=%d", len(parent.children))
   117  	}
   118  	if len(parent.children[0].inodes) != 2 {
   119  		t.Fatalf("exp=2; got=%d", len(parent.children[0].inodes))
   120  	}
   121  	if len(parent.children[1].inodes) != 3 {
   122  		t.Fatalf("exp=3; got=%d", len(parent.children[1].inodes))
   123  	}
   124  }
   125  
   126  func TestNode_split_MinKeys(t *testing.T) {
   127  	n := &node{inodes: make(inodes, 0), bucket: &Bucket{tx: &Tx{db: &DB{}, meta: &meta{pgid: 1}}}}
   128  	n.put([]byte("00000001"), []byte("00000001"), []byte("0123456701234567"), 0, 0)
   129  	n.put([]byte("00000002"), []byte("00000002"), []byte("0123456701234567"), 0, 0)
   130  
   131  	n.split(20)
   132  	if n.parent != nil {
   133  		t.Fatalf("expected nil parent")
   134  	}
   135  }
   136  
   137  func TestNode_split_SinglePage(t *testing.T) {
   138  	n := &node{inodes: make(inodes, 0), bucket: &Bucket{tx: &Tx{db: &DB{}, meta: &meta{pgid: 1}}}}
   139  	n.put([]byte("00000001"), []byte("00000001"), []byte("0123456701234567"), 0, 0)
   140  	n.put([]byte("00000002"), []byte("00000002"), []byte("0123456701234567"), 0, 0)
   141  	n.put([]byte("00000003"), []byte("00000003"), []byte("0123456701234567"), 0, 0)
   142  	n.put([]byte("00000004"), []byte("00000004"), []byte("0123456701234567"), 0, 0)
   143  	n.put([]byte("00000005"), []byte("00000005"), []byte("0123456701234567"), 0, 0)
   144  
   145  	n.split(4096)
   146  	if n.parent != nil {
   147  		t.Fatalf("expected nil parent")
   148  	}
   149  }