diff --git a/server/tree.go b/server/tree.go index 4808885..299f861 100644 --- a/server/tree.go +++ b/server/tree.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "io/ioutil" "os" "path" @@ -65,15 +66,68 @@ func (tree Tree) WithRoot(root string) Tree { } func (tree Tree) GetRootMeta() (Branch, error) { + if meta, ok := tree.getCachedRootMeta(); ok { + return meta, nil + } got, err := tree.getRoot(NewID(""), false, false) + if err != nil { + return Branch{}, err + } + tree.cacheRootMeta(got) return got, err } func (tree Tree) GetRoot() (Branch, error) { + if root, ok := tree.getCachedRoot(); ok { + return root, nil + } got, err := tree.getRoot(NewID(""), true, false) + if err != nil { + return Branch{}, err + } + tree.cacheRoot(got) 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) { m := Branch{Branches: map[ID]Branch{}} 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 { + tree.cacheClear() if _, err := os.Stat(tree.toData(id)); os.IsNotExist(err) { b, err := yaml.Marshal(Leaf{}) if err != nil { @@ -145,6 +200,7 @@ func (tree Tree) Put(id ID, input Leaf) error { } func (tree Tree) Del(id ID) error { + tree.cacheClear() got, err := tree.Get(id) if os.IsNotExist(err) { return nil @@ -160,6 +216,7 @@ func (tree Tree) Del(id ID) error { } func (tree Tree) HardDel(id ID) error { + tree.cacheClear() os.RemoveAll(tree.toDir(id)) return nil }