cache tree traversal for both full and meta on disk as json

master
Bel LaPointe 2022-02-16 16:09:02 -07:00
parent 76d67cff7a
commit 9219e3656b
1 changed files with 57 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
@ -65,15 +66,68 @@ func (tree Tree) WithRoot(root string) Tree {
} }
func (tree Tree) GetRootMeta() (Branch, error) { func (tree Tree) GetRootMeta() (Branch, error) {
if meta, ok := tree.getCachedRootMeta(); ok {
return meta, nil
}
got, err := tree.getRoot(NewID(""), false, false) got, err := tree.getRoot(NewID(""), false, false)
if err != nil {
return Branch{}, err
}
tree.cacheRootMeta(got)
return got, err return got, err
} }
func (tree Tree) GetRoot() (Branch, error) { func (tree Tree) GetRoot() (Branch, error) {
if root, ok := tree.getCachedRoot(); ok {
return root, nil
}
got, err := tree.getRoot(NewID(""), true, false) got, err := tree.getRoot(NewID(""), true, false)
if err != nil {
return Branch{}, err
}
tree.cacheRoot(got)
return got, err return got, err
} }
func (tree Tree) getCachedRoot() (Branch, bool) {
return tree.getCachedFrom("root.json")
}
func (tree Tree) getCachedRootMeta() (Branch, bool) {
return tree.getCachedFrom("root_meta.json")
}
func (tree Tree) getCachedFrom(name string) (Branch, bool) {
b, err := ioutil.ReadFile(path.Join(tree.root, name))
if err != nil {
return Branch{}, false
}
var branch Branch
err = json.Unmarshal(b, &branch)
return branch, err == nil
}
func (tree Tree) cacheRoot(branch Branch) {
tree.cacheRootFrom("root.json", branch)
}
func (tree Tree) cacheRootMeta(branch Branch) {
tree.cacheRootFrom("root_meta.json", branch)
}
func (tree Tree) cacheRootFrom(name string, branch Branch) {
b, err := json.Marshal(branch)
if err != nil {
return
}
ensureAndWrite(path.Join(tree.root, name), b)
}
func (tree Tree) cacheClear() {
os.Remove(path.Join(path.Join(tree.root, "root.json")))
os.Remove(path.Join(path.Join(tree.root, "root_meta.json")))
}
func (tree Tree) getRoot(pid ID, withContent, withDeleted bool) (Branch, error) { func (tree Tree) getRoot(pid ID, withContent, withDeleted bool) (Branch, error) {
m := Branch{Branches: map[ID]Branch{}} m := Branch{Branches: map[ID]Branch{}}
entries, err := os.ReadDir(tree.root) entries, err := os.ReadDir(tree.root)
@ -121,6 +175,7 @@ func (tree Tree) toData(id ID) string {
} }
func (tree Tree) Put(id ID, input Leaf) error { func (tree Tree) Put(id ID, input Leaf) error {
tree.cacheClear()
if _, err := os.Stat(tree.toData(id)); os.IsNotExist(err) { if _, err := os.Stat(tree.toData(id)); os.IsNotExist(err) {
b, err := yaml.Marshal(Leaf{}) b, err := yaml.Marshal(Leaf{})
if err != nil { if err != nil {
@ -145,6 +200,7 @@ func (tree Tree) Put(id ID, input Leaf) error {
} }
func (tree Tree) Del(id ID) error { func (tree Tree) Del(id ID) error {
tree.cacheClear()
got, err := tree.Get(id) got, err := tree.Get(id)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
@ -160,6 +216,7 @@ func (tree Tree) Del(id ID) error {
} }
func (tree Tree) HardDel(id ID) error { func (tree Tree) HardDel(id ID) error {
tree.cacheClear()
os.RemoveAll(tree.toDir(id)) os.RemoveAll(tree.toDir(id))
return nil return nil
} }