1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: Apache-2.0
13 // lookupnode is a caching tree node that is initially empty and calls
14 // loadOne and loadAll to load/update child nodes as needed.
16 // See (*customFileSystem)MountUsers for example usage.
17 type lookupnode struct {
19 loadOne func(parent inode, name string) (inode, error)
20 loadAll func(parent inode) ([]inode, error)
21 stale func(time.Time) bool
26 staleOne map[string]time.Time
29 func (ln *lookupnode) Readdir() ([]os.FileInfo, error) {
31 defer ln.staleLock.Unlock()
32 checkTime := time.Now()
33 if ln.stale(ln.staleAll) {
34 all, err := ln.loadAll(ln)
38 for _, child := range all {
39 _, err = ln.inode.Child(child.FileInfo().Name(), func(inode) (inode, error) {
46 ln.staleAll = checkTime
47 // No value in ln.staleOne can make a difference to an
48 // "entry is stale?" test now, because no value is
49 // newer than ln.staleAll. Reclaim memory.
52 return ln.inode.Readdir()
55 func (ln *lookupnode) Child(name string, replace func(inode) (inode, error)) (inode, error) {
57 defer ln.staleLock.Unlock()
58 checkTime := time.Now()
59 if ln.stale(ln.staleAll) && ln.stale(ln.staleOne[name]) {
60 _, err := ln.inode.Child(name, func(inode) (inode, error) {
61 return ln.loadOne(ln, name)
66 if ln.staleOne == nil {
67 ln.staleOne = map[string]time.Time{name: checkTime}
69 ln.staleOne[name] = checkTime
72 return ln.inode.Child(name, replace)