Skip to content

Commit

Permalink
refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
chirst committed Jun 23, 2024
1 parent 88915d3 commit 8f6c23e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
go-version: '1.22'

- name: Build
run: go build -v ./...
run: make build

- name: Test
run: make test
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ run:
go run .

test:
go test ./...
go test -v ./...

build:
go build -v ./...
30 changes: 16 additions & 14 deletions kv.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ func (kv *kv) Get(pageNumber uint16, key []byte) ([]byte, bool, error) {
// with the root page of the corresponding table. The system catalog uses the
// page number 1.
func (kv *kv) Set(pageNumber uint16, key, value []byte) error {
// TODO set has some issues. One being set doesn't differentiate between
// insert and update which isn't very intentional. Two being set cannot
// perform multiple insertions in the span of one transaction since page
// splits pull out stale pages on subsequent inserts which causes difficult
// bugs.
if pageNumber == EMPTY_PARENT_PAGE_NUMBER {
return errorReservedPage
}
Expand Down Expand Up @@ -97,24 +102,21 @@ func (kv *kv) Set(pageNumber uint16, key, value []byte) error {
return nil
}

// TODO this is really messy and is a symptom of internal pages using two keys
// to represent two ranges where only one key is necessary.
func insertIntoOne(key, value []byte, p1, p2 *page) {
p1k := p1.getEntries()[0].key
p2k := p2.getEntries()[0].key
if bytes.Equal(p1k, key) {
p1.setEntries(append(p1.getEntries(), pageTuple{key, value}))
// a helper function to insert into a left or right page given the left and
// right pages have space and the right page is greater than the left.
func insertIntoOne(key, value []byte, lp, rp *page) {
rpk := rp.getEntries()[0].key
comp := bytes.Compare(key, rpk)
if comp == 0 { // key == rpk
rp.setEntries(append(rp.getEntries(), pageTuple{key, value}))
return
}
if bytes.Equal(p2k, key) {
p2.setEntries(append(p2.getEntries(), pageTuple{key, value}))
if comp == -1 { // key < rpk
lp.setEntries(append(lp.getEntries(), pageTuple{key, value}))
return
}
if bytes.Compare(p1k, key) == -1 && bytes.Compare(key, p2k) == -1 {
p1.setEntries(append(p1.getEntries(), pageTuple{key, value}))
return
}
p2.setEntries(append(p2.getEntries(), pageTuple{key, value}))
// key > rpk
rp.setEntries(append(rp.getEntries(), pageTuple{key, value}))
}

func (kv *kv) getLeafPage(nextPageNumber uint16, key []byte) *page {
Expand Down
40 changes: 26 additions & 14 deletions kv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,37 @@ func TestKv(t *testing.T) {

t.Run("set page split", func(t *testing.T) {
kv, _ := NewKv(true)
for i := 0; i < 256; i += 1 {
kv.Set(1, []byte{byte(i)}, []byte{1, 2, 3, 4, 5})
}
for i := 0; i < 138; i += 1 {
kv.Set(1, []byte{byte(i), 0}, []byte{1, 2, 3, 4, 5})
}
// this value causes a split
k := []byte{byte(140), 0}
v := []byte{1, 1, 1, 1, 1}
kv.Set(1, k, v)
res, found, err := kv.Get(1, k)
var rk []byte
var rv []byte
ri := 178
// For a page 4096 a split is more than guaranteed here because
// 512*8=4096 not including the header of each page.
for i := 1; i < 512; i += 1 {
kv.BeginWriteTransaction()
k := EncodeKey(uint16(i))
v := []byte{1, 0, 0, 0}
if len(k) != 4 {
t.Fatal("need k to be len 4")
}
if len(v) != 4 {
t.Fatal("need v to be len 4")
}
kv.Set(1, k, v)
if ri == i {
rk = k
rv = v
}
kv.EndWriteTransaction()
}
res, found, err := kv.Get(1, rk)
if err != nil {
t.Fatal(err)
}
if !found {
t.Errorf("expected value for %v to be found", k)
t.Fatalf("expected value for %v to be found", rk)
}
if !bytes.Equal(res, v) {
t.Errorf("expected value %v got %v", v, res)
if !bytes.Equal(rv, res) {
t.Errorf("expected value %v got %v", rv, res)
}
})
}

0 comments on commit 8f6c23e

Please sign in to comment.