This commit is contained in:
2026-06-14 23:12:03 +03:00
parent 181031a753
commit b32279deaf
35 changed files with 1395 additions and 1062 deletions

View File

@@ -11,6 +11,7 @@ import (
"gordenko.dev/dima/qb/atree"
"gordenko.dev/dima/qb/bufreader"
"gordenko.dev/dima/qb/proto"
"gordenko.dev/dima/qb/storage"
"gordenko.dev/dima/qb/transform"
"gordenko.dev/dima/qb/worker"
)
@@ -60,7 +61,7 @@ func (s *Database) handleTCPConn(conn net.Conn) {
}
func (s *Database) processRequest(conn net.Conn, r *bufreader.BufferedReader) (err error) {
fmt.Println("process request")
//fmt.Println("process request")
messageType, err := r.ReadByte()
if err != nil {
if err != io.EOF {
@@ -70,7 +71,7 @@ func (s *Database) processRequest(conn net.Conn, r *bufreader.BufferedReader) (e
}
}
fmt.Println("messageType:", messageType)
//fmt.Println("messageType:", messageType)
switch messageType {
case proto.TypeGetMetric:
@@ -111,7 +112,9 @@ func (s *Database) processRequest(conn net.Conn, r *bufreader.BufferedReader) (e
return fmt.Errorf("proto.ReadAppendMeasuresReq: %s", err)
}
//fmt.Println("append measure", req.MetricID, conn.RemoteAddr().String())
reply(conn, s.AppendMeasures(req))
if err = s.AppendMeasures(conn, req); err != nil {
return fmt.Errorf("AppendMeasures: %s", err)
}
case proto.TypeListInstantMeasures:
req, err := proto.ReadListInstantMeasuresReq(r)
@@ -195,7 +198,7 @@ func (s *Database) processRequest(conn net.Conn, r *bufreader.BufferedReader) (e
// API
func (s *Database) AddMetric(req proto.AddMetricReq) uint16 {
fmt.Println("database.AddMetric")
//fmt.Println("database.AddMetric")
// Валидация
if req.MetricID == 0 {
return proto.ErrEmptyMetricID
@@ -215,8 +218,10 @@ func (s *Database) AddMetric(req proto.AddMetricReq) uint16 {
fmt.Println("add job")
s.workerInbox.Push(worker.AddMetricReq{
MetricID: req.MetricID,
ResultCh: resultCh,
MetricID: req.MetricID,
MetricType: req.MetricType,
FracDigits: req.FracDigits,
ResultCh: resultCh,
})
fmt.Println("job added")
@@ -226,19 +231,13 @@ func (s *Database) AddMetric(req proto.AddMetricReq) uint16 {
switch resultCode {
case worker.Succeed:
fmt.Println("OK")
// s.storage.Append(storage.MetricAddRecord{
// MetricID: req.MetricID,
// MetricType: req.MetricType,
// FracDigits: req.FracDigits,
// })
//<-waitCh
case worker.MetricDuplicate:
fmt.Println("ErrDuplicate")
//fmt.Println("ErrDuplicate")
return proto.ErrDuplicate
default:
fmt.Println("ErrWrongResultCodeBug")
//fmt.Println("ErrWrongResultCodeBug")
qb.Abort(qb.WrongResultCodeBug, ErrWrongResultCodeBug)
}
return 0
@@ -325,8 +324,8 @@ type FilledPage struct {
ValuesSize uint16
}
func (s *Database) AppendMeasures(req proto.AppendMeasuresReq) uint16 {
resultCh := make(chan worker.AppendMeasuresResult, 1)
func (s *Database) AppendMeasures(conn io.Writer, req proto.AppendMeasuresReq) error {
resultCh := make(chan storage.MeasuresAppendResult, 1)
s.workerInbox.Push(worker.AppendMeasuresReq{
MetricID: req.MetricID,
@@ -337,32 +336,30 @@ func (s *Database) AppendMeasures(req proto.AppendMeasuresReq) uint16 {
result := <-resultCh
switch result.ResultCode {
case worker.CanAppend:
// report, err := s.atree.AppendDataPage(atree.AppendDataPageReq{})
// if err != nil {
// qb.Abort(qb.WriteToAtreeFailed, err)
// }
// _ = report
// if len(toAppendMeasures) > 0 {
// waitCh := s.storage.WriteAppendMeasures(
// storage.AppendedMeasures{
// MetricID: req.MetricID,
// Measures: toAppendMeasures,
// },
// false,
// )
// <-waitCh
// }
case worker.Succeed, worker.NonMonotonicValue, worker.ExpiredMeasure:
var errorCode byte
switch result.ResultCode {
case worker.NonMonotonicValue:
errorCode = proto.ErrNonMonotonicValue
case worker.ExpiredMeasure:
errorCode = proto.ErrExpiredMeasure
}
answer := []byte{
proto.RespValue,
0, 0, // written count
errorCode,
}
bin.PutIntAsUint16(answer[1:], result.WrittenCount)
_, err := conn.Write(answer)
if err != nil {
return err
}
case worker.NoMetric:
return proto.ErrNoMetric
reply(conn, proto.ErrNoMetric)
default:
qb.Abort(qb.WrongResultCodeBug, ErrWrongResultCodeBug)
}
return 0
return nil
}
func (s *Database) DeleteMeasures(req proto.DeleteMeasuresReq) uint16 {
@@ -380,25 +377,25 @@ func (s *Database) DeleteMeasures(req proto.DeleteMeasuresReq) uint16 {
case worker.NoMeasuresToDelete:
// ok
case worker.DeleteFromAtreeNotNeeded:
// регистрирую удаление в TransactionLog
// s.storage.Append(storage.MeasuresDeleteRecord{
// MetricID: req.MetricID,
// })
//<-waitCh
//case worker.DeleteFromAtreeNotNeeded:
// регистрирую удаление в TransactionLog
// s.storage.Append(storage.MeasuresDeleteRecord{
// MetricID: req.MetricID,
// })
//<-waitCh
case worker.DeleteFromAtreeRequired:
// собираю номера всех data и index страниц метрики (типа запись REDO лога).
// pageNumbers, err := s.atree.GetAllPages(req.MetricID)
// if err != nil {
// qb.Abort(qb.FailedAtreeRequest, err)
// }
// // регистрирую удаление в TransactionLog
// s.storage.Append(storage.DeletedMeasures{
// MetricID: req.MetricID,
// FreePageNumbers: pageNumbers,
// })
//<-waitCh
//case worker.DeleteFromAtreeRequired:
// собираю номера всех data и index страниц метрики (типа запись REDO лога).
// pageNumbers, err := s.atree.GetAllPages(req.MetricID)
// if err != nil {
// qb.Abort(qb.FailedAtreeRequest, err)
// }
// // регистрирую удаление в TransactionLog
// s.storage.Append(storage.DeletedMeasures{
// MetricID: req.MetricID,
// FreePageNumbers: pageNumbers,
// })
//<-waitCh
case worker.NoMetric:
return proto.ErrNoMetric
@@ -615,6 +612,7 @@ func (s *Database) fullScan(req fullScanReq) error {
switch result.ResultCode {
case worker.QueryDone:
fmt.Printf("query done")
req.ResponseWriter.Close()
case worker.UntilFound:

View File

@@ -9,7 +9,6 @@ import (
"sync"
"time"
"gordenko.dev/dima/qb"
"gordenko.dev/dima/qb/inbox"
"gordenko.dev/dima/qb/recovery"
"gordenko.dev/dima/qb/storage"
@@ -69,21 +68,20 @@ func New(opt Options) (_ *Database, err error) {
s := &Database{
dir: opt.Dir,
databaseName: opt.DatabaseName,
//metricLockEntries: make(map[uint32]*metricLockEntry),
//dataFreeList: dataFreeList,
//indexFreeList: indexFreeList,
tcpPort: opt.TCPPort,
logfile: opt.Logfile,
logger: log.New(opt.Logfile, "", log.LstdFlags),
exitCh: opt.ExitCh,
waitGroup: opt.WaitGroup,
tcpPort: opt.TCPPort,
logfile: opt.Logfile,
logger: log.New(opt.Logfile, "", log.LstdFlags),
exitCh: opt.ExitCh,
waitGroup: opt.WaitGroup,
}
recoveryReport, err := recovery.Recovery(s.dir, s.databaseName)
if err != nil {
return
return nil, fmt.Errorf("recovery.Recovery: %s", err)
}
fmt.Printf("%#v\n", recoveryReport)
storageInbox := inbox.New()
s.workerInbox = inbox.New()
@@ -99,18 +97,21 @@ func New(opt Options) (_ *Database, err error) {
WaitGroup: s.waitGroup,
})
if err != nil {
qb.Abort(qb.CreateChangesWriterFailed, err)
return nil, fmt.Errorf("storage.NewWriter: %s", err)
}
fmt.Println("storage created")
s.worker = worker.New(worker.Options{
Inbox: s.workerInbox,
StorageInbox: storageInbox,
//Metrics: make(map[uint32]*_metric), FIX
Dir: opt.Dir,
ExitCh: opt.ExitCh,
WaitGroup: opt.WaitGroup,
Inbox: s.workerInbox,
StorageInbox: storageInbox,
ReplayMetrics: recoveryReport.ReplayMetrics,
Dir: opt.Dir,
DatabaseName: opt.DatabaseName,
ExitCh: opt.ExitCh,
WaitGroup: opt.WaitGroup,
})
fmt.Println("worker created")
return s, nil
}
@@ -120,6 +121,7 @@ func (s *Database) ListenAndServe() (err error) {
return fmt.Errorf("net.Listen: %s; port=%d", err, s.tcpPort)
}
//s.waitGroup.Add(1)
go s.storage.Run()
// s.atree, err = atree.New(atree.Options{