16745: Keep a SiteFileSystem alive for multiple read requests.
[arvados.git] / sdk / go / arvados / fs_base.go
index aa75fee7c4d0f5bf47826d12300b51cdcf08a424..2478641df5478639c92ff2b4d0f57d847165eee7 100644 (file)
@@ -106,6 +106,9 @@ type FileSystem interface {
        // path is "", flush all dirs/streams; otherwise, flush only
        // the specified dir/stream.
        Flush(path string, shortBlocks bool) error
+
+       // Estimate current memory usage.
+       MemorySize() int64
 }
 
 type inode interface {
@@ -156,6 +159,7 @@ type inode interface {
        sync.Locker
        RLock()
        RUnlock()
+       MemorySize() int64
 }
 
 type fileinfo struct {
@@ -229,6 +233,13 @@ func (*nullnode) Child(name string, replace func(inode) (inode, error)) (inode,
        return nil, ErrNotADirectory
 }
 
+func (*nullnode) MemorySize() int64 {
+       // Types that embed nullnode should report their own size, but
+       // if they don't, we at least report a non-zero size to ensure
+       // a large tree doesn't get reported as 0 bytes.
+       return 64
+}
+
 type treenode struct {
        fs       FileSystem
        parent   inode
@@ -319,6 +330,15 @@ func (n *treenode) Sync() error {
        return nil
 }
 
+func (n *treenode) MemorySize() (size int64) {
+       n.RLock()
+       defer n.RUnlock()
+       for _, inode := range n.inodes {
+               size += inode.MemorySize()
+       }
+       return
+}
+
 type fileSystem struct {
        root inode
        fsBackend
@@ -607,6 +627,10 @@ func (fs *fileSystem) Flush(string, bool) error {
        return ErrInvalidOperation
 }
 
+func (fs *fileSystem) MemorySize() int64 {
+       return fs.root.MemorySize()
+}
+
 // rlookup (recursive lookup) returns the inode for the file/directory
 // with the given name (which may contain "/" separators). If no such
 // file/directory exists, the returned node is nil.