wp
This commit is contained in:
@@ -4,22 +4,20 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
qb "gordenko.dev/dima/qb"
|
||||
"gordenko.dev/dima/qb/atree"
|
||||
"gordenko.dev/dima/qb/txlog"
|
||||
"gordenko.dev/dima/qb/storage"
|
||||
)
|
||||
|
||||
type WALReplayer struct {
|
||||
walReader *txlog.Reader
|
||||
walReader *storage.WALReader
|
||||
metrics map[uint32]*ReplayMetric
|
||||
freeIndexPages []uint32
|
||||
freeDataPages []uint32
|
||||
indexPages []txlog.PageToWrite
|
||||
dataPages []txlog.PageToWrite
|
||||
indexPages []storage.PageToWrite
|
||||
dataPages []storage.PageToWrite
|
||||
}
|
||||
|
||||
type WALReplayerOptions struct {
|
||||
WALReader *txlog.Reader
|
||||
WALReader *storage.WALReader
|
||||
Metrics map[uint32]*ReplayMetric // from snapshot
|
||||
FreeIndexPages []uint32 // from snapshot
|
||||
FreeDataPages []uint32 // from snapshot
|
||||
@@ -40,122 +38,80 @@ func NewWALReplayer(opt WALReplayerOptions) (*WALReplayer, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *WALReplayer) IndexPages() []storage.PageToWrite {
|
||||
return s.indexPages
|
||||
}
|
||||
|
||||
func (s *WALReplayer) DataPages() []storage.PageToWrite {
|
||||
return s.dataPages
|
||||
}
|
||||
|
||||
func (s *WALReplayer) Replay() error {
|
||||
for {
|
||||
records, isLast, err := s.walReader.NextPacket()
|
||||
records, isLastPacket, err := s.walReader.NextPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if isLast {
|
||||
if len(records) > 0 {
|
||||
var appendRecords []txlog.WALRecordAppendMeasures
|
||||
for _, untyped := range records {
|
||||
rec, ok := untyped.(txlog.WALRecordAppendMeasures)
|
||||
if ok {
|
||||
appendRecords = append(appendRecords, rec)
|
||||
}
|
||||
}
|
||||
// prepare pages and rewrite
|
||||
indexPages, dataPages := pagesToWriteFromWALRecords(metrics, appendRecords)
|
||||
|
||||
err = s.txlog.WritePagesToAtree(indexPages, dataPages)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// для останнього rec - повторюємо запис сторінок
|
||||
// rewrite write pages
|
||||
//s.txlog.
|
||||
//return nil
|
||||
}
|
||||
|
||||
for _, rec := range records {
|
||||
if err = s.replayWALRecord(rec); err != nil {
|
||||
if err = s.replayRecord(rec, isLastPacket); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func (s *WALReplayer) replayPacket(records []any, isLastPacket bool) {
|
||||
// for _, untyped := range records {
|
||||
// switch rec := untyped.(type) {
|
||||
// case txlog.WALRecordAppendMeasures:
|
||||
// s.onWALRecordAppendMeasures(rec, isLastPacket)
|
||||
// }
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
func (s *WALReplayer) replayWALRecord(untyped any) (err error) {
|
||||
func (s *WALReplayer) replayRecord(untyped any, isLastPacket bool) (err error) {
|
||||
switch rec := untyped.(type) {
|
||||
case txlog.AddedMetric:
|
||||
if err = s.onAddedMetric(rec); err != nil {
|
||||
case storage.MeasuresAppendRecord:
|
||||
if err = s.onMeasuresAppend(rec); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
case txlog.DeletedMetric:
|
||||
if err = s.onDeletedMetric(rec); err != nil {
|
||||
case storage.MeasuresAppendWithGrowRecord:
|
||||
if err = s.onMeasuresAppendWithGrow(rec, isLastPacket); err != nil {
|
||||
return
|
||||
}
|
||||
case storage.MetricAddRecord:
|
||||
if err = s.onMetricAdd(rec); err != nil {
|
||||
return
|
||||
}
|
||||
case storage.MetricDeleteRecord:
|
||||
if err = s.onMetricDelete(rec); err != nil {
|
||||
return
|
||||
}
|
||||
// case storage.DeletedMeasures:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if ok {
|
||||
// metric.DeleteMeasures()
|
||||
// if len(rec.FreePageNumbers) > 0 {
|
||||
// s.freeList.AddPages(rec.FreePageNumbers)
|
||||
// }
|
||||
// }
|
||||
|
||||
// case txlog.AppendedMeasure:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if ok {
|
||||
// metric.Timestamps.Append(rec.Timestamp)
|
||||
// metric.Values.Append(rec.Value)
|
||||
|
||||
// if metric.Since == 0 {
|
||||
// metric.Since = rec.Timestamp
|
||||
// metric.SinceValue = rec.Value
|
||||
// }
|
||||
|
||||
// metric.Until = rec.Timestamp
|
||||
// metric.UntilValue = rec.Value
|
||||
// }
|
||||
|
||||
case txlog.WALRecordAppendMeasures:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if !ok {
|
||||
// qb.Abort(qb.MetricNotFoundDuringReplay, nil)
|
||||
// }
|
||||
//metric.ReplayAppendedMeasures(rec) FIX
|
||||
|
||||
// case txlog.DeletedMeasures:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if ok {
|
||||
// metric.DeleteMeasures()
|
||||
// if len(rec.FreePageNumbers) > 0 {
|
||||
// s.freeList.AddPages(rec.FreePageNumbers)
|
||||
// }
|
||||
// }
|
||||
|
||||
default:
|
||||
qb.Abort(qb.UnknownTxLogRecordTypeBug,
|
||||
fmt.Errorf("bug: unknown record type %T in TransactionLog", rec))
|
||||
// default:
|
||||
// qb.Abort(qb.UnknownstorageRecordTypeBug,
|
||||
// fmt.Errorf("bug: unknown record type %T in TransactionLog", rec))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WALReplayer) onAddedMetric(rec txlog.AddedMetric) (err error) {
|
||||
func (s *WALReplayer) onMetricAdd(rec storage.MetricAddRecord) (err error) {
|
||||
_, ok := s.metrics[rec.MetricID]
|
||||
if ok {
|
||||
return fmt.Errorf("metric %d add failed: already added", rec.MetricID)
|
||||
}
|
||||
var (
|
||||
buf = make([]byte, atree.DataPageSize)
|
||||
buf = make([]byte, storage.DataPageSize)
|
||||
)
|
||||
s.metrics[rec.MetricID] = &ReplayMetric{
|
||||
metricType: rec.MetricType,
|
||||
fracDigits: byte(rec.FracDigits),
|
||||
buf: buf,
|
||||
databuf: buf[:atree.DataPagePayloadSize],
|
||||
databuf: buf[:storage.DataPagePayloadSize],
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *WALReplayer) onDeletedMetric(rec txlog.DeletedMetric) error {
|
||||
func (s *WALReplayer) onMetricDelete(rec storage.MetricDeleteRecord) error {
|
||||
_, ok := s.metrics[rec.MetricID]
|
||||
if !ok {
|
||||
return fmt.Errorf("metric %d deletion failed: not found", rec.MetricID)
|
||||
@@ -166,15 +122,21 @@ func (s *WALReplayer) onDeletedMetric(rec txlog.DeletedMetric) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *WALReplayer) onAppendMeasures(rec txlog.WALRecordAppendMeasures, isLastPacket bool) {
|
||||
func (s *WALReplayer) onMeasuresAppend(rec storage.MeasuresAppendRecord) (err error) {
|
||||
metric, ok := s.metrics[rec.MetricID]
|
||||
if !ok {
|
||||
qb.Abort(qb.MetricNotFoundDuringReplay, nil)
|
||||
return fmt.Errorf("append measures failed: metric %d not found", rec.MetricID)
|
||||
}
|
||||
if isLastPacket {
|
||||
s.collectPagesToWrite(metric, rec)
|
||||
metric.MeasuresAppend(rec)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *WALReplayer) onMeasuresAppendWithGrow(rec storage.MeasuresAppendWithGrowRecord, isLastPacket bool) (err error) {
|
||||
metric, ok := s.metrics[rec.MetricID]
|
||||
if !ok {
|
||||
return fmt.Errorf("append measures failed: metric %d not found", rec.MetricID)
|
||||
}
|
||||
result := metric.AppendedMeasures(rec, isLastPacket)
|
||||
result := metric.MeasuresAppendWithGrow(rec, isLastPacket)
|
||||
//
|
||||
if isLastPacket {
|
||||
s.indexPages = append(s.indexPages, result.IndexPages...)
|
||||
@@ -183,22 +145,33 @@ func (s *WALReplayer) onAppendMeasures(rec txlog.WALRecordAppendMeasures, isLast
|
||||
//
|
||||
s.freeIndexPages = s.freeIndexPages[:len(s.freeIndexPages)-result.ReusedIndexPagesCount]
|
||||
s.freeDataPages = s.freeDataPages[:len(s.freeDataPages)-result.ReusedDataPagesCount]
|
||||
return
|
||||
}
|
||||
|
||||
func (s *WALReplayer) collectPagesToWrite(metric *ReplayMetric, rec txlog.WALRecordAppendMeasures) {
|
||||
metric.ApplyHeadDataPage(rec.CompletedDataPage)
|
||||
//func (s *WALReplayer) collectPagesToWrite(metric *ReplayMetric, rec storage.WALRecordAppendMeasures) {
|
||||
// metric.ApplyHeadDataPage(rec.CompletedDataPage)
|
||||
|
||||
s.dataPages = append(s.dataPages, txlog.PageToWrite{
|
||||
PageNo: p.PageNo,
|
||||
Content: metric.buf,
|
||||
})
|
||||
// s.dataPages = append(s.dataPages, storage.PageToWrite{
|
||||
// PageNo: p.PageNo,
|
||||
// Content: metric.buf,
|
||||
// })
|
||||
|
||||
for _, x := range rec.DataPages {
|
||||
s.dataPages = append(s.dataPages, txlog.PageToWrite{
|
||||
PageNo: x.PageNo,
|
||||
Content: x.Content,
|
||||
})
|
||||
}
|
||||
//metric.ApplyHeadIndexPages(rec.ChangedIndexLevels)
|
||||
// for _, x := range rec.DataPages {
|
||||
// s.dataPages = append(s.dataPages, storage.PageToWrite{
|
||||
// PageNo: x.PageNo,
|
||||
// Content: x.Content,
|
||||
// })
|
||||
// }
|
||||
//metric.ApplyHeadIndexPages(rec.ChangedIndexLevels)
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
// func (s *WALReplayer) replayPacket(records []any, isLastPacket bool) {
|
||||
// for _, untyped := range records {
|
||||
// switch rec := untyped.(type) {
|
||||
// case storage.WALRecordAppendMeasures:
|
||||
// s.onWALRecordAppendMeasures(rec, isLastPacket)
|
||||
// }
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user