MIT6.5830 Lab1-GoDB实验记录(六)

MIT6.5830 Lab1-GoDB实验记录(六) – WhiteNight's Site

标签:Golang

赛博坐牢之旅第一章第六节:接着上一节,补全heap_page剩下的函数。

开始坐牢

删除tuple

这个看起来…难度还没那么高,写一下试试吧。那就遍历tuple然后找rid呗。

func (h *heapPage) deleteTuple(rid recordID) error {
	// TODO: some code goes here
	for i, tuple := range h.Tuple {
		if tuple.Rid == rid {
			h.Tuple[i] = nil
			h.Hdr.UsedSlots -= 1
			return nil
		}
	}
	return errors.New("the slot is invalid") //replace me

}

跑一下TestDeleteHeapPage,过。

MIT6.5830 Lab1-GoDB实验记录(六)_第1张图片

确实有了思路之后写起来得心应手,接着往下看看。

别忘了还有个TestHeapPageDeleteTuple,跑一下。嗯?居然报错了。又是访问越界啊啊啊啊啊啊。

MIT6.5830 Lab1-GoDB实验记录(六)_第2张图片

看看报错地方在哪里。仔细一看,tuple没判空……………………………tuple等于nil的话拿不到rid自然就会访问越界……………….补全一下

func (h *heapPage) deleteTuple(rid recordID) error {
	// TODO: some code goes here
	for i, tuple := range h.Tuple {
		if tuple != nil && tuple.Rid == rid {
			h.Tuple[i] = nil
			h.Hdr.UsedSlots -= 1
			return nil
		}
	}
	return errors.New("the slot is invalid") //replace me

}

再test一下,过。

MIT6.5830 Lab1-GoDB实验记录(六)_第3张图片

实验步骤

dirty

判断page是否为“脏页”和将page设置为“脏页”,那还得在page的结构里加个dirty。

type heapPage struct {
	// TODO: some code goes here
	Hdr   Header
	Tuple []*Tuple
	Desc  *TupleDesc

	File   *HeapFile
	PageNo int
	Dirty  bool
}

这两个函数也没啥说的,挺简单的。

// Page method - return whether or not the page is dirty
func (h *heapPage) isDirty() bool {
	// TODO: some code goes here
	return h.Dirty //replace me
}

// Page method - mark the page as dirty
func (h *heapPage) setDirty(dirty bool) {
	// TODO: some code goes here
	h.Dirty = dirty
}

这个居然也有test,那就跑一下吧,过。

MIT6.5830 Lab1-GoDB实验记录(六)_第4张图片

瞄了一眼下一个test,呵呵,又是序列化,看来赛博坐牢之旅还得继续。

实验步骤

返回对应的page

这个真的难吗?如难。

好吧仔细一看它真的有点难。因为注释就一句话:返回当前heap page所在的heapFile。

// Page method - return the corresponding HeapFile
// for this page.
func (p *heapPage) getFile() *DBFile {
	// TODO: some code goes here

	return nil //replace me
}

没其它提示了,那我们只能先看看DBFile的定义。

MIT6.5830 Lab1-GoDB实验记录(六)_第5张图片

嗯…给的是一个接口,那么DBFile应该是包含heapfile的。那直接把heap page的file返回给接口不就好了…

func (p *heapPage) getFile() *DBFile {
	// TODO: some code goes here
	var dbFile DBFile = p.File
	return &dbFile //replace me
}

没法test,因为GetPage还没写完,那就先….过!

实验步骤

又是序列化

序列化我是真的不熟。只能硬着头皮写了。先来看看要做些什么。

// Allocate a new bytes.Buffer and write the heap page to it. Returns an error
// if the write to the the buffer fails. You will likely want to call this from
// your [HeapFile.flushPage] method.  You should write the page header, using
// the binary.Write method in LittleEndian order, followed by the tuples of the
// page, written using the Tuple.writeTo method.
func (h *heapPage) toBuffer() (*bytes.Buffer, error) {
	// TODO: some code goes here
	
	return nil, nil //replace me

}

// Read the contents of the HeapPage from the supplied buffer.
func (h *heapPage) initFromBuffer(buf *bytes.Buffer) error {
	// TODO: some code goes here
	return nil //replace me
}

序列化和反序列化在之前的tuple我们已经接触过了,那这里我们就直接开写呗。

老样子,先是写入缓冲区。感觉比tuple简单些,毕竟不用考虑不同的字段fields类型了。

func (h *heapPage) toBuffer() (*bytes.Buffer, error) {
	// TODO: some code goes here
	bytesBuffer := new(bytes.Buffer)
	err := binary.Write(bytesBuffer, binary.LittleEndian, h.Hdr)
	if err != nil {
		return nil, err
	}
	for _, tuple := range h.Tuple {
		if tuple != nil {
			err := tuple.writeTo(bytesBuffer)
			if err != nil {
				return nil, err
			}
		}
	}

	return bytesBuffer, nil //replace me
}

接下来是读取缓冲区。读取的时候要注意范围,比如page可用102个插槽,表示的是从0-101下标的插槽都是可用的,所以TotalSlots要减一。

func (h *heapPage) initFromBuffer(buf *bytes.Buffer) error {
	// TODO: some code goes here
	err := binary.Read(buf, binary.LittleEndian, &h.Hdr)
	if err != nil {
		return err
	}
	for i := 0; i < int(h.Hdr.TotalSlots)-1; i++ {
		tuple, err := readTupleFrom(buf, h.Desc)
		if err != nil {
			return err
		}
		h.Tuple[i] = tuple
	}
	return nil //replace me
}

run一下test,过。至此我们就完成了Exercise 3的全部内容,接下来就是完成Exercise 4咯。

MIT6.5830 Lab1-GoDB实验记录(六)_第6张图片

你可能感兴趣的:(GO语言,golang,数据库)