This commit is contained in:
2026-06-13 19:53:27 +03:00
parent 5778782737
commit 1d1fdb1f0b
19 changed files with 1508 additions and 858 deletions

View File

@@ -11,7 +11,6 @@ import (
"sync"
"gordenko.dev/dima/qb"
"gordenko.dev/dima/qb/atree"
"gordenko.dev/dima/qb/freelist"
)
@@ -63,21 +62,19 @@ type Changes struct {
}
type Writer struct {
mutex sync.Mutex
dataPagesCount uint32
indexPagesCount uint32
dataFreeList *freelist.FreeList
indexFreeList *freelist.FreeList
atree *atree.Atree
mutex sync.Mutex
dataPagesCount uint32
indexPagesCount uint32
dataFreeList *freelist.FreeList
indexFreeList *freelist.FreeList
//atree *atree.Atree
dir string
w *bytes.Buffer // wal буфер для упаковки даних перед записом на диск
wal *os.File
dataFile *os.File
indexFile *os.File
indexPageSize int
dataPageSize int
input []any
dataPreparer *WritePreparer
writePreparer *WritePreparer
appendToWorkerQueue func(any)
written int64
isExited bool
@@ -87,25 +84,23 @@ type Writer struct {
}
type WriterOptions struct {
IndexPageSize int
DataPageSize int
Dir string
SnapshotNumber int // номер журнала
Dir string
//SnapshotNumber int // номер журнала
AppendToWorkerQueue func(any)
DataFreeList *freelist.FreeList
IndexFreeList *freelist.FreeList
Atree *atree.Atree
ExitCh chan struct{}
WaitGroup *sync.WaitGroup
//Atree *atree.Atree
ExitCh chan struct{}
WaitGroup *sync.WaitGroup
}
func NewWriter(opt WriterOptions) (*Writer, error) {
if (opt.IndexPageSize % 2) != 0 {
return nil, errors.New("IndexPageSize must be multiple of 2")
}
if (opt.DataPageSize % 2) != 0 {
return nil, errors.New("DataPageSize must be multiple of 2")
}
// if (opt.IndexPageSize % 2) != 0 {
// return nil, errors.New("IndexPageSize must be multiple of 2")
// }
// if (opt.DataPageSize % 2) != 0 {
// return nil, errors.New("DataPageSize must be multiple of 2")
// }
if opt.Dir == "" {
return nil, errors.New("Dir option is required")
}
@@ -118,9 +113,9 @@ func NewWriter(opt WriterOptions) (*Writer, error) {
if opt.IndexFreeList == nil {
return nil, errors.New("IndexFreeList option is required")
}
if opt.Atree == nil {
return nil, errors.New("Atree option is required")
}
// if opt.Atree == nil {
// return nil, errors.New("Atree option is required")
// }
if opt.ExitCh == nil {
return nil, errors.New("ExitCh option is required")
}
@@ -128,21 +123,31 @@ func NewWriter(opt WriterOptions) (*Writer, error) {
return nil, errors.New("WaitGroup option is required")
}
pageIngester, err := NewPageIngester(PageIngesterOptions{
GetIndexPageNumber: s.getIndexPageNumber,
GetDataPageNumber: s.getDataPageNumber,
})
if err != nil {
return nil, err
}
writePreparer := NewWritePreparer(WritePreparerOptions{
//MinWALBufferSize: 128,
PageIngester: pageIngester,
})
s := &Writer{
indexPageSize: opt.IndexPageSize,
dataPageSize: opt.DataPageSize,
dir: opt.Dir,
appendToWorkerQueue: opt.AppendToWorkerQueue,
dataFreeList: opt.DataFreeList,
indexFreeList: opt.IndexFreeList,
atree: opt.Atree,
exitCh: opt.ExitCh,
waitGroup: opt.WaitGroup,
signalCh: make(chan struct{}, 1),
writePreparer: writePreparer,
//atree: opt.Atree,
exitCh: opt.ExitCh,
waitGroup: opt.WaitGroup,
signalCh: make(chan struct{}, 1),
}
var err error
if opt.SnapshotNumber <= 0 {
log.Fatalln("FIX FUCK NUMBER")
}
@@ -214,7 +219,7 @@ func (s *Writer) packAndWrite() (err error) {
// }
s.mutex.Unlock()
prepared := s.dataPreparer.Prepare(input)
prepared := s.writePreparer.Prepare(input)
// 3. Пишу на диск WAL (append)
n, err := s.wal.Write(prepared.Packet)
@@ -348,35 +353,35 @@ type PageToWrite struct {
// writePagesToAtree - записує сторінки в .data та .index файли
func (s *Writer) WritePagesToAtree(indexPages []PageToWrite, dataPages []PageToWrite) (err error) {
for _, p := range dataPages {
if len(p.Content) != s.dataPageSize {
if len(p.Content) != DataPageSize {
return fmt.Errorf("wrong data page size: %d", len(p.Content))
}
var (
off = int(p.PageNo-1) * s.dataPageSize
off = int(p.PageNo-1) * DataPageSize
n int
)
n, err = s.dataFile.WriteAt(p.Content, int64(off))
if err != nil {
return
}
if n != s.dataPageSize {
return fmt.Errorf("write %d instead of %d", n, s.dataPageSize)
if n != DataPageSize {
return fmt.Errorf("write %d instead of %d", n, DataPageSize)
}
}
for _, p := range indexPages {
if len(p.Content) != s.indexPageSize {
if len(p.Content) != IndexPageSize {
return fmt.Errorf("wrong index page size: %d", len(p.Content))
}
var (
off = int(p.PageNo-1) * s.indexPageSize
off = int(p.PageNo-1) * IndexPageSize
n int
)
n, err = s.indexFile.WriteAt(p.Content, int64(off))
if err != nil {
return
}
if n != s.indexPageSize {
return fmt.Errorf("write %d instead of %d", n, s.indexPageSize)
if n != IndexPageSize {
return fmt.Errorf("write %d instead of %d", n, IndexPageSize)
}
}
return nil