This commit is contained in:
2026-06-15 01:20:30 +03:00
parent b32279deaf
commit 80309aab99
20 changed files with 149 additions and 40 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/database_linux

1
a Normal file

File diff suppressed because one or more lines are too long

1
b Normal file

File diff suppressed because one or more lines are too long

View File

@@ -209,6 +209,9 @@ func (s *Connection) AppendMeasures(req proto.AppendMeasuresReq) (result AppendM
if err != nil { if err != nil {
return return
} }
case proto.RespError:
err = s.onMaybeError()
return
default: default:
err = fmt.Errorf("unknown reponse code %d", code) err = fmt.Errorf("unknown reponse code %d", code)
return return

View File

@@ -9,6 +9,7 @@ import (
"sync" "sync"
"time" "time"
"gordenko.dev/dima/qb"
"gordenko.dev/dima/qb/inbox" "gordenko.dev/dima/qb/inbox"
"gordenko.dev/dima/qb/recovery" "gordenko.dev/dima/qb/recovery"
"gordenko.dev/dima/qb/storage" "gordenko.dev/dima/qb/storage"
@@ -85,6 +86,25 @@ func New(opt Options) (_ *Database, err error) {
storageInbox := inbox.New() storageInbox := inbox.New()
s.workerInbox = inbox.New() s.workerInbox = inbox.New()
// create separately, because needed for page cache
dataFile, err := os.OpenFile(
qb.GetDataFilePath(opt.Dir, opt.DatabaseName),
os.O_CREATE|os.O_RDWR,
0666,
)
if err != nil {
return nil, err
}
indexFile, err := os.OpenFile(
qb.GetIndexFilePath(opt.Dir, opt.DatabaseName),
os.O_CREATE|os.O_RDWR,
0666,
)
if err != nil {
return nil, err
}
s.storage, err = storage.NewWriter(storage.WriterOptions{ s.storage, err = storage.NewWriter(storage.WriterOptions{
Inbox: storageInbox, Inbox: storageInbox,
WorkerInbox: s.workerInbox, WorkerInbox: s.workerInbox,
@@ -93,6 +113,8 @@ func New(opt Options) (_ *Database, err error) {
WAL: recoveryReport.WAL, WAL: recoveryReport.WAL,
IndexFreeList: recoveryReport.IndexFreeList, IndexFreeList: recoveryReport.IndexFreeList,
DataFreeList: recoveryReport.DataFreeList, DataFreeList: recoveryReport.DataFreeList,
DataFile: dataFile,
IndexFile: indexFile,
ExitCh: s.exitCh, ExitCh: s.exitCh,
WaitGroup: s.waitGroup, WaitGroup: s.waitGroup,
}) })

Binary file not shown.

View File

@@ -162,7 +162,7 @@ func (s *TimeDeltaCompressor) Evaluate(tmp []byte, timestamp uint32) qb.TimeEval
RewindOffset: rewindOffset, RewindOffset: rewindOffset,
Offset: len(s.buf) - s.pos - rewindOffset, Offset: len(s.buf) - s.pos - rewindOffset,
ChangeSize: i, ChangeSize: i,
TotalSpace: s.pos - rewindOffset + i, TotalSpace: len(s.buf) - s.pos - rewindOffset + i,
} }
} }
@@ -279,6 +279,7 @@ func (s *TimeDeltaCompressor) WriteCommitedTo(w io.Writer) (err error) {
} }
func (s *TimeDeltaCompressor) ReplaceBuffer(newbuf []byte) { func (s *TimeDeltaCompressor) ReplaceBuffer(newbuf []byte) {
//fmt.Printf("time replace buffer: new size %d\n", len(newbuf))
s.buf = newbuf s.buf = newbuf
s.pos = len(s.buf) s.pos = len(s.buf)
s.lastUnixtime = 0 s.lastUnixtime = 0

View File

@@ -1,7 +1,6 @@
package enc package enc
import ( import (
"fmt"
"io" "io"
"log" "log"
"math" "math"
@@ -136,7 +135,7 @@ func (s *ValueDeltaCompressor) Evaluate(tmp []byte, value float64) qb.ValueEvalu
RewindOffset: rewindOffset, RewindOffset: rewindOffset,
Offset: s.pos - rewindOffset, Offset: s.pos - rewindOffset,
ChangeSize: i, ChangeSize: i,
TotalSpace: s.pos + i - rewindOffset, TotalSpace: s.pos - rewindOffset + i,
Delta: delta, Delta: delta,
} }
} }
@@ -147,6 +146,8 @@ func (s *ValueDeltaCompressor) Append(rewindOffset int, change []byte, value flo
// fmt.Printf("rewind offset: %d\n", rewindOffset) // fmt.Printf("rewind offset: %d\n", rewindOffset)
// fmt.Printf("change: % x\n", change) // fmt.Printf("change: % x\n", change)
// fmt.Printf("value: %v\n", value) // fmt.Printf("value: %v\n", value)
// fmt.Printf("bufsize: %d\n", len(s.buf))
// fmt.Printf("s.pos: %d\n", s.pos)
//fmt.Printf("delta: %d\n", delta) //fmt.Printf("delta: %d\n", delta)
if s.pos > 0 { if s.pos > 0 {
s.lastDelta = delta s.lastDelta = delta
@@ -242,6 +243,7 @@ func (s *ValueDeltaCompressor) WriteCommitedTo(w io.Writer) (err error) {
} }
func (s *ValueDeltaCompressor) ReplaceBuffer(newbuf []byte) { func (s *ValueDeltaCompressor) ReplaceBuffer(newbuf []byte) {
//fmt.Printf("value replace buffer: new size %d\n", len(newbuf))
s.buf = newbuf s.buf = newbuf
s.pos = 0 s.pos = 0
s.baseValue = 0 s.baseValue = 0
@@ -318,7 +320,7 @@ func (s *ValueDeltaDecompressor) RestoreFromEnd(buf []byte) {
} }
func (s *ValueDeltaDecompressor) RestoreFromState(state qb.ValueDeltaCapturedState) { func (s *ValueDeltaDecompressor) RestoreFromState(state qb.ValueDeltaCapturedState) {
fmt.Printf("%#v\n", state) //fmt.Printf("%#v\n", state)
s.buf = state.Payload s.buf = state.Payload
s.pos = len(s.buf) // first free s.pos = len(s.buf) // first free
if len(s.buf) > 0 { if len(s.buf) > 0 {

View File

@@ -324,7 +324,7 @@ func sendRequests(conn *client.Connection) {
result, err := conn.AppendMeasures(proto.AppendMeasuresReq{ result, err := conn.AppendMeasures(proto.AppendMeasuresReq{
MetricID: cumulativeMetricID, MetricID: cumulativeMetricID,
Measures: cumulativeMeasures[:1], Measures: cumulativeMeasures[:1000],
}) })
if err != nil { if err != nil {
log.Fatalf("conn.AppendMeasures: %s\n", err) log.Fatalf("conn.AppendMeasures: %s\n", err)

Binary file not shown.

2
go.mod
View File

@@ -5,5 +5,5 @@ go 1.24.2
require ( require (
gopkg.in/ini.v1 v1.67.1 gopkg.in/ini.v1 v1.67.1
gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb
gordenko.dev/dima/pretty v0.0.0-20221225212746-0c27d8c0ac69 gordenko.dev/dima/textutil v0.0.0-20221225052909-270513dcbbbf
) )

4
go.sum
View File

@@ -20,5 +20,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb h1:XBYZbK5Z+yfpKmSR2wuPLyW14ReCRSNdOlL5MWro8ns= gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb h1:XBYZbK5Z+yfpKmSR2wuPLyW14ReCRSNdOlL5MWro8ns=
gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb/go.mod h1:up64wpJp9xI+HqACtMDBIfPNUH6BYY/b3inKpUfrqDQ= gordenko.dev/dima/bin v0.0.0-20260612161453-4ee9be3474fb/go.mod h1:up64wpJp9xI+HqACtMDBIfPNUH6BYY/b3inKpUfrqDQ=
gordenko.dev/dima/pretty v0.0.0-20221225212746-0c27d8c0ac69 h1:nyJ3mzTQ46yUeMZCdLyYcs7B5JCS54c67v84miyhq2E= gordenko.dev/dima/textutil v0.0.0-20221225052909-270513dcbbbf h1:GCL/m736iGDy3LgOm6iuvkxlGhUEyjfP7zgwZRkTYOg=
gordenko.dev/dima/pretty v0.0.0-20221225212746-0c27d8c0ac69/go.mod h1:AxgKDktpqBVyIOhIcP+nlCpK+EsJyjN5kPdqyd8euVU= gordenko.dev/dima/textutil v0.0.0-20221225052909-270513dcbbbf/go.mod h1:M3e8S3N1USCMYmL6Q5uDQJaxfzBlWHnTX7rxCJQ6iJs=

View File

@@ -53,6 +53,7 @@ func (s *WALReader) NextPacket() (_ []any, _ bool, err error) {
} else { } else {
current, err = s.readPacket() current, err = s.readPacket()
if err != nil { if err != nil {
err = fmt.Errorf("readPacket: %s", err)
return return
} }
if current == nil { if current == nil {
@@ -61,6 +62,7 @@ func (s *WALReader) NextPacket() (_ []any, _ bool, err error) {
} }
s.next, err = s.readPacket() s.next, err = s.readPacket()
if err != nil { if err != nil {
err = fmt.Errorf("readPacket: %s", err)
return return
} }
return current, s.next == nil, nil return current, s.next == nil, nil
@@ -85,9 +87,12 @@ func (s *WALReader) readPacket() (_ []any, err error) {
} }
calculatedCRC := util.CalculateCRC32(body) calculatedCRC := util.CalculateCRC32(body)
if calculatedCRC != writtenCRC { if calculatedCRC != writtenCRC {
//fmt.Printf("bodySize: %d\n", bodySize)
//fmt.Printf("body: % x\n", body)
return nil, fmt.Errorf("written CRC %d != calculated CRC %d", return nil, fmt.Errorf("written CRC %d != calculated CRC %d",
writtenCRC, calculatedCRC) writtenCRC, calculatedCRC)
} }
//fmt.Println("SAME CRC")
return s.parseRecords(body) return s.parseRecords(body)
} }

View File

@@ -49,6 +49,7 @@ type PreparedData struct {
// ) // )
func (s *WritePreparer) Prepare(input []any) PreparedData { func (s *WritePreparer) Prepare(input []any) PreparedData {
s.w.Reset()
s.w.Write([]byte{ s.w.Write([]byte{
0, 0, 0, 0, 0, 0, 0, 0, 0, // size (max 9 byte) 0, 0, 0, 0, 0, 0, 0, 0, 0, // size (max 9 byte)
}) })
@@ -249,7 +250,7 @@ func (s *WritePreparer) Reset() {
} }
func getIndexRecords(buf []byte, count int) (list []IndexRecord) { func getIndexRecords(buf []byte, count int) (list []IndexRecord) {
fmt.Printf("ipage: % x\n", buf) //fmt.Printf("ipage: % x\n", buf)
i := 0 i := 0
for range count { for range count {
var rec IndexRecord var rec IndexRecord
@@ -268,5 +269,11 @@ func finalizePacket(w *bytes.Buffer, checksum uint32) []byte {
// cut empty bytes at start // cut empty bytes at start
start := 9 - bin.CountVarSize(bodySize) start := 9 - bin.CountVarSize(bodySize)
bin.PutVarSize(packet[start:], bodySize) bin.PutVarSize(packet[start:], bodySize)
fmt.Printf("checksum: %d\n", checksum)
fmt.Printf("bodySize: %d\n", bodySize)
//fmt.Printf("start: %d\n", start)
fmt.Printf("body: % x\n", packet[9:len(packet)-4])
return packet[start:] return packet[start:]
} }

View File

@@ -89,6 +89,8 @@ type WriterOptions struct {
WAL string WAL string
DataFreeList *freelist.FreeList DataFreeList *freelist.FreeList
IndexFreeList *freelist.FreeList IndexFreeList *freelist.FreeList
DataFile *os.File
IndexFile *os.File
//Atree *atree.Atree //Atree *atree.Atree
ExitCh chan struct{} ExitCh chan struct{}
WaitGroup *sync.WaitGroup WaitGroup *sync.WaitGroup
@@ -122,9 +124,12 @@ func NewWriter(opt WriterOptions) (*Writer, error) {
if opt.IndexFreeList == nil { if opt.IndexFreeList == nil {
return nil, errors.New("IndexFreeList option is required") return nil, errors.New("IndexFreeList option is required")
} }
// if opt.Atree == nil { if opt.DataFile == nil {
// return nil, errors.New("Atree option is required") return nil, errors.New("DataFile option is required")
// } }
if opt.IndexFile == nil {
return nil, errors.New("IndexFile option is required")
}
if opt.ExitCh == nil { if opt.ExitCh == nil {
return nil, errors.New("ExitCh option is required") return nil, errors.New("ExitCh option is required")
} }
@@ -162,6 +167,8 @@ func NewWriter(opt WriterOptions) (*Writer, error) {
workerInbox: opt.WorkerInbox, workerInbox: opt.WorkerInbox,
dir: opt.Dir, dir: opt.Dir,
databaseName: opt.DatabaseName, databaseName: opt.DatabaseName,
dataFile: opt.DataFile,
indexFile: opt.IndexFile,
dataFreeList: opt.DataFreeList, dataFreeList: opt.DataFreeList,
indexFreeList: opt.IndexFreeList, indexFreeList: opt.IndexFreeList,
writePreparer: writePreparer, writePreparer: writePreparer,
@@ -184,6 +191,7 @@ func NewWriter(opt WriterOptions) (*Writer, error) {
return nil, err return nil, err
} }
} }
return s, nil return s, nil
} }
@@ -220,28 +228,33 @@ func (s *Writer) packAndWrite() (err error) {
prepared := s.writePreparer.Prepare(input) prepared := s.writePreparer.Prepare(input)
//fmt.Printf("prepared: %#v\n", prepared) //fmt.Printf("prepared: %#v\n", prepared)
fmt.Println("prepared")
// 3. Пишу на диск WAL (append) // 3. Пишу на диск WAL (append)
n, err := s.wal.Write(prepared.Packet) n, err := s.wal.Write(prepared.Packet)
if err != nil { if err != nil {
return return
} }
//fmt.Printf("written to wal: % x\n", prepared.Packet)
if n != len(prepared.Packet) { if n != len(prepared.Packet) {
return fmt.Errorf("written %d != packet size %d", n, len(prepared.Packet)) return fmt.Errorf("written %d != packet size %d", n, len(prepared.Packet))
} }
if err = s.wal.Sync(); err != nil { if err = s.wal.Sync(); err != nil {
return return
} }
fmt.Println("synced to wal")
// 4. Пишу в atree сторінки // 4. Пишу в atree сторінки
err = WriteDataPages(s.dataFile, prepared.WriteToData) err = WriteDataPages(s.dataFile, prepared.WriteToData)
if err != nil { if err != nil {
return return
} }
fmt.Println("written to data")
err = WriteIndexPages(s.indexFile, prepared.WriteToIndex) err = WriteIndexPages(s.indexFile, prepared.WriteToIndex)
if err != nil { if err != nil {
return return
} }
fmt.Println("written to index")
// 6. відправляю input - worker-у // 6. відправляю input - worker-у
@@ -300,6 +313,7 @@ func (s *Writer) packAndWrite() (err error) {
s.workerInbox.Push(Changes{ s.workerInbox.Push(Changes{
Commits: prepared.Commits, Commits: prepared.Commits,
}) })
fmt.Println("pushed commits")
} }
return nil return nil
} }
@@ -345,6 +359,9 @@ type PageToWrite struct {
func WriteDataPages(file *os.File, pages []PageToWrite) (err error) { func WriteDataPages(file *os.File, pages []PageToWrite) (err error) {
for _, p := range pages { for _, p := range pages {
fmt.Println("pageNo: %d\n", p.PageNo)
}
for _, p := range pages {
if len(p.Content) != DataPageSize { if len(p.Content) != DataPageSize {
return fmt.Errorf("wrong data page size: %d", len(p.Content)) return fmt.Errorf("wrong data page size: %d", len(p.Content))
} }
@@ -354,7 +371,7 @@ func WriteDataPages(file *os.File, pages []PageToWrite) (err error) {
) )
n, err = file.WriteAt(p.Content, int64(off)) n, err = file.WriteAt(p.Content, int64(off))
if err != nil { if err != nil {
return return fmt.Errorf("file.WriteAt: %s; off=%d", err, off)
} }
if n != DataPageSize { if n != DataPageSize {
return fmt.Errorf("write %d instead of %d", n, DataPageSize) return fmt.Errorf("write %d instead of %d", n, DataPageSize)

Binary file not shown.

View File

@@ -1,7 +1,6 @@
package transform package transform
import ( import (
"fmt"
"io" "io"
bin "gordenko.dev/dima/bin/little" bin "gordenko.dev/dima/bin/little"
@@ -102,7 +101,7 @@ type CumulativeMeasureWriter struct {
} }
func NewCumulativeMeasureWriter(dst io.Writer, since uint32) *CumulativeMeasureWriter { func NewCumulativeMeasureWriter(dst io.Writer, since uint32) *CumulativeMeasureWriter {
fmt.Println("NewCumulativeMeasureWriter") //fmt.Println("NewCumulativeMeasureWriter")
// 20 - это timestamp, value, total // 20 - это timestamp, value, total
return &CumulativeMeasureWriter{ return &CumulativeMeasureWriter{
arr: make([]byte, 20), arr: make([]byte, 20),
@@ -128,13 +127,13 @@ func (s *CumulativeMeasureWriter) feed(timestamp uint32, value float64, isBuffer
s.responder.AppendRecord(s.arr) s.responder.AppendRecord(s.arr)
} }
} }
fmt.Println("feed:", timestamp, value, isBuffer) //fmt.Println("feed:", timestamp, value, isBuffer)
s.endTimestamp = timestamp s.endTimestamp = timestamp
s.endValue = value s.endValue = value
} }
func (s *CumulativeMeasureWriter) pack(total float64) { func (s *CumulativeMeasureWriter) pack(total float64) {
fmt.Println("PACK") //fmt.Println("PACK")
bin.PutUint32(s.arr[0:], s.endTimestamp) bin.PutUint32(s.arr[0:], s.endTimestamp)
bin.PutFloat64(s.arr[4:], s.endValue) bin.PutFloat64(s.arr[4:], s.endValue)
bin.PutFloat64(s.arr[12:], total) bin.PutFloat64(s.arr[12:], total)

View File

@@ -38,13 +38,13 @@ func NewChunkedResponder(dst io.Writer) *ChunkedResponder {
func (s *ChunkedResponder) BufferRecord(rec []byte) { func (s *ChunkedResponder) BufferRecord(rec []byte) {
s.buf.Write(rec) s.buf.Write(rec)
s.recordsQty++ s.recordsQty++
fmt.Println("BufferRecord", s.recordsQty) //fmt.Println("BufferRecord", s.recordsQty)
} }
func (s *ChunkedResponder) AppendRecord(rec []byte) error { func (s *ChunkedResponder) AppendRecord(rec []byte) error {
s.buf.Write(rec) s.buf.Write(rec)
s.recordsQty++ s.recordsQty++
fmt.Println("AppendRecord", s.recordsQty) //fmt.Println("AppendRecord", s.recordsQty)
if s.buf.Len() < 1500 { if s.buf.Len() < 1500 {
return nil return nil
@@ -63,7 +63,7 @@ func (s *ChunkedResponder) AppendRecord(rec []byte) error {
} }
func (s *ChunkedResponder) Flush() error { func (s *ChunkedResponder) Flush() error {
fmt.Println("Flush", s.recordsQty) //fmt.Println("Flush", s.recordsQty)
if s.recordsQty > 0 { if s.recordsQty > 0 {
if err := s.sendBuffered(); err != nil { if err := s.sendBuffered(); err != nil {
return err return err
@@ -78,14 +78,14 @@ func (s *ChunkedResponder) Flush() error {
} }
func (s *ChunkedResponder) sendBuffered() (err error) { func (s *ChunkedResponder) sendBuffered() (err error) {
fmt.Println("sendBuffered", s.recordsQty) //fmt.Println("sendBuffered", s.recordsQty)
msg := s.buf.Bytes() msg := s.buf.Bytes()
bin.PutUint32(msg[1:], uint32(s.recordsQty)) bin.PutUint32(msg[1:], uint32(s.recordsQty))
fmt.Printf("put uint16: %d\n", msg[:3]) //fmt.Printf("put uint16: %d\n", msg[:3])
fmt.Printf("send %d records\n", s.recordsQty) //fmt.Printf("send %d records\n", s.recordsQty)
fmt.Printf("send buffered: %d, qty: %d\n", msg, s.recordsQty) //fmt.Printf("send buffered: %d, qty: %d\n", msg, s.recordsQty)
n, err := s.dst.Write(msg) n, err := s.dst.Write(msg)
if err != nil { if err != nil {

View File

@@ -1,8 +1,14 @@
package util package util
import ( import (
"bytes"
"fmt"
"hash/crc32" "hash/crc32"
"io"
"os"
"testing" "testing"
"gordenko.dev/dima/textutil"
) )
var page = make([]byte, 4096) var page = make([]byte, 4096)
@@ -19,3 +25,38 @@ func BenchmarkCRC32IEEE(b *testing.B) {
crc32.Checksum(page, ieeeTable) crc32.Checksum(page, ieeeTable)
} }
} }
func TestHash(t *testing.T) {
raw, err := os.ReadFile("../b")
if err != nil {
t.Fatal(err)
}
buf, err := textutil.ParseHex(string(raw))
if err != nil {
t.Fatal(err)
}
fmt.Println(CalculateCRC32(buf))
w := bytes.NewBuffer(nil)
w.Write([]byte{
0, 0, 0, 0, 0, 0, 0, 0, 0, // size (max 9 byte)
})
hasher := NewHasher()
multi := io.MultiWriter(w, hasher)
i := 0
for i < len(buf) {
end := i + 50
if end >= len(buf) {
end = len(buf)
}
multi.Write(buf[i:end])
i += 50
}
fmt.Println(hasher.Sum32())
}

View File

@@ -77,6 +77,7 @@ func (s *Metric) OnMeasuresDeleteCommited(rec storage.MeasuresDeleteCommited) {
} }
func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox *inbox.Inbox) { func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox *inbox.Inbox) {
if s.capturedState != nil { if s.capturedState != nil {
s.WaitQueue = append(s.WaitQueue, req) s.WaitQueue = append(s.WaitQueue, req)
} }
@@ -118,9 +119,9 @@ func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox
} }
tReport := timestamps.Evaluate(tmp[:7], measure.Timestamp) tReport := timestamps.Evaluate(tmp[:7], measure.Timestamp)
fmt.Printf("tReport: %#v\n", tReport) //fmt.Printf("tReport: %#v\n", tReport)
vReport := values.Evaluate(tmp[7:], measure.Value) vReport := values.Evaluate(tmp[7:], measure.Value)
fmt.Printf("vReport: %#v\n", vReport) //fmt.Printf("vReport: %#v\n", vReport)
totalRequiredSpace := tReport.TotalSpace + vReport.TotalSpace totalRequiredSpace := tReport.TotalSpace + vReport.TotalSpace
@@ -136,6 +137,7 @@ func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox
valuesRewindOffset = vReport.RewindOffset valuesRewindOffset = vReport.RewindOffset
} }
} else { } else {
fmt.Println("PAGE FILLED")
// сторінка заповнена // сторінка заповнена
since := s.timestamps.ReplaceSinceWithUntil() since := s.timestamps.ReplaceSinceWithUntil()
@@ -161,6 +163,11 @@ func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox
// renew // renew
s.buffer = buf s.buffer = buf
tReport = timestamps.Evaluate(tmp[:7], measure.Timestamp)
//fmt.Printf("tReport: %#v\n", tReport)
vReport = values.Evaluate(tmp[7:], measure.Value)
//fmt.Printf("vReport: %#v\n", vReport)
timestamps.Append(tReport.RewindOffset, tmp[:tReport.ChangeSize], measure.Timestamp) timestamps.Append(tReport.RewindOffset, tmp[:tReport.ChangeSize], measure.Timestamp)
values.Append(vReport.RewindOffset, tmp[7:7+vReport.ChangeSize], measure.Value, vReport.Delta) values.Append(vReport.RewindOffset, tmp[7:7+vReport.ChangeSize], measure.Value, vReport.Delta)
} }
@@ -181,6 +188,7 @@ func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox
// скопіювати. Причому можна скопіювати зрізи chunks // скопіювати. Причому можна скопіювати зрізи chunks
if len(pages) > 0 { if len(pages) > 0 {
fmt.Println("push pages")
// пишу в storage довгим шляхом через redo файл і запис в data файл // пишу в storage довгим шляхом через redo файл і запис в data файл
storageInbox.Push(storage.MeasuresAppendWithGrow{ storageInbox.Push(storage.MeasuresAppendWithGrow{
MetricID: req.MetricID, MetricID: req.MetricID,
@@ -198,6 +206,7 @@ func (s *Metric) AppendMeasures(req AppendMeasuresReq, tmp []byte, storageInbox
ResultCh: req.ResultCh, ResultCh: req.ResultCh,
}) })
} else { } else {
fmt.Println("push simple")
// короткий шлях - запис лише в storage // короткий шлях - запис лише в storage
storageInbox.Push(storage.MeasuresAppend{ storageInbox.Push(storage.MeasuresAppend{
MetricID: req.MetricID, MetricID: req.MetricID,
@@ -329,27 +338,27 @@ func (s *Metric) StartFullScan(req FullScanReq) {
if done { if done {
break break
} }
fmt.Println("ts:", timestamp) //fmt.Println("ts:", timestamp)
value, done := valueDecompressor.NextValue() value, done := valueDecompressor.NextValue()
if done { if done {
qb.Abort(qb.HasTimestampNoValueBug, ErrNoValueBug) qb.Abort(qb.HasTimestampNoValueBug, ErrNoValueBug)
} }
fmt.Println("value:", value) //fmt.Println("value:", value)
req.ResponseWriter.FeedNoSend(timestamp, value) req.ResponseWriter.FeedNoSend(timestamp, value)
} }
if s.lastPageNo > 0 { // if s.lastPageNo > 0 {
req.ResultCh <- FullScanResult{ // req.ResultCh <- FullScanResult{
ResultCode: UntilFound, // ResultCode: UntilFound,
LastPageNo: s.lastPageNo, // LastPageNo: s.lastPageNo,
FracDigits: s.fracDigits, // FracDigits: s.fracDigits,
} // }
s.rLocks++ // s.rLocks++
} else { // } else {
req.ResultCh <- FullScanResult{ req.ResultCh <- FullScanResult{
ResultCode: QueryDone, ResultCode: QueryDone,
} }
} //}
} }
// індекси // індекси