~emersion/drmdb

e08b971c54320a0b44560fcc1138acf7587ab42b — Simon Ser 9 days ago f5007b7
Cache DB entries in memory with a ring buffer
3 files changed, 58 insertions(+), 12 deletions(-)

M database/db.go
M database/fs.go
M server.go
M database/db.go => database/db.go +55 -4
@@ 4,25 4,76 @@ import (
	"git.sr.ht/~emersion/drmdb/drmtree"
)

const cacheSize = 1000

type cacheEntry struct {
	key  string
	node *drmtree.Node
}

type DB struct {
	cache   []cacheEntry   // ring buffer
	indexes map[string]int // key → cache index
	cur     int
}

func Open() (*DB, error) {
	return &DB{}, initDB()
	if err := initDB(); err != nil {
		return nil, err
	}
	return &DB{
		cache:   make([]cacheEntry, cacheSize),
		indexes: make(map[string]int, cacheSize),
	}, nil
}

func (db *DB) storeCache(k string, n *drmtree.Node) {
	prev := db.cache[db.cur]
	delete(db.indexes, prev.key)
	db.cache[db.cur] = cacheEntry{key: k, node: n}
	db.indexes[k] = db.cur
	db.cur = (db.cur + 1) % len(db.cache)
}

func (db *DB) loadCache(k string) *drmtree.Node {
	i, ok := db.indexes[k]
	if !ok {
		return nil
	}
	return db.cache[i].node
}

func (db *DB) Store(n *drmtree.Node) (string, error) {
	return store(n)
	k, err := store(n)
	if err == nil {
		db.storeCache(k, n)
	}
	return k, err
}

func (db *DB) Load(k string) (*drmtree.Node, error) {
	return load(k)
	if n := db.loadCache(k); n != nil {
		return n, nil
	}
	n, err := load(k)
	if err == nil {
		db.storeCache(k, n)
	}
	return n, err
}

func (db *DB) Walk(fn func(k string, n *drmtree.Node) error) error {
	return walk(fn)
	return walk(func(k string) error {
		n, err := db.Load(k)
		if err != nil {
			return err
		}
		return fn(k, n)
	})
}

func (db *DB) Close() error {
	db.cache = nil
	db.indexes = nil
	return nil
}

M database/fs.go => database/fs.go +2 -7
@@ 99,7 99,7 @@ func load(k string) (*drmtree.Node, error) {
	return &n, f.Close()
}

func walk(fn func(k string, n *drmtree.Node) error) error {
func walk(fn func(k string) error) error {
	files, err := ioutil.ReadDir(Dir)
	if err != nil {
		return err


@@ 111,12 111,7 @@ func walk(fn func(k string, n *drmtree.Node) error) error {
		}
		k := strings.TrimSuffix(fi.Name(), ".json")

		n, err := load(k)
		if err != nil {
			return err
		}

		if err := fn(k, n); err == ErrStop {
		if err := fn(k); err == ErrStop {
			return nil
		} else if err != nil {
			return err

M server.go => server.go +1 -1
@@ 76,7 76,7 @@ func New() *echo.Echo {

	e.GET("/", func(c echo.Context) error {
		data := struct {
			Host string
			Host         string
			NumSnapshots int
			NumDevices   int
			NumDrivers   int