From ef12f1daad0cef591ebeb4f79fa384c231d6b990 Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr@nexedi.com>
Date: Tue, 5 Feb 2019 22:55:49 +0300
Subject: [PATCH] .

---
 "wcfs/internal/\316\264btree/\316\264btree.go" | 18 +++++++++++++-----
 wcfs/notes.txt                                 |  2 ++
 wcfs/wcfs.go                                   |  6 +++---
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git "a/wcfs/internal/\316\264btree/\316\264btree.go" "b/wcfs/internal/\316\264btree/\316\264btree.go"
index bed76e4..bf672d3 100644
--- "a/wcfs/internal/\316\264btree/\316\264btree.go"
+++ "b/wcfs/internal/\316\264btree/\316\264btree.go"
@@ -32,10 +32,14 @@ import (
 type Tree   = btree.LOBTree
 type Bucket = btree.LOBucket
 
-// PathMap is a residency index which maps BTree|Bucket to top tree element.
+// PathSet is a collection of BTree paths.
 //
-// PathMap is not safe for concurrent access.
-type PathMap struct {
+// For example it can be a set of visited BTree paths.
+// There is no requirement that paths belong to only one single BTree.
+//
+// PathSet is not safe for concurrent access.
+type PathSet struct {
+	// residency index which maps BTree|Bucket to top tree element.
 	residencyIdx map[zodb.Oid]SetTree // oid -> {} roots
 }
 
@@ -43,7 +47,9 @@ type PathMap struct {
 //
 // path[0] signifies a root.
 // All path elemens must be Tree except last one which must be Bucket.
-func (m *PathMap) Add(path []zodb.IPersistent) {
+//
+// XXX catch cycles on add?
+func (m *PathSet) Add(path []zodb.IPersistent) {
 	l := len(path)
 	if l == 0 {
 		panic("empty path")
@@ -82,7 +88,9 @@ func (m *PathMap) Add(path []zodb.IPersistent) {
 // returned are: roots of changed trees.
 //
 // XXX stub.
-func (m *PathMap) Invalidates(changev []zodb.Oid) SetTree {
+//
+// TODO toposort changev wrt nodes ordering (defined by traversed paths) and do δbtree top-down.
+func (m *PathSet) Invalidates(changev []zodb.Oid) SetTree {
 	toinvalidate := make(SetTree)
 
 	for _, oid := range changev {
diff --git a/wcfs/notes.txt b/wcfs/notes.txt
index 1af5a49..efa843c 100644
--- a/wcfs/notes.txt
+++ b/wcfs/notes.txt
@@ -182,6 +182,8 @@ i.e. exactly as for buckets and it accumulates to global Δ.
 
 The globally-accumulated Δ is the answer for δ(BTree, (@new, []oid))
 
+top-down order is obtained via toposort({oid}) wrt visited PathSet.
+
 XXX -> internal/btreediff ?
 
 δ(BTree) in wcfs context:
diff --git a/wcfs/wcfs.go b/wcfs/wcfs.go
index e815ff5..ba0f73a 100644
--- a/wcfs/wcfs.go
+++ b/wcfs/wcfs.go
@@ -460,8 +460,8 @@ type BigFileDir struct {
 	mu      sync.Mutex
 	fileTab map[zodb.Oid]*BigFile
 
-	// residency index for btree|bucket -> which file
-	btreeMap *δbtree.PathMap
+	// visited BTree nodes -> which file + ordering for toposort on δbtree
+	blktabLoaded *δbtree.PathSet
 }
 
 // /(head|<rev>)/bigfile/<bigfileX>	- served by BigFile.
@@ -1162,7 +1162,7 @@ func (f *BigFile) readBlk(ctx context.Context, blk int64, dest []byte) error {
 	close(loading.ready)
 
 	// XXX locking
-	_ = treepath	// TODO -> btreeMap
+	x.blktabVisited.Add(treepath)
 
 	// XXX before loading.ready?
 	blkrevmax, _ := f.δFtail.LastRevOf(blk, zbf.PJar().At())
-- 
2.30.9