wp
This commit is contained in:
@@ -6,39 +6,30 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gordenko.dev/dima/qb"
|
||||
"gordenko.dev/dima/qb/atree"
|
||||
"gordenko.dev/dima/qb/inbox"
|
||||
"gordenko.dev/dima/qb/recovery"
|
||||
"gordenko.dev/dima/qb/storage"
|
||||
"gordenko.dev/dima/qb/worker"
|
||||
)
|
||||
|
||||
func JoinSnapshotFileName(dir string, snapshotNumber int) string {
|
||||
return filepath.Join(dir, fmt.Sprintf("%d.snapshot", snapshotNumber))
|
||||
}
|
||||
|
||||
func JoinWALFileName(dir string, snapshotNumber int) string {
|
||||
return filepath.Join(dir, fmt.Sprintf("%d.wal", snapshotNumber))
|
||||
}
|
||||
|
||||
// type metricLockEntry struct {
|
||||
// XLock bool
|
||||
// RLocks int
|
||||
// WaitQueue []any
|
||||
// }
|
||||
//metricLockEntries map[uint32]*metricLockEntry
|
||||
|
||||
type Database struct {
|
||||
mutex sync.Mutex
|
||||
worker *Worker
|
||||
//metricLockEntries map[uint32]*metricLockEntry
|
||||
//dataFreeList *freelist.FreeList
|
||||
//indexFreeList *freelist.FreeList
|
||||
mutex sync.Mutex
|
||||
dir string
|
||||
databaseName string
|
||||
workerInbox *inbox.Inbox
|
||||
worker *worker.Worker
|
||||
storage *storage.Writer
|
||||
atree *atree.Atree
|
||||
tcpPort int
|
||||
logfile *os.File
|
||||
logger *log.Logger
|
||||
@@ -50,7 +41,6 @@ type Options struct {
|
||||
TCPPort int
|
||||
Dir string
|
||||
DatabaseName string
|
||||
RedoDir string
|
||||
Logfile *os.File
|
||||
ExitCh chan struct{}
|
||||
WaitGroup *sync.WaitGroup
|
||||
@@ -66,9 +56,6 @@ func New(opt Options) (_ *Database, err error) {
|
||||
if opt.DatabaseName == "" {
|
||||
return nil, errors.New("DatabaseName option is required")
|
||||
}
|
||||
if opt.RedoDir == "" {
|
||||
return nil, errors.New("RedoDir option is required")
|
||||
}
|
||||
if opt.Logfile == nil {
|
||||
return nil, errors.New("Logfile option is required")
|
||||
}
|
||||
@@ -79,40 +66,7 @@ func New(opt Options) (_ *Database, err error) {
|
||||
return nil, errors.New("WaitGroup option is required")
|
||||
}
|
||||
|
||||
// deltaFreeListFile, err := os.OpenFile(
|
||||
// filepath.Join(opt.Dir, opt.DatabaseName+".deltafree"),
|
||||
// os.O_RDWR|os.O_CREATE,
|
||||
// 0666,
|
||||
// )
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// dataFreeList, err := freelist.New(freelist.Options{
|
||||
// PageSize: 2048,
|
||||
// BaseFilePath: filepath.Join(opt.Dir, opt.DatabaseName+".free_data"),
|
||||
// DeltaFilePath: filepath.Join(opt.Dir, opt.DatabaseName+".free_data_delta"),
|
||||
// })
|
||||
|
||||
// indexFreeList, err := freelist.New(freelist.Options{
|
||||
// PageSize: 2048,
|
||||
// BaseFilePath: filepath.Join(opt.Dir, opt.DatabaseName+".free_index"),
|
||||
// DeltaFilePath: filepath.Join(opt.Dir, opt.DatabaseName+".free_index_delta"),
|
||||
// })
|
||||
|
||||
worker := NewWorker(WorkerOptions{
|
||||
//
|
||||
Metrics: make(map[uint32]*_metric),
|
||||
Dir: opt.Dir,
|
||||
SaveToStorage: func(in any) {
|
||||
fmt.Println("save to storage")
|
||||
},
|
||||
ExitCh: opt.ExitCh,
|
||||
WaitGroup: opt.WaitGroup,
|
||||
})
|
||||
|
||||
s := &Database{
|
||||
worker: worker,
|
||||
dir: opt.Dir,
|
||||
databaseName: opt.DatabaseName,
|
||||
//metricLockEntries: make(map[uint32]*metricLockEntry),
|
||||
@@ -124,6 +78,42 @@ func New(opt Options) (_ *Database, err error) {
|
||||
exitCh: opt.ExitCh,
|
||||
waitGroup: opt.WaitGroup,
|
||||
}
|
||||
|
||||
recoveryReport, err := recovery.Recovery(s.dir, s.databaseName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
storageInbox := inbox.New()
|
||||
s.workerInbox = inbox.New()
|
||||
|
||||
s.storage, err = storage.NewWriter(storage.WriterOptions{
|
||||
Inbox: storageInbox,
|
||||
WorkerInbox: s.workerInbox,
|
||||
Dir: s.dir,
|
||||
DatabaseName: s.databaseName,
|
||||
WAL: recoveryReport.WAL,
|
||||
IndexFreeList: recoveryReport.IndexFreeList,
|
||||
DataFreeList: recoveryReport.DataFreeList,
|
||||
ExitCh: s.exitCh,
|
||||
WaitGroup: s.waitGroup,
|
||||
})
|
||||
if err != nil {
|
||||
qb.Abort(qb.CreateChangesWriterFailed, err)
|
||||
|
||||
}
|
||||
|
||||
s.worker = worker.NewWorker(worker.WorkerOptions{
|
||||
Inbox: s.workerInbox,
|
||||
StorageInbox: storageInbox,
|
||||
//Metrics: make(map[uint32]*_metric), FIX
|
||||
Dir: opt.Dir,
|
||||
// SaveToStorage: func(in any) {
|
||||
// fmt.Println("save to storage")
|
||||
// },
|
||||
ExitCh: opt.ExitCh,
|
||||
WaitGroup: opt.WaitGroup,
|
||||
})
|
||||
return s, nil
|
||||
}
|
||||
|
||||
@@ -133,19 +123,6 @@ func (s *Database) ListenAndServe() (err error) {
|
||||
return fmt.Errorf("net.Listen: %s; port=%d", err, s.tcpPort)
|
||||
}
|
||||
|
||||
s.storage, err = storage.NewWriter(storage.WriterOptions{
|
||||
Dir: s.dir,
|
||||
//LogNumber: logNumber,
|
||||
AppendToWorkerQueue: s.worker.AddJobToQueue,
|
||||
//FreeList: s.freeList,
|
||||
//Atree: s.atree,
|
||||
ExitCh: s.exitCh,
|
||||
WaitGroup: s.waitGroup,
|
||||
})
|
||||
if err != nil {
|
||||
qb.Abort(qb.CreateChangesWriterFailed, err)
|
||||
|
||||
}
|
||||
go s.storage.Run()
|
||||
|
||||
// s.atree, err = atree.New(atree.Options{
|
||||
@@ -177,50 +154,14 @@ func (s *Database) ListenAndServe() (err error) {
|
||||
|
||||
// зробити object?
|
||||
|
||||
func (s *Database) replayChanges(snapshotNumber int) (err error) {
|
||||
snapshot, err := readSnapshot(JoinSnapshotFileName(s.dir, snapshotNumber))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// func (s *Database) replayChanges(snapshotNumber int) (err error) {
|
||||
// snapshot, err := readSnapshot(JoinSnapshotFileName(s.dir, snapshotNumber))
|
||||
// if err != nil {
|
||||
// return
|
||||
// }
|
||||
|
||||
walReader, err := storage.NewWALReader(storage.WALReaderOptions{
|
||||
FileName: JoinWALFileName(s.dir, snapshotNumber),
|
||||
BufferSize: 8 * 1024 * 1024,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
walReplayer, err := NewWALReplayer(WALReplayerOptions{
|
||||
WALReader: walReader,
|
||||
Metrics: snapshot.Metrics,
|
||||
FreeIndexPages: snapshot.IndexPageNumbers,
|
||||
FreeDataPages: snapshot.DataPageNumbers,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = walReplayer.Replay()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = s.storage.WritePagesToAtree(walReplayer.IndexPages(), walReplayer.DataPages())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// FIX free pages sync
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Database) relayMetricsToMetrics(replayMetrics map[uint32]*ReplayMetric) {
|
||||
//for metricID, x := range replayMetrics {
|
||||
//s.metrics[metricID] = x.ToMetric() FIX
|
||||
//}
|
||||
}
|
||||
// return nil
|
||||
// }
|
||||
|
||||
//func (s *Database) verifySnapshot(fileName string) (_ bool, err error) {
|
||||
// file, err := os.Open(fileName)
|
||||
|
||||
Reference in New Issue
Block a user