File.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package DB
  2. import (
  3. "TsDB2/DB/pool"
  4. "os"
  5. "unsafe"
  6. )
  7. const (
  8. PageSize4K = 4096 // 头、表、索引元数据
  9. // 索引页是动态长度,不由这里定义
  10. )
  11. // File 只负责:打开、关闭、读、写 —— unsafe 全部收敛
  12. type File struct {
  13. f *os.File
  14. bp *pool.BufferPool // 页面缓冲池 (nil = 未启用)
  15. }
  16. func OpenFile(path string) (*File, error) {
  17. f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0644)
  18. if err != nil {
  19. return nil, err
  20. }
  21. return &File{f: f}, nil
  22. }
  23. func (ff *File) Close() error {
  24. if ff.bp != nil {
  25. ff.bp.Stop() // 先刷盘再关文件
  26. }
  27. return ff.f.Close()
  28. }
  29. // InitBufferPool 初始化页面缓冲池, 拦截 ReadPage/WritePage 实现内存缓存
  30. // capacity: 最大缓存页数 (建议 10000~50000)
  31. func (ff *File) InitBufferPool(capacity int) {
  32. ff.bp = pool.NewBufferPool(capacity, ff.readPageDisk, ff.writePageDisk, nil)
  33. }
  34. // Commit 显式提交 — 将所有脏页刷盘
  35. func (ff *File) Commit() error {
  36. if ff.bp != nil {
  37. return ff.bp.Commit()
  38. }
  39. return nil
  40. }
  41. func (ff *File) WritePage16K(pageID uint32, buf *[PageSize]byte) error {
  42. // 头占一个4K,所以 pageID 从 1 开始
  43. offset := int64(PageSize4K) + int64(pageID-1)*int64(PageSize)
  44. _, err := ff.f.WriteAt(buf[:], offset)
  45. return err
  46. }
  47. // -----------------------------------------------------------------------------------
  48. // ✅ 动态长度:索引页 — 缓冲池拦截层
  49. // -----------------------------------------------------------------------------------
  50. func (ff *File) WritePage(pageID uint32, buf []byte) error {
  51. if ff.bp != nil {
  52. return ff.bp.WritePage(pageID, buf) // 写缓存, 延迟落盘
  53. }
  54. return ff.writePageDisk(pageID, buf)
  55. }
  56. func (ff *File) ReadPage(pageID uint32, buf []byte) error {
  57. if ff.bp != nil {
  58. return ff.bp.ReadPage(pageID, buf) // 先查缓存
  59. }
  60. return ff.readPageDisk(pageID, buf)
  61. }
  62. // -----------------------------------------------------------------------------------
  63. // ✅ 底层磁盘 I/O (缓冲池回源)
  64. // -----------------------------------------------------------------------------------
  65. func (ff *File) writePageDisk(pageID uint32, buf []byte) error {
  66. offset := int64(PageSize4K) + int64(pageID-1)*int64(len(buf))
  67. _, err := ff.f.WriteAt(buf, offset)
  68. return err
  69. }
  70. func (ff *File) readPageDisk(pageID uint32, buf []byte) error {
  71. offset := int64(PageSize4K) + int64(pageID-1)*int64(len(buf))
  72. _, err := ff.f.ReadAt(buf, offset)
  73. return err
  74. }
  75. // -----------------------------------------------------------------------------------
  76. // ✅ 头读写(固定4K)
  77. // -----------------------------------------------------------------------------------
  78. func (ff *File) WriteHeader(h *HeaderPage) error {
  79. var buf [PageSize4K]byte
  80. copy(buf[:], (*[PageSize4K]byte)(unsafe.Pointer(h))[:])
  81. _, err := ff.f.WriteAt(buf[:], 0)
  82. return err
  83. }
  84. func (ff *File) ReadHeader() (*HeaderPage, error) {
  85. buf := make([]byte, PageSize4K)
  86. _, err := ff.f.ReadAt(buf, 0)
  87. if err != nil {
  88. return nil, err
  89. }
  90. h := &HeaderPage{}
  91. copy((*[PageSize4K]byte)(unsafe.Pointer(h))[:], buf)
  92. return h, nil
  93. }
  94. func (ff *File) TruncateSize(size int64) error {
  95. return ff.f.Truncate(size)
  96. }