Files
qb/atree/redox/reader.go
2026-02-23 19:37:05 +00:00

97 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package redox
import (
"fmt"
"hash/crc32"
"io"
"os"
"gordenko.dev/dima/qb/bin"
)
type REDOFile struct {
MetricID uint32
Timestamp uint32
Value float64
IsDataPageReused bool
DataPage PageToWrite
IsRootChanged bool
RootPageNo uint32
ReusedIndexPages []uint32
IndexPages []PageToWrite
}
type ReadREDOFileReq struct {
FileName string
DataPageSize int
IndexPageSize int
}
func ReadREDOFile(req ReadREDOFileReq) (*REDOFile, error) {
buf, err := os.ReadFile(req.FileName)
if err != nil {
return nil, err
}
if len(buf) < 25 {
return nil, io.EOF
}
var (
end = len(buf) - 4
payload = buf[:end]
checksum = bin.GetUint32(buf[end:])
calculatedChecksum = crc32.ChecksumIEEE(payload)
)
// Помилка чексуми означає що файл або недописаний, або пошкодженний
if checksum != calculatedChecksum {
return nil, fmt.Errorf("written checksum %d not equal calculated checksum %d",
checksum, calculatedChecksum)
}
var (
redoLog = REDOFile{
MetricID: bin.GetUint32(buf[0:]),
Timestamp: bin.GetUint32(buf[4:]),
Value: bin.GetFloat64(buf[8:]),
IsDataPageReused: buf[16] == 1,
DataPage: PageToWrite{
PageNo: bin.GetUint32(buf[17:]),
Data: buf[21 : 21+req.DataPageSize],
},
}
pos = 21 + req.DataPageSize
)
for {
if pos == len(payload) {
return &redoLog, nil
}
if pos > len(payload) {
return nil, io.EOF
}
flags := buf[pos]
item := PageToWrite{
PageNo: bin.GetUint32(buf[pos+1:]),
}
pos += 5 // flags + pageNo
item.Data = buf[pos : pos+req.IndexPageSize]
pos += req.IndexPageSize
redoLog.IndexPages = append(redoLog.IndexPages, item)
if (flags & FlagReused) == FlagReused {
redoLog.ReusedIndexPages = append(redoLog.ReusedIndexPages, item.PageNo)
}
if (flags & FlagNewRoot) == FlagNewRoot {
redoLog.IsRootChanged = true
redoLog.RootPageNo = item.PageNo
}
}
}