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

这篇具有很好参考价值的文章主要介绍了MIT6.5830 Lab1-GoDB实验记录(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

标签:Golang

读写缓冲区我是一点思路都没有,所以得单独开篇文章记录。

实验补充

了解buffer、序列化与反序列化

这里的序列化,简单来说类似于把一个很长的字符串拆成一个个字符;反序列化就是把这一个个字符拼回成完整的字符串。此处我们需要根据所给的Tuple,转换为二进制后再写入buffer中。

而buffer–缓冲区相信大家都不陌生了。我们来个go中的例子。先来个把结构转换为二进制后写入buffer的例子。

MIT6.5830 Lab1-GoDB实验记录(四),GO语言,golang,前端,数据库

再来看个从buffer中读取byte[],再将其转换为字符串的例子

MIT6.5830 Lab1-GoDB实验记录(四),GO语言,golang,前端,数据库

实验BUG

修正tuple.equal函数

如果你是按着我的代码敲的,在tuple.equal中有个bug,会导致你即使没动过writeTo和read函数,run test TestTupleSerialization也能通过。

主要是因为没比较两个元组的长度,只比较了Desc的长度。所以如果两个元组字段相同但记录不一样,会导致最后equal仍然return true。

修改一下equal即可。

func (t1 *Tuple) equals(t2 *Tuple) bool {
	// TODO: some code goes here
	if t1.Desc.equals(&t2.Desc) == false {
		return false
	}
	if len(t1.Fields) != len(t2.Fields) {
		return false
	}
	for i := range t1.Fields {
		if t1.Fields[i] != t2.Fields[i] {
			return false
		}
	}
	return true
}

实验步骤

补全writeTo函数

先来看看writeTo,把一个元组的字段写入缓冲区。Desc倒是不用写入,这点可以从read函数中反推出来。

还好GoDB只支持两种数据类型:int和string。所以只需要判断字段是int还是string。int比较好处理,没做要求所以我们直接写入即可。

func (t *Tuple) writeTo(b *bytes.Buffer) error {
	// TODO: some code goes here
	for _,field :=range t.Fields{
		switch f:=field.(type){
		case IntField:
			err:=binary.Write(b,binary.LittleEndian,f.Value)
			if err!=nil{
				return err
			}
		case StringField:
			
		}
	}
	return 

在注释中,还提到了缓冲区大小不够,无法写入元组的情况,这种情况需要返回一个err,所以我们还需要判断缓冲区和元组的大小,并new一个error。

但是这又有个问题:缓冲区大小是受你电脑或者操作系统分配的。buffer会根据你要传递的数据自动增长。用人话讲:缓冲区的大小会自动改变,那我们该怎么判断它大小不够无法再写入数据了呢?

说实话,没戏。获取自己电脑的系统内存?没戏,起码对于入门的Goer没戏;更何况真达到这个上限的时候内存早爆了。

所以我选择自定义一个2G的缓冲区大小,超出2G就报错。按一个字符串32字节来算,那也能存67108864个字符串,足够了。

func (t *Tuple) writeTo(b *bytes.Buffer) error {
	// TODO: some code goes here
	maxSize := 0
	for _, field := range t.Fields {
		switch f := field.(type) {
		case IntField:
			maxSize += int(unsafe.Sizeof(f.Value))
		case StringField:
			maxSize += 32
		}
	}
	if maxSize >= 2147483648 { //2 G=2,147,483,648 Bytes
		err := errors.New("Buffer has insufficient capacity!")
		return err
	} else {
		for _, field := range t.Fields {
			switch f := field.(type) {
			case IntField:
				err := binary.Write(b, binary.LittleEndian, f.Value)
				if err != nil {
					return err
				}
			case StringField:
				
			}
		}
		return nil
	}
}

接下来就是重头戏了:怎么处理string类型的字符串。

// Strings can be converted to byte arrays by casting to []byte. Note that all
// strings need to be padded to StringLength bytes (set in types.go). For
// example if StringLength is set to 5, the string 'mit' should be written as
// 'm', 'i', 't', 0, 0

可以看出,字符串先要转为字节数组,然后小于32字节的字符串要补0,一直补到32字节为止。那很简单,make一个len-x的切片,然后添加到字节数组后面即可。

func (t *Tuple) writeTo(b *bytes.Buffer) error {
	// TODO: some code goes here
	maxSize := 0
	for _, field := range t.Fields {
		switch f := field.(type) {
		case IntField:
			maxSize += int(unsafe.Sizeof(f.Value))
		case StringField:
			maxSize += 32
		}
	}
	if maxSize >= 2147483648 { //2 G=2,147,483,648 Bytes
		err := errors.New("Buffer has insufficient capacity!")
		return err
	} else {
		for _, field := range t.Fields {
			switch f := field.(type) {
			case IntField:
				err := binary.Write(b, binary.LittleEndian, f.Value)
				if err != nil {
					return err
				}
			case StringField:
				str := []byte(f.Value)
				if len(str) < StringLength {
					padding := make([]byte, StringLength-len(str))
					str = append(str, padding...)
				}
				err := binary.Write(b, binary.LittleEndian, str)
				if err != nil {
					return err
				}
			}
		}
		return nil //replace me
	}
}

run file test,全过,prefect。

MIT6.5830 Lab1-GoDB实验记录(四),GO语言,golang,前端,数据库文章来源地址https://www.toymoban.com/news/detail-737778.html

到了这里,关于MIT6.5830 Lab1-GoDB实验记录(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MIT6.S081 - Lab2: system calls

    step1:系统调用声明 user/user.h :系统调用函数(如 int fork(void) ) step2:ecall 进入内核态 user/usys.S (该文件由 user/usys.pl 生成,后续添加函数可以在这里添加):执行如下命令 将系统调用的编号(在 kernel/syscall.h 中定义)写入 a7 寄存器 从 ecall 进入中断处理函数 step3:保存数据并

    2024年04月23日
    浏览(34)
  • MIT 6s081 lab1:Xv6 and Unix utilities

    作业网址:https://pdos.csail.mit.edu/6.828/2020/labs/util.html 下载,启动xv6系统 使用system call sleep .函数(在user/user.h中被声明)来完成 使用系统调用在一对管道上的两个进程之间“乒乓”一个字节,每个方向一个。父进程应该向子进程发送一个字节;子进程应打印“<pid>:received

    2024年01月17日
    浏览(26)
  • 「实验记录」MIT 6.824 Raft Lab2C Persist

    MIT-6.824 2020 课程官网 Lab2: Raft 实验主页 simviso 精品付费翻译 MIT 6.824 课程 Paper - Raft extended version source code 的 Gitee 地址 Lab2C: Persist 的 Gitee 地址 课程官网提供的 Lab 代码下载地址,我没有访问成功,于是我从 Github 其他用户那里 clone 到干净的源码,有需要可以访问我的 Gitee 获取

    2024年02月08日
    浏览(64)
  • 「实验记录」MIT 6.824 Raft Lab2A Leader Election

    MIT-6.824 2020 课程官网 Lab2: Raft 实验主页 simviso 精品付费翻译 MIT 6.824 课程 source code 的 Gitee 地址 Lab2A: Leader Election 的 Gitee 地址 课程官网提供的 Lab 代码下载地址,我没有访问成功,于是我从 Github 其他用户那里 clone 到干净的源码,有需要可以访问我的 Gitee 获取 提出 Raft 的主要

    2024年02月05日
    浏览(29)
  • 「实验记录」MIT 6.824 KVRaft Lab3B With Log Compaction

    MIT-6.824 2020 课程官网 Lab3: KVRaft 实验主页 simviso 精品付费翻译 MIT 6.824 课程 Paper - Raft extended version source code 的 Gitee 地址 Lab3B: KVRaft with log compaction的 Gitee 地址 课程官网提供的 Lab 代码下载地址,我没有访问成功,于是我从 Github 其他用户那里 clone 到干净的源码,有需要可以访

    2024年02月15日
    浏览(35)
  • MIT6.024学习笔记(三)——图论(2)

    科学是使人变得勇敢的最好途径。——布鲁诺 在通信网络中,分为主机和路由器两部分,我们将主机分为输入端和输出端,则构成的图中有三部分:路由器、输入端、输出端,构成了一个有向图。那么,一个N*N规模的通信网络,应该怎么构成才能达到性能最佳呢(假设N总是

    2024年02月09日
    浏览(39)
  • CSAPP lab1 Data Lab

    前言: 本系列文章用于记录开始学习csapp的过程,奈何感觉自己基础实在太渣渣,系统好好学习一下这本神书以及其对应的lab 这一张的lab是真的干,好几道题卡的我脑壳都卡秃噜了,好歹终于凭借着面向用例编程完成了这一张的lab 很多很多测试用例哦,再也不用担心绞尽脑

    2024年02月10日
    浏览(29)
  • MIT6.S081学习笔记--lec 1

    abstract H/W 抽象化硬件 multiplex 多路复用 isolation 隔离性 sharing 共享(进程通信,数据共享) security / access control 安全性/权限控制 performance 性能/内核开销 range of applications 多应用场景 操作系统应该提供的功能:1. 多进程支持 2. 进程间隔离 3. 受控制的进程间通信 xv6 :一种在本

    2024年02月16日
    浏览(29)
  • Lab1 Packet Sniffing and Spoofing Lab

    @[TOC] Packet Sniffing and Spoofing Lab 实验网站连接link 1.先在虚拟机上导入 SEED VM并完成相应的配置。配置可以参考:link 2.使用准备好的docker-compose.yml去配置虚拟机环境 2.1先把docker-compose.yml放到虚拟机的某个文件夹下。 2.2 然后再文件所在的目录下输入命令运行 docker-compose up -d就能

    2024年02月07日
    浏览(41)
  • CS144--Lab1笔记

    CS144——Lab1笔记 作为使用了版本管理的项目,开始新的开发,当然先要新建一个开发分支啦,可以用命令或者直接在IDE中GIT的图形控制界面操作,太简单就不细说。(我习惯命名:dev-lab1) 首先要从原始仓库合并Lab1的相关文件到本地仓库,接着在build目录下编译。执行下面的

    2024年02月20日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包