如果count
超过了0xFFFF
,会采用ptr
部分的第一个元素来存储count
,读取的时候也是会预先判断。
请问在这种情况下,读取[idx:count]
部分的pgid,难道不会少读一个吗?
例如在写入时,ptr[0]
存储count=4,ptr[1]=0001,ptr[2]=0002,ptr[3]=0003,ptr[4]=0004
,
读取的时候,就会读取ptr[1:4],得到的不就是ptr[1]、ptr[2]、ptr[3]
了吗。
// If the page.count is at the max uint16 value (64k) then it's considered
// an overflow and the size of the freelist is stored as the first element.
idx, count := 0, int(p.count)
if count == 0xFFFF {
idx = 1
// 用第一个uint64来存储整个count的值
count = int(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[0])
}
// Copy the list of page ids from the freelist.
if count == 0 {
f.ids = nil
} else {
ids := ((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[idx:count]
f.ids = make([]pgid, len(ids))
copy(f.ids, ids)
// Make sure they're sorted.
sort.Sort(pgids(f.ids))
}
// Rebuild the page cache.
f.reindex()
}
func (f *freelist) write(p *page) error {
// Combine the old free pgids and pgids waiting on an open transaction.
// Update the header flag.
p.flags |= freelistPageFlag
// The page.count can only hold up to 64k elements so if we overflow that
// number then we handle it by putting the size in the first element.
lenids := f.count()
if lenids == 0 {
p.count = uint16(lenids)
} else if lenids < 0xFFFF {
p.count = uint16(lenids)
// 拷贝到page的ptr中
f.copyall(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[:])
} else {
// 有溢出的情况下,后面第一个元素放置其长度,然后再存放所有的pgid列表
p.count = 0xFFFF
// paid是uint64,长度足够
((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[0] = pgid(lenids)
// 从第一个元素位置拷贝
f.copyall(((*[maxAllocSize]pgid)(unsafe.Pointer(&p.ptr)))[1:])
}
return nil
}