wp
This commit is contained in:
@@ -12,11 +12,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
diploma "gordenko.dev/dima/qb"
|
||||
"gordenko.dev/dima/qb"
|
||||
"gordenko.dev/dima/qb/atree"
|
||||
"gordenko.dev/dima/qb/bin"
|
||||
"gordenko.dev/dima/qb/chunkenc"
|
||||
"gordenko.dev/dima/qb/conbuf"
|
||||
"gordenko.dev/dima/qb/freelist"
|
||||
"gordenko.dev/dima/qb/recovery"
|
||||
"gordenko.dev/dima/qb/txlog"
|
||||
@@ -84,13 +82,25 @@ func New(opt Options) (_ *Database, err error) {
|
||||
return nil, errors.New("WaitGroup option is required")
|
||||
}
|
||||
|
||||
filePath := filepath.Join(opt.Dir, opt.DatabaseName+".free")
|
||||
|
||||
freeListFile, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
freeList, err := freelist.New(freelist.Options{
|
||||
PageSize: 2048,
|
||||
File: freeListFile,
|
||||
})
|
||||
|
||||
s := &Database{
|
||||
workerSignalCh: make(chan struct{}, 1),
|
||||
dir: opt.Dir,
|
||||
databaseName: opt.DatabaseName,
|
||||
metrics: make(map[uint32]*_metric),
|
||||
//metricLockEntries: make(map[uint32]*metricLockEntry),
|
||||
freeList: freelist.New(),
|
||||
freeList: freeList,
|
||||
tcpPort: opt.TCPPort,
|
||||
logfile: opt.Logfile,
|
||||
logger: log.New(opt.Logfile, "", log.LstdFlags),
|
||||
@@ -143,7 +153,7 @@ func (s *Database) recovery() {
|
||||
|
||||
recipe, err := advisor.GetRecipe()
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.GetRecoveryRecipeFailed, err)
|
||||
qb.Abort(qb.GetRecoveryRecipeFailed, err)
|
||||
}
|
||||
|
||||
var logNumber int
|
||||
@@ -152,13 +162,13 @@ func (s *Database) recovery() {
|
||||
if recipe.Snapshot != "" {
|
||||
err = s.loadSnapshot(recipe.Snapshot)
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.LoadSnapshotFailed, err)
|
||||
qb.Abort(qb.LoadSnapshotFailed, err)
|
||||
}
|
||||
}
|
||||
for _, changesFileName := range recipe.Changes {
|
||||
err = s.replayChanges(changesFileName)
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.ReplayChangesFailed, err)
|
||||
qb.Abort(qb.ReplayChangesFailed, err)
|
||||
}
|
||||
}
|
||||
logNumber = recipe.LogNumber
|
||||
@@ -174,28 +184,28 @@ func (s *Database) recovery() {
|
||||
WaitGroup: s.waitGroup,
|
||||
})
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.CreateChangesWriterFailed, err)
|
||||
qb.Abort(qb.CreateChangesWriterFailed, err)
|
||||
|
||||
}
|
||||
go s.txlog.Run()
|
||||
|
||||
// fileNames, err := s.searchREDOFiles()
|
||||
// if err != nil {
|
||||
// diploma.Abort(diploma.SearchREDOFilesFailed, err)
|
||||
// qb.Abort(qb.SearchREDOFilesFailed, err)
|
||||
// }
|
||||
|
||||
// if len(fileNames) > 0 {
|
||||
// for _, fileName := range fileNames {
|
||||
// err = s.replayREDOFile(fileName)
|
||||
// if err != nil {
|
||||
// diploma.Abort(diploma.ReplayREDOFileFailed, err)
|
||||
// qb.Abort(qb.ReplayREDOFileFailed, err)
|
||||
// }
|
||||
// }
|
||||
|
||||
// for _, fileName := range fileNames {
|
||||
// err = os.Remove(fileName)
|
||||
// if err != nil {
|
||||
// diploma.Abort(diploma.RemoveREDOFileFailed, err)
|
||||
// qb.Abort(qb.RemoveREDOFileFailed, err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -204,14 +214,14 @@ func (s *Database) recovery() {
|
||||
if recipe.CompleteSnapshot {
|
||||
err = s.dumpSnapshot(logNumber)
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.DumpSnapshotFailed, err)
|
||||
qb.Abort(qb.DumpSnapshotFailed, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, fileName := range recipe.ToDelete {
|
||||
err = os.Remove(fileName)
|
||||
if err != nil {
|
||||
diploma.Abort(diploma.RemoveRecipeFileFailed, err)
|
||||
qb.Abort(qb.RemoveRecipeFileFailed, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,100 +358,100 @@ func (s *Database) replayChanges(fileName string) error {
|
||||
}
|
||||
|
||||
func (s *Database) replayChangesRecord(untyped any) error {
|
||||
switch rec := untyped.(type) {
|
||||
case txlog.AddedMetric:
|
||||
var (
|
||||
values diploma.ValueCompressor
|
||||
timestampsBuf = conbuf.New(nil)
|
||||
valuesBuf = conbuf.New(nil)
|
||||
)
|
||||
// switch rec := untyped.(type) {
|
||||
// case txlog.AddedMetric:
|
||||
// var (
|
||||
// values qb.ValueCompressor
|
||||
// timestampsBuf = conbuf.New(nil)
|
||||
// valuesBuf = conbuf.New(nil)
|
||||
// )
|
||||
|
||||
if rec.MetricType == diploma.Cumulative {
|
||||
values = chunkenc.NewReverseCumulativeDeltaCompressor(
|
||||
valuesBuf, 0, byte(rec.FracDigits))
|
||||
} else {
|
||||
values = chunkenc.NewReverseInstantDeltaCompressor(
|
||||
valuesBuf, 0, byte(rec.FracDigits))
|
||||
}
|
||||
|
||||
s.metrics[rec.MetricID] = &_metric{
|
||||
MetricType: rec.MetricType,
|
||||
FracDigits: byte(rec.FracDigits),
|
||||
TimestampsBuf: timestampsBuf,
|
||||
ValuesBuf: valuesBuf,
|
||||
Timestamps: chunkenc.NewReverseTimeDeltaCompressor(timestampsBuf, 0),
|
||||
Values: values,
|
||||
}
|
||||
|
||||
case txlog.DeletedMetric:
|
||||
delete(s.metrics, rec.MetricID)
|
||||
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.AppendedMeasures:
|
||||
metric, ok := s.metrics[rec.MetricID]
|
||||
if ok {
|
||||
for _, measure := range rec.Measures {
|
||||
metric.Timestamps.Append(measure.Timestamp)
|
||||
metric.Values.Append(measure.Value)
|
||||
|
||||
if metric.Since == 0 {
|
||||
metric.Since = measure.Timestamp
|
||||
metric.SinceValue = measure.Value
|
||||
}
|
||||
|
||||
metric.Until = measure.Timestamp
|
||||
metric.UntilValue = measure.Value
|
||||
}
|
||||
}
|
||||
|
||||
// case txlog.AppendedMeasureWithOverflow:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if ok {
|
||||
// metric.ReinitBy(rec.Timestamp, rec.Value)
|
||||
// if rec.IsRootChanged {
|
||||
// metric.RootPageNo = rec.RootPageNo
|
||||
// if rec.MetricType == qb.Cumulative {
|
||||
// values = chunkenc.NewReverseCumulativeDeltaCompressor(
|
||||
// valuesBuf, 0, byte(rec.FracDigits))
|
||||
// } else {
|
||||
// values = chunkenc.NewReverseInstantDeltaCompressor(
|
||||
// valuesBuf, 0, byte(rec.FracDigits))
|
||||
// }
|
||||
// metric.LastPageNo = rec.DataPageNo
|
||||
// // delete free pages
|
||||
// if rec.IsDataPageReused {
|
||||
// s.freeList.DeleteReservedPages([]uint32{
|
||||
// rec.DataPageNo,
|
||||
// })
|
||||
|
||||
// s.metrics[rec.MetricID] = &_metric{
|
||||
// MetricType: rec.MetricType,
|
||||
// FracDigits: byte(rec.FracDigits),
|
||||
// TimestampsBuf: timestampsBuf,
|
||||
// ValuesBuf: valuesBuf,
|
||||
// Timestamps: chunkenc.NewReverseTimeDeltaCompressor(timestampsBuf, 0),
|
||||
// Values: values,
|
||||
// }
|
||||
// if len(rec.ReusedIndexPages) > 0 {
|
||||
// s.freeList.DeleteReservedPages(rec.ReusedIndexPages)
|
||||
|
||||
// case txlog.DeletedMetric:
|
||||
// delete(s.metrics, rec.MetricID)
|
||||
// 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.AppendedMeasures:
|
||||
// metric, ok := s.metrics[rec.MetricID]
|
||||
// if ok {
|
||||
// for _, measure := range rec.Measures {
|
||||
// metric.Timestamps.Append(measure.Timestamp)
|
||||
// metric.Values.Append(measure.Value)
|
||||
|
||||
// if metric.Since == 0 {
|
||||
// metric.Since = measure.Timestamp
|
||||
// metric.SinceValue = measure.Value
|
||||
// }
|
||||
|
||||
// metric.Until = measure.Timestamp
|
||||
// metric.UntilValue = measure.Value
|
||||
// }
|
||||
// }
|
||||
|
||||
// // case txlog.AppendedMeasureWithOverflow:
|
||||
// // metric, ok := s.metrics[rec.MetricID]
|
||||
// // if ok {
|
||||
// // metric.ReinitBy(rec.Timestamp, rec.Value)
|
||||
// // if rec.IsRootChanged {
|
||||
// // metric.RootPageNo = rec.RootPageNo
|
||||
// // }
|
||||
// // metric.LastPageNo = rec.DataPageNo
|
||||
// // // delete free pages
|
||||
// // if rec.IsDataPageReused {
|
||||
// // s.freeList.DeleteReservedPages([]uint32{
|
||||
// // rec.DataPageNo,
|
||||
// // })
|
||||
// // }
|
||||
// // if len(rec.ReusedIndexPages) > 0 {
|
||||
// // s.freeList.DeleteReservedPages(rec.ReusedIndexPages)
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// 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))
|
||||
// }
|
||||
|
||||
case txlog.DeletedMeasures:
|
||||
metric, ok := s.metrics[rec.MetricID]
|
||||
if ok {
|
||||
metric.DeleteMeasures()
|
||||
if len(rec.FreePageNumbers) > 0 {
|
||||
s.freeList.AddPages(rec.FreePageNumbers)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
diploma.Abort(diploma.UnknownTxLogRecordTypeBug,
|
||||
fmt.Errorf("bug: unknown record type %T in TransactionLog", rec))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user