TablePage.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. package core
  2. import (
  3. "TsDB2/DB/core/index/btree"
  4. "TsDB2/DB/core/page"
  5. "TsDB2/DB/core/types"
  6. "TsDB2/DB/core/util"
  7. "unsafe"
  8. )
  9. type TablePage struct {
  10. hdr page.PageHdr
  11. tables []*Table
  12. handle page.HandleDb
  13. hdrSize uint32 // hdr 的大小
  14. tableInfoSize uint32 // 表头大小
  15. lastPageID uint32 // 最后一页
  16. }
  17. // NewTablePage 创建表页管理器
  18. func NewTablePage(handle page.HandleDb) *TablePage {
  19. return &TablePage{
  20. handle: handle,
  21. hdrSize: uint32(unsafe.Sizeof(page.PageHdr{})),
  22. tableInfoSize: uint32(unsafe.Sizeof(TableInfo{})),
  23. }
  24. }
  25. // Tables 获取所有表
  26. func (t *TablePage) Tables() []*Table {
  27. return t.tables
  28. }
  29. // LastPageID 获取最后页ID
  30. func (t *TablePage) LastPageID() uint32 {
  31. return t.lastPageID
  32. }
  33. // Init 初始化表页:从磁盘读取所有表 + 所有字段(支持跨页存储)
  34. func (t *TablePage) Init(pageID uint32) {
  35. t.tables = make([]*Table, 0)
  36. t.hdrSize = uint32(unsafe.Sizeof(page.PageHdr{}))
  37. t.tableInfoSize = uint32(unsafe.Sizeof(TableInfo{}))
  38. t.hdr.PageID = pageID
  39. t.hdr.Type = page.TableIndex
  40. t.hdr.NextPage = 0
  41. t.lastPageID = 0
  42. if pageID == 0 {
  43. return
  44. }
  45. for pageID != 0 {
  46. t.lastPageID = pageID
  47. pageBuf := make([]byte, PageSize)
  48. if err := t.handle.ReadPage(pageID, pageBuf); err != nil {
  49. break
  50. }
  51. pageHdr := (*page.PageHdr)(unsafe.Pointer(&pageBuf[0]))
  52. offset := t.hdrSize
  53. for offset+t.tableInfoSize <= pageHdr.UseSize {
  54. info := (*TableInfo)(unsafe.Pointer(&pageBuf[offset]))
  55. if util.IsHighBitSet(info.Flag) {
  56. offset += t.tableInfoSize + uint32(info.FieldAllocateSize)
  57. continue
  58. }
  59. activeVer, masterFields, versions, fieldOffset := readSchema(
  60. t.handle, pageID, uint16(offset+t.tableInfoSize), info.FieldAllocateSize)
  61. indexMate := &IndexMetaPage{
  62. handle: t.handle,
  63. }
  64. indexMate.Init(info.FirstIndexID)
  65. t.tables = append(t.tables, &Table{
  66. info: info,
  67. Field: masterFields,
  68. handle: t.handle,
  69. indexMeta: indexMate,
  70. tablePageID: pageID,
  71. tableStartOffset: offset,
  72. curOffset: fieldOffset,
  73. activeVersion: activeVer,
  74. versions: versions,
  75. })
  76. offset += t.tableInfoSize + uint32(info.FieldAllocateSize)
  77. }
  78. pageID = pageHdr.NextPage
  79. }
  80. }
  81. // ===========================================================================
  82. // ✅ Create 完整正确(字段数量全是 byte,255上限)
  83. // ===========================================================================
  84. func (t *TablePage) Create(name string, fields []types.FieldInfo) (*Table, error) {
  85. fieldCount := byte(len(fields))
  86. if len(name) > TableNameSize {
  87. return nil, ErrTableNameTooLong
  88. }
  89. for _, tb := range t.tables {
  90. if util.BytesToString(tb.info.Name[:]) == name && !util.IsHighBitSet(tb.info.Flag) {
  91. return nil, ErrTableExists
  92. }
  93. }
  94. if fieldCount == 0 || int(fieldCount)+1 >= MaxFieldSize {
  95. return nil, ErrInvalidFieldCount
  96. }
  97. realFieldSize := uint32(1) // 字段数量:1字节(byte)
  98. for _, f := range fields {
  99. realFieldSize += 2 + uint32(len(f.FieldName))
  100. }
  101. allocateSize := realFieldSize * 2
  102. if allocateSize < MinFieldAllocateSize {
  103. allocateSize = MinFieldAllocateSize
  104. }
  105. if allocateSize > PageSize {
  106. return nil, ErrFieldAllocateTooLarge
  107. }
  108. var pageBuf []byte
  109. var pageHdr *page.PageHdr
  110. if t.hdr.PageID == 0 {
  111. pid := t.handle.NewPage()
  112. pageBuf, pageHdr = t.InitHeader(pid)
  113. t.hdr.PageID = pid
  114. t.lastPageID = pid
  115. } else {
  116. pageBuf = make([]byte, PageSize)
  117. t.handle.ReadPage(t.lastPageID, pageBuf)
  118. pageHdr = (*page.PageHdr)(unsafe.Pointer(&pageBuf[0]))
  119. }
  120. // 当前已经使用了的
  121. offset := pageHdr.UseSize
  122. // 这个表总共需要多少空间
  123. required := t.tableInfoSize + uint32(allocateSize)
  124. // 表空间不足就创建新的页存表
  125. if offset+required > PageSize {
  126. newPID := t.handle.NewPage()
  127. newBuf, newHdr := t.InitHeader(newPID)
  128. pageHdr.NextPage = newPID
  129. t.handle.SavePage(t.lastPageID, pageBuf) // 保存旧页的 NextPage 更新
  130. t.lastPageID = newPID
  131. pageBuf = newBuf
  132. pageHdr = newHdr
  133. offset = t.hdrSize
  134. }
  135. info := (*TableInfo)(unsafe.Pointer(&pageBuf[offset]))
  136. copy(info.Name[:], name)
  137. info.Flag = 0
  138. info.FieldCount = fieldCount
  139. info.ActiveFieldCount = fieldCount // 初始时实际字段数等于总字段数
  140. info.RowSize = types.CalcRowSize(fields)
  141. info.FieldAllocateSize = uint16(allocateSize)
  142. info.TotalRows = 0
  143. // 创建数据页
  144. dataPID := t.handle.NewPage()
  145. info.FirstData = dataPID
  146. info.LastData = dataPID
  147. dataBuf := make([]byte, PageSize)
  148. dHdr := (*page.PageHdr)(unsafe.Pointer(&dataBuf[0]))
  149. dHdr.Type = page.DataIndex
  150. dHdr.PageID = dataPID
  151. dHdr.UseSize = t.hdrSize
  152. t.handle.SavePage(dataPID, dataBuf)
  153. // 创建堆页
  154. heapPID := t.handle.NewPage()
  155. info.FirstHeap = heapPID
  156. info.LastHeap = heapPID
  157. heapBuf := make([]byte, PageSize)
  158. hHdr := (*page.PageHdr)(unsafe.Pointer(&heapBuf[0]))
  159. hHdr.Type = page.HeapIndex
  160. hHdr.PageID = heapPID
  161. hHdr.UseSize = t.hdrSize
  162. t.handle.SavePage(heapPID, heapBuf)
  163. indexMate := &IndexMetaPage{
  164. handle: t.handle,
  165. }
  166. // 创建索引元数据
  167. indexPID := t.handle.NewPage()
  168. indexMate.Init(indexPID)
  169. indexMate.InitHeader(indexPID)
  170. info.FirstIndexID = indexPID
  171. info.LastIndexID = indexPID
  172. // ==========================
  173. // 写新版 schema 字段定义链
  174. // 格式: [activeVer(1B)] [masterCount(1B)] [type+len+name]×N [verCount(1B)] [ver1...]
  175. // ==========================
  176. fieldOff := offset + t.tableInfoSize
  177. wo := fieldOff
  178. // activeVer = 1
  179. pageBuf[wo] = 1
  180. wo++
  181. // masterCount
  182. pageBuf[wo] = fieldCount
  183. wo++
  184. // master fields
  185. masterIndices := make([]byte, fieldCount)
  186. for i, f := range fields {
  187. pageBuf[wo] = byte(f.FieldType)
  188. pageBuf[wo+1] = byte(len(f.FieldName))
  189. wo += 2
  190. copy(pageBuf[wo:], f.FieldName)
  191. wo += uint32(len(f.FieldName))
  192. masterIndices[i] = byte(i)
  193. }
  194. // verCount = 1
  195. pageBuf[wo] = 1
  196. wo++
  197. // version 1 definition
  198. pageBuf[wo] = 1 // verNo
  199. wo++
  200. pageBuf[wo] = fieldCount
  201. wo++
  202. copy(pageBuf[wo:], masterIndices)
  203. wo += uint32(len(masterIndices))
  204. pageHdr.UseSize = offset + required
  205. t.handle.SavePage(t.lastPageID, pageBuf)
  206. // 构建初始 SchemaVersion
  207. initialVersions := []SchemaVersion{{Version: 1, FieldIndices: masterIndices}}
  208. newTable := Table{
  209. info: info,
  210. Field: fields,
  211. handle: t.handle,
  212. indexMeta: indexMate,
  213. tablePageID: t.lastPageID,
  214. tableStartOffset: offset,
  215. curOffset: FieldOffset{PageID: t.lastPageID, StartOffset: uint16(fieldOff), EndOffset: uint16(wo - fieldOff)},
  216. activeVersion: 1,
  217. versions: initialVersions,
  218. }
  219. t.tables = append(t.tables, &newTable)
  220. return &newTable, nil
  221. }
  222. // ===========================================================================
  223. // ✅ Drop 删除表并回收所有页
  224. // ===========================================================================
  225. func (t *TablePage) Drop(name string) error {
  226. pageID := t.hdr.PageID
  227. for pageID != 0 {
  228. buf := make([]byte, PageSize)
  229. if err := t.handle.ReadPage(pageID, buf); err != nil {
  230. return err
  231. }
  232. hdr := (*page.PageHdr)(unsafe.Pointer(&buf[0]))
  233. offset := t.hdrSize
  234. for offset+t.tableInfoSize <= hdr.UseSize {
  235. info := (*TableInfo)(unsafe.Pointer(&buf[offset]))
  236. if util.BytesToString(info.Name[:]) == name && !util.IsHighBitSet(info.Flag) {
  237. // 找到该表在内存中的 Table 对象,获取其索引元数据
  238. var tableEntry *Table
  239. for _, tb := range t.tables {
  240. if util.BytesToString(tb.info.Name[:]) == name && !util.IsHighBitSet(tb.info.Flag) {
  241. tableEntry = tb
  242. break
  243. }
  244. }
  245. // 回收该表所有页 (用该表自己的 indexMeta.metas,不遍历共享的 IndexMeta 页链)
  246. t.recycleTablePages(info, tableEntry)
  247. // 软删除标记
  248. info.Flag = util.SetHighBit(info.Flag)
  249. t.handle.SavePage(pageID, buf)
  250. for i := range t.tables {
  251. if util.BytesToString(t.tables[i].info.Name[:]) == name {
  252. t.tables = append(t.tables[:i], t.tables[i+1:]...)
  253. break
  254. }
  255. }
  256. return nil
  257. }
  258. offset += t.tableInfoSize + uint32(info.FieldAllocateSize)
  259. }
  260. pageID = hdr.NextPage
  261. }
  262. return ErrTableNotFound
  263. }
  264. // recycleTablePages 回收表的所有页 (B+树页、DataPage页、Heap页)
  265. // 注意: IndexMeta 页是所有表共享的,不能释放!
  266. func (t *TablePage) recycleTablePages(info *TableInfo, tableEntry *Table) {
  267. if t.handle.FreePage == nil {
  268. return
  269. }
  270. var pagesToFree []uint32
  271. // 1. 用该表自己的 indexMeta.metas 收集 B+ 树页和 DataPage
  272. // 不遍历共享的 IndexMeta 页链,避免误释放其他表的索引页
  273. if tableEntry != nil && tableEntry.indexMeta != nil {
  274. for i := range tableEntry.indexMeta.metas {
  275. m := &tableEntry.indexMeta.metas[i]
  276. if m.Flag&0x80 != 0 || m.EntryPage == 0 {
  277. continue
  278. }
  279. // 收集 B+ 树所有节点页 (内部节点+叶子节点)
  280. btPages := btree.CollectAllPageIDs(t.handle, m.EntryPage)
  281. pagesToFree = append(pagesToFree, btPages...)
  282. // 只有主键/时序索引的叶子节点存 DataPage ID
  283. // 二级索引叶子存的是 PKID(8B),不是 DataPage ID!
  284. if m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime {
  285. dpIDs := btree.GetDataPageIDs(t.handle, m.EntryPage)
  286. pagesToFree = append(pagesToFree, dpIDs...)
  287. }
  288. }
  289. }
  290. // 2. 收集 Heap 页链 (溢出页)
  291. heapID := info.FirstHeap
  292. for heapID != 0 {
  293. buf := make([]byte, PageSize)
  294. if err := t.handle.ReadPage(heapID, buf); err != nil {
  295. break
  296. }
  297. hdr := (*page.PageHdr)(unsafe.Pointer(&buf[0]))
  298. nextHeap := hdr.NextPage
  299. pagesToFree = append(pagesToFree, heapID)
  300. heapID = nextHeap
  301. }
  302. // 3. 收集 Overflow 页链
  303. oflowID := info.FirstOverflow
  304. for oflowID != 0 {
  305. buf := make([]byte, PageSize)
  306. if err := t.handle.ReadPage(oflowID, buf); err != nil {
  307. break
  308. }
  309. hdr := (*page.PageHdr)(unsafe.Pointer(&buf[0]))
  310. nextOflow := hdr.NextPage
  311. pagesToFree = append(pagesToFree, oflowID)
  312. oflowID = nextOflow
  313. }
  314. // 4. 统一释放所有页
  315. for _, pid := range pagesToFree {
  316. t.handle.FreePage(pid)
  317. }
  318. }
  319. func (t *TablePage) Find(name string) (*Table, bool) {
  320. for i := range t.tables {
  321. tb := t.tables[i]
  322. if util.BytesToString(tb.info.Name[:]) == name && !util.IsHighBitSet(tb.info.Flag) {
  323. return tb, true
  324. }
  325. }
  326. return nil, false
  327. }
  328. // InitHeader 初始化头部信息
  329. func (t *TablePage) InitHeader(pageID uint32) ([]byte, *page.PageHdr) {
  330. newBuf := make([]byte, PageSize)
  331. newHdr := (*page.PageHdr)(unsafe.Pointer(&newBuf[0]))
  332. newHdr.Type = page.TableIndex
  333. newHdr.PageID = pageID
  334. newHdr.UseSize = uint32(unsafe.Sizeof(*newHdr))
  335. t.handle.SavePage(pageID, newBuf)
  336. return newBuf, newHdr
  337. }