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 }