2026-02-23 11:02:29 +00:00
|
|
|
package qb
|
2026-02-10 14:02:11 +00:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2026-06-09 08:16:16 +03:00
|
|
|
"io"
|
2026-02-10 14:02:11 +00:00
|
|
|
"os"
|
2026-06-13 22:43:17 +00:00
|
|
|
"path/filepath"
|
2026-02-10 14:02:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type MetricType byte
|
|
|
|
|
type GroupBy byte
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
Cumulative MetricType = 1
|
|
|
|
|
Instant MetricType = 2
|
|
|
|
|
MaxFracDigits byte = 7
|
|
|
|
|
|
|
|
|
|
GroupByHour GroupBy = 1
|
|
|
|
|
GroupByDay GroupBy = 2
|
|
|
|
|
GroupByMonth GroupBy = 3
|
|
|
|
|
|
|
|
|
|
AggregateMin byte = 1
|
|
|
|
|
AggregateMax byte = 2
|
|
|
|
|
AggregateAvg byte = 4
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type TimestampCompressor interface {
|
2026-06-11 01:46:25 +00:00
|
|
|
// (tmp, timestamp)
|
|
|
|
|
Evaluate([]byte, uint32) TimeEvaluationReport
|
2026-06-12 06:11:57 +00:00
|
|
|
// (rewindOffset, change, timestamp)
|
2026-06-11 14:27:38 +00:00
|
|
|
Append(int, []byte, uint32)
|
|
|
|
|
Size() int
|
2026-06-12 14:21:14 +00:00
|
|
|
StoredSize() int
|
2026-06-07 21:27:18 +03:00
|
|
|
//DeleteLast()
|
2026-06-12 06:11:57 +00:00
|
|
|
CaptureState()
|
2026-06-13 07:13:03 +00:00
|
|
|
ForgetCapturedState()
|
2026-06-12 06:11:57 +00:00
|
|
|
// (offset) => payload
|
|
|
|
|
Tail(int) []byte
|
2026-05-31 20:01:28 +00:00
|
|
|
CreateDecompressor() TimestampDecompressor
|
2026-06-09 08:16:16 +03:00
|
|
|
//Payload() []byte // для снапшота
|
2026-06-11 01:46:25 +00:00
|
|
|
// Offset() int
|
2026-06-12 06:11:57 +00:00
|
|
|
ReplaceBuffer([]byte)
|
2026-06-12 14:21:14 +00:00
|
|
|
WriteStoredTo(io.Writer) error
|
2026-06-09 08:16:16 +03:00
|
|
|
LastTimestamp() uint32
|
|
|
|
|
ReplaceSinceWithUntil() uint32
|
2026-02-10 14:02:11 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-12 00:29:02 +03:00
|
|
|
type TimeDeltaCapturedState struct {
|
|
|
|
|
H byte
|
|
|
|
|
LastUnixtime uint32
|
|
|
|
|
LastDelta uint32
|
|
|
|
|
Payload []byte
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-11 01:46:25 +00:00
|
|
|
type TimeEvaluationReport struct {
|
2026-06-12 06:11:57 +00:00
|
|
|
TotalSpace int
|
|
|
|
|
Offset int // from payload start
|
|
|
|
|
RewindOffset int // steps to back from pos
|
|
|
|
|
ChangeSize int
|
2026-06-11 01:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-10 14:02:11 +00:00
|
|
|
type ValueCompressor interface {
|
2026-06-11 01:46:25 +00:00
|
|
|
// (tmp, value)
|
|
|
|
|
Evaluate([]byte, float64) ValueEvaluationReport
|
2026-06-12 06:11:57 +00:00
|
|
|
// (rewindOffset, change, value, delta)
|
2026-06-11 14:27:38 +00:00
|
|
|
Append(int, []byte, float64, uint64)
|
|
|
|
|
Size() int
|
2026-06-12 14:21:14 +00:00
|
|
|
StoredSize() int
|
2026-06-07 21:27:18 +03:00
|
|
|
//Chunks() [][]byte
|
|
|
|
|
//DeleteLast()
|
2026-06-12 06:11:57 +00:00
|
|
|
CaptureState()
|
2026-06-13 07:13:03 +00:00
|
|
|
ForgetCapturedState()
|
2026-06-12 06:11:57 +00:00
|
|
|
// (offset) => payload
|
|
|
|
|
Tail(int) []byte
|
2026-05-31 20:01:28 +00:00
|
|
|
// fracDigits
|
2026-06-12 06:11:57 +00:00
|
|
|
CreateDecompressor(MetricType, byte) ValueDecompressor
|
2026-06-09 08:16:16 +03:00
|
|
|
//Payload() []byte // для снапшота
|
2026-06-11 01:46:25 +00:00
|
|
|
//Offset() int
|
2026-06-12 06:11:57 +00:00
|
|
|
ReplaceBuffer([]byte)
|
2026-06-12 14:21:14 +00:00
|
|
|
WriteStoredTo(io.Writer) error
|
2026-06-09 08:16:16 +03:00
|
|
|
LastValue() float64
|
2026-02-10 14:02:11 +00:00
|
|
|
}
|
|
|
|
|
|
2026-06-12 00:29:02 +03:00
|
|
|
type ValueDeltaCapturedState struct {
|
|
|
|
|
H byte
|
|
|
|
|
LastDelta uint64
|
|
|
|
|
Payload []byte
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-11 01:46:25 +00:00
|
|
|
type ValueEvaluationReport struct {
|
2026-06-12 06:11:57 +00:00
|
|
|
TotalSpace int
|
|
|
|
|
Offset int // from payload start
|
|
|
|
|
RewindOffset int // steps to back from pos
|
|
|
|
|
ChangeSize int
|
|
|
|
|
Delta uint64
|
2026-06-11 01:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-10 14:02:11 +00:00
|
|
|
type TimestampDecompressor interface {
|
|
|
|
|
NextValue() (uint32, bool)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ValueDecompressor interface {
|
|
|
|
|
NextValue() (float64, bool)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AbortCode int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
// Fatal errors
|
|
|
|
|
WrongPrevPageNo AbortCode = 1
|
|
|
|
|
WriteToAtreeFailed AbortCode = 2
|
|
|
|
|
MaxAtreeSizeExceeded AbortCode = 3
|
|
|
|
|
FailedWriteToTxLog AbortCode = 4
|
|
|
|
|
ReferenceCountBug AbortCode = 5
|
|
|
|
|
WrongResultCodeBug AbortCode = 6
|
|
|
|
|
RemoveREDOFileFailed AbortCode = 7
|
|
|
|
|
FailedAtreeRequest AbortCode = 8
|
2026-05-31 20:01:28 +00:00
|
|
|
FailedGetPageNumber AbortCode = 9
|
2026-02-10 14:02:11 +00:00
|
|
|
UnknownTxLogRecordTypeBug AbortCode = 11
|
|
|
|
|
HasTimestampNoValueBug AbortCode = 12
|
|
|
|
|
NoMetricBug AbortCode = 13
|
|
|
|
|
NoLockEntryBug AbortCode = 14
|
|
|
|
|
NoXLockBug AbortCode = 15
|
|
|
|
|
MetricAddedBug AbortCode = 16
|
|
|
|
|
NoRLockBug AbortCode = 17
|
|
|
|
|
XLockBug AbortCode = 18
|
|
|
|
|
FailedFreeListSerialize AbortCode = 19
|
|
|
|
|
UnknownWorkerQueueItemBug AbortCode = 20
|
|
|
|
|
UnknownMetricWaitQueueItemBug AbortCode = 21
|
2026-05-31 20:01:28 +00:00
|
|
|
RepeatableLock AbortCode = 22
|
2026-06-05 19:43:01 +00:00
|
|
|
NoSpaceOnIndexPage AbortCode = 23
|
2026-06-09 08:16:16 +03:00
|
|
|
|
|
|
|
|
WriteSnapshotFailed AbortCode = 24
|
2026-02-10 14:02:11 +00:00
|
|
|
//
|
|
|
|
|
GetRecoveryRecipeFailed AbortCode = 26
|
|
|
|
|
LoadSnapshotFailed AbortCode = 27
|
|
|
|
|
ReplayChangesFailed AbortCode = 28
|
|
|
|
|
CreateChangesWriterFailed AbortCode = 29
|
|
|
|
|
RemoveRecipeFileFailed AbortCode = 30
|
|
|
|
|
DumpSnapshotFailed AbortCode = 31
|
|
|
|
|
SearchREDOFilesFailed AbortCode = 32
|
|
|
|
|
ReplayREDOFileFailed AbortCode = 33
|
|
|
|
|
DeletePrevChangesFileFailed AbortCode = 34
|
|
|
|
|
DeletePrevSnapshotFileFailed AbortCode = 35
|
2026-06-09 08:16:16 +03:00
|
|
|
|
|
|
|
|
MetricNotFoundDuringReplay AbortCode = 36
|
2026-06-10 06:18:45 +03:00
|
|
|
|
|
|
|
|
WALReplayFailed AbortCode = 37
|
2026-02-10 14:02:11 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func Abort(code AbortCode, err error) {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
os.Exit(int(code))
|
|
|
|
|
}
|
2026-06-13 22:43:17 +00:00
|
|
|
|
|
|
|
|
func GetIndexFilePath(dir string, databaseName string) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.index", databaseName))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetDataFilePath(dir string, databaseName string) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.data", databaseName))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetWALFilePath(dir string, databaseName string, snapshotNumber int) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.wal_%d", databaseName, snapshotNumber))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetSnapshotFilePath(dir string, databaseName string, snapshotNumber int) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.snapshot_%d", databaseName, snapshotNumber))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetIndexFreeListFilePath(dir string, databaseName string) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.index_free", databaseName))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GetDataFreeListFilePath(dir string, databaseName string) string {
|
|
|
|
|
return filepath.Join(dir, fmt.Sprintf("%s.data_free", databaseName))
|
|
|
|
|
}
|