bbolt: open

签名
func Open(path string, mode os.FileMode, options *Options) (*DB, error)

  1. 打开文件
  2. lock, 调用syscall的flock
  3. 初始化或者读取文件元信息

每个page的初始元信息

type page struct {
	id       pgid
	flags    uint16
	count    uint16
	overflow uint32
	ptr      uintptr
}

ptr字段其实只是个站位的,ptr这个字段开始其实就是meta结构体的起始地址,ptr之前的是header信息

const pageHeaderSize = int(unsafe.Offsetof(((*page)(nil)).ptr))

// meta returns a pointer to the metadata section of the page.
func (p *page) meta() *meta {
	return (*meta)(unsafe.Pointer(&p.ptr))
}

可以看出pageHeaderSize就是拿ptr的起始地址作为长度的。
meta page的内存布局就是page heade --> meta。 page header的ptr地址就是meta的起始地址,两个数据结构通过ptr巧妙的连接在一起了。

meta:

type meta struct {
	magic    uint32
	version  uint32
	pageSize uint32
	flags    uint32
	root     bucket
	freelist pgid
	pgid     pgid
	txid     txid
	checksum uint64
}

init:
初始化四个page
0,1作为meta page, 为什么需要两个???
3,freelistpage
4,leafPage

读取:
读取文件千4k,检查meta是否合法:

// validate checks the marker bytes and version of the meta page to ensure it matches this binary.
func (m *meta) validate() error {
	if m.magic != magic {
		return ErrInvalid
	} else if m.version != version {
		return ErrVersionMismatch
	} else if m.checksum != 0 && m.checksum != m.sum64() {
		return ErrChecksum
	}
	return nil
}

为什么是4k呢?因为page header和meta肯定不会超过4k

内存池:

	// Initialize page pool.
	db.pagePool = sync.Pool{
		New: func() interface{} {
			return make([]byte, db.pageSize)
		},
	}

loadFreelist:
这个freelist的作用是什么还要看写入过程发生了什么。我们可以从数据插入的过程来看,先假设走的是init流程,没有freelist,了解完freelist的用处以后再回过头来看这个

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值