| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- package core
- import (
- "TsDB2/DB/core/page"
- "unsafe"
- )
- type HeapInfo struct {
- Hdr page.PageHdr
- Data [PageSize - page.PageHdrSize]byte
- }
- type HeapPage struct {
- Info HeapInfo
- handle page.HandleDb // 回调函数
- }
- // =============================================================================
- // HeapPage 核心自治方法(所有操作全封装在这里,无管理器)
- // =============================================================================
- // NewHeapPage 创建一个全新的堆页(开辟函数)
- func NewHeapPage(handle page.HandleDb, pageType page.PageType) *HeapPage {
- hp := &HeapPage{handle: handle}
- hp.Info.Hdr.Type = pageType // 固定=堆页
- hp.Info.Hdr.PageID = handle.NewPage() // 自动分配新页ID
- hp.Info.Hdr.UseSize = page.PageHdrSize // 初始已用 = 页头大小
- return hp
- }
- // LoadHeapPage 从磁盘加载已存在的堆页
- func LoadHeapPage(handle page.HandleDb, pageID uint32) (*HeapPage, error) {
- buf := make([]byte, PageSize)
- if err := handle.ReadPage(pageID, buf); err != nil {
- return nil, err
- }
- return &HeapPage{
- Info: HeapInfo{
- Hdr: *(*page.PageHdr)(unsafe.Pointer(&buf[0])),
- Data: ([PageSize - page.PageHdrSize]byte)(buf[page.PageHdrSize:]),
- },
- handle: handle,
- }, nil
- }
- // -----------------------
- // 修复完成!Alloc 返回 【数据区内部偏移】(去掉页头)
- // -----------------------
- //func (hp *HeapPage) Alloc(need uint32) (allocPageID uint32, allocOff uint32, err error) {
- // if need > PageSize-page.PageHdrSize {
- // return 0, 0, ErrHeapPageTooLarge
- // }
- //
- // // 1. 计算剩余空间(只算数据区)
- // usedData := hp.Info.Hdr.UseSize - page.PageHdrSize // 已用数据区大小
- // freeData := (PageSize - page.PageHdrSize) - usedData // 剩余数据区大小
- //
- // // 空间足够 → 分配【数据区偏移】
- // if freeData >= need {
- // // 🔥 核心修复:返回的是 Data 数组的偏移(去掉页头)
- // off := usedData
- // hp.Info.Hdr.UseSize += need
- // _ = hp.Save()
- // return hp.Info.Hdr.PageID, off, nil
- // }
- //
- // // 2. 空间不足 → 创建新页
- // newHp := NewHeapPage(hp.handle, hp.Info.Hdr.Type)
- //
- // // 维护页链
- // hp.Info.Hdr.NextPage = newHp.Info.Hdr.PageID
- // newHp.Info.Hdr.PrePage = hp.Info.Hdr.PageID
- // _ = hp.Save()
- //
- // // 3. 新页分配:返回【数据区偏移 0】
- // newOff := uint32(0)
- // newHp.Info.Hdr.UseSize += need
- // _ = newHp.Save()
- //
- // return newHp.Info.Hdr.PageID, newOff, nil
- //}
- func (hp *HeapPage) Alloc(need uint32) (allocPageID uint32, allocOff uint32, err error) {
- // 安全检查:申请空间不能超过单页最大容量
- if need > PageSize-page.PageHdrSize {
- return 0, 0, ErrHeapPageTooLarge
- }
- // 1. 当前页剩余空间足够 → 直接分配【页内物理偏移】
- free := PageSize - hp.Info.Hdr.UseSize
- if free >= need {
- // ✅ 直接返回当前页的物理偏移(包含页头,真实地址)
- off := hp.Info.Hdr.UseSize
- hp.Info.Hdr.UseSize += need
- _ = hp.Save()
- return hp.Info.Hdr.PageID, off, nil
- }
- // 2. 空间不足 → 创建新堆页
- newHp := NewHeapPage(hp.handle, hp.Info.Hdr.Type)
- // 维护页双向链
- hp.Info.Hdr.NextPage = newHp.Info.Hdr.PageID
- newHp.Info.Hdr.PrePage = hp.Info.Hdr.PageID
- _ = hp.Save()
- // 3. 新页分配:返回新页的物理偏移(PageHdrSize,真实起始地址)
- newOff := newHp.Info.Hdr.UseSize // = page.PageHdrSize
- newHp.Info.Hdr.UseSize += need
- _ = newHp.Save()
- return newHp.Info.Hdr.PageID, newOff, nil
- }
- // Save 自动保存当前堆页到磁盘
- func (hp *HeapPage) Save() error {
- buf := make([]byte, PageSize)
- // 写入页头
- *(*page.PageHdr)(unsafe.Pointer(&buf[0])) = hp.Info.Hdr
- // 写入数据区
- copy(buf[page.PageHdrSize:], hp.Info.Data[:])
- return hp.handle.SavePage(hp.Info.Hdr.PageID, buf)
- }
- // Get 返回 HeapInfo 的零拷贝字节切片(直接指向内部内存)
- func (hp *HeapPage) Get() []byte {
- size := unsafe.Sizeof(hp.Info)
- ptr := (*byte)(unsafe.Pointer(&hp.Info))
- return unsafe.Slice(ptr, size)
- }
|