From c4a49a11cf4127b3d7bb1ce3c355c51ba1c82eae Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr@nexedi.com>
Date: Fri, 3 Jul 2020 17:55:01 +0300
Subject: [PATCH] .

---
 "wcfs/\316\264btail.go" | 133 ++++++++++++++++++++++------------------
 1 file changed, 75 insertions(+), 58 deletions(-)

diff --git "a/wcfs/\316\264btail.go" "b/wcfs/\316\264btail.go"
index 3da6fbe1..74832833 100644
--- "a/wcfs/\316\264btail.go"
+++ "b/wcfs/\316\264btail.go"
@@ -694,10 +694,10 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 
 	var av rangeSplit  // nodes expanded from a
 	var bv rangeSplit  // nodes expanded from b
-	Aqueue := SetKey{} // "to process" keys on A
-	Bqueue := SetKey{} // "to process" keys on B
-	Adone  := SetKey{} // "processed" keys on A
-	Bdone  := SetKey{} // "processed" keys on B
+//	Aqueue := SetKey{} // "to process" keys on A
+//	Bqueue := SetKey{} // "to process" keys on B
+//	Adone  := SetKey{} // "processed" keys on A
+//	Bdone  := SetKey{} // "processed" keys on B
 
 	// XXX precise range as for a ^^^ ?
 	btop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: b} // [-鈭�, 鈭�)
@@ -708,7 +708,10 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 	// XXX maybe walk till a from root to get more precise initial range?
 	atop := &nodeInRange{lo: KeyMin, hi_: KeyMax, node: a} // [-鈭�, 鈭�)
 	av  = rangeSplit{atop}
-	aq := []*nodeInRange{atop} // stack
+	Aqueue := []*nodeInRange{atop} // stack: "to process" nodes on A
+	Bqueue := []*nodeInRange{}     // stack: "to process" nodes on B
+
+/*
 	for len(aq) > 0 {
 		l := len(aq)
 		arn  := aq[l-1]; aq=aq[:l-1] // arn=aq.pop()
@@ -749,7 +752,7 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 		for _, rchild := range children {
 			coid := rchild.node.POid()
 			if !( 未ZTC.Has(coid) ||
-			      /* embedded bucket */
+			      embedded bucket
 			      (len(children) == 1 && coid == zodb.InvalidOid) )  {
 				continue
 			}
@@ -789,6 +792,7 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 			}
 		}
 	}
+*/
 
 	tracef("  av: %s\n", av)
 	tracef("  bv: %s\n", bv)
@@ -797,9 +801,6 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 	// corresponding nodes, and merge diff generated from them into 未.
 	// Each delve for A or B, potentially adds new keys to process on the
 	// other side.
-	//
-	// XXX inefficient: we process each key separately, while they can be
-	// processed in sorted batches.
 	for {
 		tracef("\n")
 		tracef("  aq: %s\n", Aqueue)
@@ -809,6 +810,61 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 			break
 		}
 
+		// A queue
+//		Bqueue = SetKey{}
+		for len(Aqueue) > 0 {
+			Xa := pop(&Aqueue)
+			tracef("  A %v\n", Xa)
+
+/*
+			anode, ok, err := av.GetToLeaf(ctx, k)
+			if err != nil {
+				return nil, err
+			}
+			if !ok {
+				// FIXME -> key must be included into some node.hole
+				continue // key not covered
+			}
+
+			// XXX check for anode.node.(*Tree)	(酶 tree case)
+
+			// - bucket if that bucket is reached for the first time
+			if !anode.done {
+				未A, err := diffB(ctx, anode.node.(*Bucket), nil)
+				if err != nil {
+					return nil, err
+				}
+				// XXX also extract holes
+
+				// 未 <- 未A
+				err = 未Merge(未, 未A)
+				if err != nil {
+					return nil, err
+				}
+
+				// Adone  <- 未A
+				// Bqueue <- 未A
+				for k_ := range 未A {
+					Adone.Add(k_)
+					if !Bdone.Has(k_) {
+						Bqueue.Add(k_)
+					}
+				}
+
+				anode.done = true
+			}
+
+			// k is not there -> -[k]酶
+			if !Adone.Has(k) {
+				// XXX do we need to add(?) [k]酶->酶 ?
+				Adone.Add(k)
+			}
+*/
+
+			tracef("  av: %s\n", av)
+		}
+
+/*
 		// B queue
 		// expand keys from new 未A -> in B till buckets;
 		// process B buckets that cover new keys into 未+
@@ -862,6 +918,7 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 
 			tracef("  bv: %s\n", bv)
 		}
+*/
 
 		// FIXME update trackIdx
 /*
@@ -891,55 +948,6 @@ func diffT(ctx context.Context, a, b *Tree, 未ZTC SetOid, trackIdx map[zodb.Oid]
 		}
 */
 
-		// A queue
-		Bqueue = SetKey{}
-		for k := range Aqueue {
-			tracef("  A [%v]\n", k)
-			anode, ok, err := av.GetToLeaf(ctx, k)
-			if err != nil {
-				return nil, err
-			}
-			if !ok {
-				// FIXME -> key must be included into some node.hole
-				continue // key not covered
-			}
-
-			// XXX check for anode.node.(*Tree)	(酶 tree case)
-
-			// - bucket if that bucket is reached for the first time
-			if !anode.done {
-				未A, err := diffB(ctx, anode.node.(*Bucket), nil)
-				if err != nil {
-					return nil, err
-				}
-				// XXX also extract holes
-
-				// 未 <- 未A
-				err = 未Merge(未, 未A)
-				if err != nil {
-					return nil, err
-				}
-
-				// Adone  <- 未A
-				// Bqueue <- 未A
-				for k_ := range 未A {
-					Adone.Add(k_)
-					if !Bdone.Has(k_) {
-						Bqueue.Add(k_)
-					}
-				}
-
-				anode.done = true
-			}
-
-			// k is not there -> -[k]酶
-			if !Adone.Has(k) {
-				// XXX do we need to add(?) [k]酶->酶 ?
-				Adone.Add(k)
-			}
-
-			tracef("  av: %s\n", av)
-		}
 	}
 
 	return 未, nil
@@ -1522,6 +1530,15 @@ func (track nodeTrack) String() string {
 }
 
 
+// pop pops top element from node stack.
+func pop(nodeStk *[]*nodeInRange) *nodeInRange {
+	stk := *nodeStk
+	l := len(stk)
+	top := stk[l-1]
+	*nodeStk = stk[:l-1]
+	return top
+}
+
 
 const debug = true
 func tracef(format string, argv ...interface{}) {
-- 
2.30.9