This commit is contained in:
2026-02-23 19:37:05 +00:00
parent 6011535509
commit 271046231c
15 changed files with 948 additions and 816 deletions

164
atree/writer.go Normal file
View File

@@ -0,0 +1,164 @@
package atree
import (
"errors"
"hash"
"hash/crc32"
)
type Writer struct {
metricID uint32
timestamp uint32
value float64
tmp []byte
hasher hash.Hash32
isDataPageReused bool
dataPageNo uint32
isRootChanged bool
newRootPageNo uint32
indexPages []uint32
reusedIndexPages []uint32
indexPagesToWrite []PageToWrite
}
type WriterOptions struct {
MetricID uint32
Value float64
Timestamp uint32
IsDataPageReused bool
DataPageNo uint32
Page []byte
}
// dataPage можно записати 1 раз. Щоб не заплутувати інтерфейс - передаю data сторінку
// через Options. Index сторінок може бути від 1 до N, тому виділяю окремий метод
func NewWriter(opt WriterOptions) (*Writer, error) {
if opt.MetricID == 0 {
return nil, errors.New("MetricID option is required")
}
if opt.DataPageNo == 0 {
return nil, errors.New("DataPageNo option is required")
}
// if len(opt.Page) != octopus.DataPageSize {
// return nil, fmt.Errorf("bug: wrong data page size %d", len(opt.Page))
// }
s := &Writer{
metricID: opt.MetricID,
timestamp: opt.Timestamp,
value: opt.Value,
tmp: make([]byte, 21),
isDataPageReused: opt.IsDataPageReused,
dataPageNo: opt.DataPageNo,
hasher: crc32.NewIEEE(),
}
// var err error
// err = s.init(opt.Page)
// if err != nil {
// return nil, err
// }
return s, nil
}
/*
Формат:
4b metricID
8b value
4b timestamp
1b flags (reused)
4b dataPageNo
8KB dataPage
*/
// func (s *Writer) init(dataPage []byte) error {
// bin.PutUint32(s.tmp[0:], s.metricID)
// bin.PutUint32(s.tmp[4:], s.timestamp)
// bin.PutFloat64(s.tmp[8:], s.value)
// if s.isDataPageReused {
// s.tmp[16] = 1
// }
// bin.PutUint32(s.tmp[17:], s.dataPageNo)
// _, err := s.file.Write(s.tmp)
// if err != nil {
// return err
// }
// _, err = s.file.Write(dataPage)
// if err != nil {
// return err
// }
// s.hasher.Write(s.tmp)
// s.hasher.Write(dataPage)
// return nil
// }
/*
Формат
1b index page flags
4b indexPageNo
Nb indexPage
*/
// func (s *Writer) AppendIndexPage(indexPageNo uint32, indexPage []byte, flags byte) error {
// s.tmp[0] = flags
// bin.PutUint32(s.tmp[1:], indexPageNo)
// // _, err := s.file.Write(s.tmp[:5])
// // if err != nil {
// // return err
// // }
// // _, err = s.file.Write(indexPage)
// // if err != nil {
// // return err
// // }
// s.hasher.Write(s.tmp[:5])
// s.hasher.Write(indexPage)
// s.indexPages = append(s.indexPages, indexPageNo)
// if (flags & FlagReused) == FlagReused {
// s.reusedIndexPages = append(s.reusedIndexPages, indexPageNo)
// }
// if (flags & FlagNewRoot) == FlagNewRoot {
// s.newRootPageNo = indexPageNo
// s.isRootChanged = true
// }
// s.indexPagesToWrite = append(s.indexPagesToWrite,
// PageToWrite{
// PageNo: indexPageNo,
// Data: indexPage,
// })
// return nil
// }
// func (s *Writer) IndexPagesToWrite() []PageToWrite {
// return s.indexPagesToWrite
// }
// func (s *Writer) Close() (err error) {
// // финализирую запись
// bin.PutUint32(s.tmp, s.hasher.Sum32())
// _, err = s.file.Write(s.tmp[:4])
// if err != nil {
// return err
// }
// err = s.file.Sync()
// if err != nil {
// return
// }
// return s.file.Close()
// }
// func (s *Writer) GetReport() Report {
// return Report{
// IsDataPageReused: s.isDataPageReused,
// DataPageNo: s.dataPageNo,
// //IndexPages: s.indexPages,
// IsRootChanged: s.isRootChanged,
// NewRootPageNo: s.newRootPageNo,
// ReusedIndexPages: s.reusedIndexPages,
// }
// }