This repository has been archived on 2022-07-30. You can view files and clone it, but cannot push or open issues/pull-requests.
mdb/database.go

104 lines
1.8 KiB
Go
Raw Normal View History

2022-07-26 12:02:32 +00:00
package mdb
import (
"net"
"os"
2022-07-26 12:10:41 +00:00
"path/filepath"
2022-07-26 12:02:32 +00:00
"sync"
"git.crumpington.com/private/mdb/kvstore"
2022-07-26 12:10:41 +00:00
"golang.org/x/sys/unix"
2022-07-26 12:02:32 +00:00
)
type Database struct {
root string
2022-07-26 12:10:41 +00:00
lock *os.File
2022-07-26 12:02:32 +00:00
kv *kvstore.KV
collections map[string]dbCollection
}
func NewPrimary(root string) *Database {
2022-07-26 12:10:41 +00:00
return newDB(root, true)
2022-07-26 12:02:32 +00:00
}
func NewSecondary(root string) *Database {
2022-07-26 12:10:41 +00:00
return newDB(root, false)
}
func newDB(root string, primary bool) *Database {
2022-07-26 12:02:32 +00:00
must(os.MkdirAll(root, 0700))
2022-07-26 12:10:41 +00:00
lockPath := filepath.Join(root, "lock")
// Acquire the lock.
lock, err := os.OpenFile(lockPath, os.O_RDWR|os.O_CREATE, 0600)
must(err)
must(unix.Flock(int(lock.Fd()), unix.LOCK_EX))
2022-07-26 12:02:32 +00:00
db := &Database{
root: root,
collections: map[string]dbCollection{},
2022-07-26 12:10:41 +00:00
lock: lock,
}
if primary {
db.kv = kvstore.NewPrimary(root)
} else {
db.kv = kvstore.NewSecondary(root, db.onStore, db.onDelete)
2022-07-26 12:02:32 +00:00
}
return db
}
func (db *Database) Start() {
wg := sync.WaitGroup{}
for _, c := range db.collections {
wg.Add(1)
go func(c dbCollection) {
defer wg.Done()
c.loadData()
}(c)
}
wg.Wait()
}
2022-07-29 19:36:42 +00:00
func (db *Database) MaxSeqNum() uint64 {
return db.kv.MaxSeqNum()
2022-07-26 12:02:32 +00:00
}
func (db *Database) Close() {
2022-07-26 12:13:41 +00:00
if db.kv != nil {
db.kv.Close()
db.kv = nil
}
if db.lock != nil {
db.lock.Close()
db.lock = nil
}
2022-07-26 12:02:32 +00:00
}
2022-07-26 12:13:41 +00:00
// ----------------------------------------------------------------------------
2022-07-26 12:02:32 +00:00
func (db *Database) onStore(collection string, id uint64, data []byte) {
c, ok := db.collections[collection]
if ok {
2022-07-30 02:25:12 +00:00
c.onStore(id, data)
2022-07-26 12:02:32 +00:00
}
}
func (db *Database) onDelete(collection string, id uint64) {
c, ok := db.collections[collection]
if ok {
2022-07-30 02:25:12 +00:00
c.onDelete(id)
2022-07-26 12:02:32 +00:00
}
}
// ----------------------------------------------------------------------------
func (db *Database) SyncSend(conn net.Conn) {
db.kv.SyncSend(conn)
}
func (db *Database) SyncRecv(conn net.Conn) {
db.kv.SyncRecv(conn)
}