Skip to content

Commit

Permalink
feat(index): implement from page method
Browse files Browse the repository at this point in the history
  • Loading branch information
DrunkenWhale committed Dec 1, 2022
1 parent 29e997d commit 98d34d0
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 14 deletions.
11 changes: 7 additions & 4 deletions index/bplusnode.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package index

import "Duckweed/page"
import (
"Duckweed/buffer"
"Duckweed/page"
)

type BPlusNode interface {
ToBytes() []byte
Expand All @@ -10,12 +13,12 @@ type BPlusNode interface {
FetchNode(pageID int) BPlusNode
}

func FromPage(page *page.Page) BPlusNode {
func FromPage(page *page.Page, bf buffer.BufferPool) BPlusNode {
flag := page.GetBytes()[0]
if flag == IndexNodeFlag {
return IndexNodeFromPage(page)
return IndexNodeFromPage(page, bf)
} else if flag == LeafNodeFlag {
return LeafNodeFromPage(page)
return LeafNodeFromPage(page, bf)
} else {
panic("Illegal Page!")
}
Expand Down
9 changes: 5 additions & 4 deletions index/indexnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
// index node in disk
//
//
// 1 byte 8 byte 8 byte
// |head|IsLeafNode|maxKeysNumber|keyNumber|
// 1 byte 8 byte 8 byte
// |head|IsIndexNode|maxKeysNumber|keyNumber|
// |body|slot(int)|key|key|key...|=>
// *****
// <=|children(int)|children(int)|
Expand All @@ -31,7 +31,7 @@ type IndexNode struct {

func (node *IndexNode) FetchNode(pageID int) BPlusNode {
p := node.bf.GetPage(pageID)
n := FromPage(p)
n := FromPage(p, node.bf)
return n
}

Expand Down Expand Up @@ -81,7 +81,7 @@ func (node *IndexNode) sync() {

// IndexNodeFromPage
// TODO: Test
func IndexNodeFromPage(p *page.Page) *IndexNode {
func IndexNodeFromPage(p *page.Page, bf buffer.BufferPool) *IndexNode {
bytes := p.GetBytes()
maxKeysNumberBytes := [8]byte{}
copy(maxKeysNumberBytes[:], bytes[1:9])
Expand All @@ -106,6 +106,7 @@ func IndexNodeFromPage(p *page.Page) *IndexNode {
children[i] = int(num)
}
node := &IndexNode{
bf: bf,
maxKVNumber: int(maxKeysNumber),
page: p,
keys: keys,
Expand Down
90 changes: 84 additions & 6 deletions index/leafnode.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@ package index

import (
"Duckweed/buffer"
"Duckweed/databox"
"Duckweed/page"
)

// leaf node in disk
//
//
// 1 byte 8 byte 8 byte 8 byte 8 byte
// |head|IsLeafNode|rightSibling|maxKVNumber|kvNumber|ridLength|
// |body|slot(int)|key|key|key...|=>
// *****
// <=|rid([]byte])|rid([]byte])|rid([]byte])|
// ridLength byte ridLength byte

type LeafNode struct {
bf buffer.BufferPool
maxKVNumber int
ridLength int
page *page.Page
keys []int // 键后续可能会扩展(多种类型) 但我要想先做个int的试试
rids []string
rids [][]byte
rightSibling int
}

Expand All @@ -20,15 +32,81 @@ func (node *LeafNode) GetPage() *page.Page {

func (node *LeafNode) FetchNode(pageID int) BPlusNode {
p := node.bf.GetPage(pageID)
n := FromPage(p)
n := FromPage(p, node.bf)
return n
}

func (node *LeafNode) ToBytes() []byte {
//TODO implement me
panic("implement me")
header := make([]byte, 1)
header[0] = LeafNodeFlag
if len(node.keys) != len(node.rids) {
panic("Keys Number Should equal Rids Number (o゜▽゜)o☆")
}
rightSiblingBytes := databox.IntToBytes(int64(node.rightSibling))
maxKeysNumberBytes := databox.IntToBytes(int64(node.maxKVNumber))
keysNumberBytes := databox.IntToBytes(int64(len(node.keys)))
ridLengthBytes := databox.IntToBytes(int64(node.ridLength))
header = append(header, rightSiblingBytes[:]...)
header = append(header, maxKeysNumberBytes[:]...)
header = append(header, keysNumberBytes[:]...)
header = append(header, ridLengthBytes[:]...)
keysBytes := make([]byte, 8*len(node.keys))
for i := 0; i < len(node.keys); i++ {
b := databox.IntToBytes(int64(node.keys[i]))
copy(keysBytes[i*8:(i+1)*8], b[:])
}
ridsBytes := make([]byte, node.ridLength*len(node.rids))
for i := 0; i < len(node.rids); i++ {
b := node.rids[len(node.rids)-1-i]
copy(ridsBytes[i*node.ridLength:(i+1)*node.ridLength], b[:])
}
blankBytesSize := page.PageSize - (len(header) + len(keysBytes) + len(ridsBytes))
blankBytes := make([]byte, blankBytesSize)
bytes := append(header, keysBytes...)
bytes = append(bytes, blankBytes...)
bytes = append(bytes, ridsBytes...)
return bytes
}

func LeafNodeFromPage(page *page.Page) *LeafNode {
return nil
func LeafNodeFromPage(p *page.Page, bf buffer.BufferPool) *LeafNode {
bytes := p.GetBytes()
rightSiblingBytes := [8]byte{}
copy(rightSiblingBytes[:], bytes[1:9])
rightSibling := int(databox.BytesToInt(rightSiblingBytes))
maxKeysNumberBytes := [8]byte{}
copy(maxKeysNumberBytes[:], bytes[9:17])
maxKeysNumber := int(databox.BytesToInt(maxKeysNumberBytes))
kvNumberBytes := [8]byte{}
copy(kvNumberBytes[:], bytes[17:25])
kvNumber := int(databox.BytesToInt(kvNumberBytes))
ridLengthBytes := [8]byte{}
copy(ridLengthBytes[:], bytes[9:17])
ridLength := int(databox.BytesToInt(ridLengthBytes))

headerOffset := 4*8 + 1

keys := make([]int, kvNumber)
rids := make([][]byte, kvNumber)

for i := 0; i < kvNumber; i++ {
b := [8]byte{}
copy(b[:], bytes[headerOffset+i*8:headerOffset+(i+1)*8])
num := databox.BytesToInt(b)
keys[i] = int(num)
}
for i := 0; i < kvNumber; i++ {
b := make([]byte, ridLength)
copy(b[:], bytes[page.PageSize-(i+1)*ridLength:page.PageSize-i*ridLength])
rids[i] = b
}
node := &LeafNode{
bf: bf,
maxKVNumber: maxKeysNumber,
ridLength: ridLength,
page: p,
keys: keys,
rids: rids,
rightSibling: rightSibling,
}
return node
}

0 comments on commit 98d34d0

Please sign in to comment.