Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
f2d3cd40
Commit
f2d3cd40
authored
Jun 11, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
2c5f6517
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
53 deletions
+86
-53
wcfs/internal/xbtree/treediff.go
wcfs/internal/xbtree/treediff.go
+51
-32
wcfs/internal/xbtree/xbtree.go
wcfs/internal/xbtree/xbtree.go
+0
-7
wcfs/internal/xbtree/δbtail.go
wcfs/internal/xbtree/δbtail.go
+32
-11
wcfs/internal/xbtree/δbtail_test.go
wcfs/internal/xbtree/δbtail_test.go
+3
-3
No files found.
wcfs/internal/xbtree/treediff.go
View file @
f2d3cd40
...
...
@@ -82,6 +82,9 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xzodb"
)
const
traceDiff
=
false
const
debugDiff
=
false
// ΔValue represents change in value.
type
ΔValue
struct
{
Old
Value
...
...
@@ -326,10 +329,12 @@ func (rs rangeSplit) String() string {
func
treediff
(
ctx
context
.
Context
,
root
zodb
.
Oid
,
δtops
SetOid
,
δZTC
SetOid
,
trackSet
PPTreeSubSet
,
zconnOld
,
zconnNew
*
zodb
.
Connection
)
(
δT
map
[
Key
]
ΔValue
,
δtrack
*
ΔPPTreeSubSet
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"treediff %s..%s %s"
,
zconnOld
.
At
(),
zconnNew
.
At
(),
root
)
tracef
(
"
\n
treediff %s δtops: %v δZTC: %v
\n
"
,
root
,
δtops
,
δZTC
)
defer
tracef
(
"
\n
"
)
δT
=
map
[
Key
]
ΔValue
{}
δtrack
=
&
ΔPPTreeSubSet
{
Del
:
PPTreeSubSet
{},
Add
:
PPTreeSubSet
{},
δnchildNonLeafs
:
map
[
zodb
.
Oid
]
int
{}}
tracefDiff
(
"
\n
treediff %s δtops: %v δZTC: %v
\n
"
,
root
,
δtops
,
δZTC
)
defer
tracefDiff
(
"
\n
-> δT: %v
\n
δtrack: %v
\n
"
,
δT
,
δtrack
)
δtrackv
:=
[]
*
ΔPPTreeSubSet
{}
for
top
:=
range
δtops
{
// XXX -> sorted?
...
...
@@ -350,8 +355,8 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
// -> assert that keys from different δtop do not overlap
// DEL k -> Tkextra += k
// +k -> Tkextra -= k
trace
f
(
"-> δtop: %v
\n
"
,
δtop
)
trace
f
(
"-> δtrackTop: %v
\n
"
,
δtrackTop
)
debugfDif
f
(
"-> δtop: %v
\n
"
,
δtop
)
debugfDif
f
(
"-> δtrackTop: %v
\n
"
,
δtrackTop
)
for
k
,
δv
:=
range
δtop
{
δT
[
k
]
=
δv
}
...
...
@@ -360,7 +365,6 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
}
// adjust trackSet by merge(δtrackTops)
δtrack
=
&
ΔPPTreeSubSet
{
Del
:
PPTreeSubSet
{},
Add
:
PPTreeSubSet
{},
δnchildNonLeafs
:
map
[
zodb
.
Oid
]
int
{}}
for
_
,
δ
:=
range
δtrackv
{
δtrack
.
Update
(
δ
)
}
...
...
@@ -430,12 +434,15 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackSet PPTreeSubSet)
// a, b point to top of subtrees @old and @new revisions.
// δZTC is connected set of objects covering δZT (objects changed in this tree in old..new).
func
diffT
(
ctx
context
.
Context
,
A
,
B
*
Tree
,
δZTC
SetOid
,
trackSet
PPTreeSubSet
)
(
δ
map
[
Key
]
ΔValue
,
δtrack
*
ΔPPTreeSubSet
,
err
error
)
{
tracef
(
" diffT %s %s
\n
"
,
xidOf
(
A
),
xidOf
(
B
))
tracef
Diff
(
" diffT %s %s
\n
"
,
xidOf
(
A
),
xidOf
(
B
))
defer
xerr
.
Contextf
(
&
err
,
"diffT %s %s"
,
xidOf
(
A
),
xidOf
(
B
))
δ
=
map
[
Key
]
ΔValue
{}
δtrack
=
&
ΔPPTreeSubSet
{
Del
:
PPTreeSubSet
{},
Add
:
PPTreeSubSet
{},
δnchildNonLeafs
:
map
[
zodb
.
Oid
]
int
{}}
defer
tracef
(
" -> δ: %v
\n
"
,
δ
)
defer
func
()
{
tracefDiff
(
" -> δ: %v
\n
"
,
δ
)
tracefDiff
(
" -> δtrack: %v
\n
"
,
δtrack
)
}()
if
A
==
nil
&&
B
==
nil
{
return
δ
,
δtrack
,
nil
// ø changes
...
...
@@ -496,7 +503,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtodo
:=
&
RangedKeySet
{}
δtodo
.
AddRange
(
r
)
δtodo
.
DifferenceInplace
(
Akdone
)
trace
f
(
" Akq <- %s
\n
"
,
δtodo
)
debugfDif
f
(
" Akq <- %s
\n
"
,
δtodo
)
Akqueue
.
UnionInplace
(
δtodo
)
}
}
...
...
@@ -505,7 +512,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
δtodo
:=
&
RangedKeySet
{}
δtodo
.
AddRange
(
r
)
δtodo
.
DifferenceInplace
(
Bkdone
)
trace
f
(
" Bkq <- %s
\n
"
,
δtodo
)
debugfDif
f
(
" Bkq <- %s
\n
"
,
δtodo
)
Bkqueue
.
UnionInplace
(
δtodo
)
}
}
...
...
@@ -523,14 +530,14 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
// - ac ∉ δZTC && ∃ bc from B: ac.oid == bc.oid (ac+ac.children were not changed, and ac stays in the tree)
Aq
:=
[]
*
nodeInRange
{
atop
}
// queue for A nodes that contribute to δ-
for
len
(
Aq
)
>
0
{
trace
f
(
"
\n
"
)
trace
f
(
" aq: %v
\n
"
,
Aq
)
trace
f
(
" av: %s
\n
"
,
Av
)
trace
f
(
" bv: %s
\n
"
,
Bv
)
debugfDif
f
(
"
\n
"
)
debugfDif
f
(
" aq: %v
\n
"
,
Aq
)
debugfDif
f
(
" av: %s
\n
"
,
Av
)
debugfDif
f
(
" bv: %s
\n
"
,
Bv
)
ra
:=
pop
(
&
Aq
)
err
=
ra
.
node
.
PActivate
(
ctx
);
/*X*/
if
err
!=
nil
{
return
nil
,
nil
,
err
}
defer
ra
.
node
.
PDeactivate
()
trace
f
(
" a: %s
\n
"
,
ra
)
debugfDif
f
(
" a: %s
\n
"
,
ra
)
switch
a
:=
ra
.
node
.
(
type
)
{
case
*
Bucket
:
...
...
@@ -636,14 +643,14 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
// * +B12, which queues A.2 and leads to
// * -B23, which queues B.3 and leads to
// * +B23, ...
trace
f
(
"
\n
phase 2:
\n
"
)
debugfDif
f
(
"
\n
phase 2:
\n
"
)
for
{
trace
f
(
"
\n
"
)
trace
f
(
" av: %s
\n
"
,
Av
)
trace
f
(
" bv: %s
\n
"
,
Bv
)
debugfDif
f
(
"
\n
"
)
debugfDif
f
(
" av: %s
\n
"
,
Av
)
debugfDif
f
(
" bv: %s
\n
"
,
Bv
)
trace
f
(
"
\n
"
)
trace
f
(
" Bkq: %s
\n
"
,
Bkqueue
)
debugfDif
f
(
"
\n
"
)
debugfDif
f
(
" Bkq: %s
\n
"
,
Bkqueue
)
if
Bkqueue
.
Empty
()
{
break
}
...
...
@@ -652,7 +659,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
lo
:=
r
.
lo
for
{
b
,
err
:=
Bv
.
GetToLeaf
(
ctx
,
lo
);
/*X*/
if
err
!=
nil
{
return
nil
,
nil
,
err
}
trace
f
(
" B k%d -> %s
\n
"
,
lo
,
b
)
debugfDif
f
(
" B k%d -> %s
\n
"
,
lo
,
b
)
// +bucket if that bucket is reached for the first time
if
!
b
.
done
{
var
δB
map
[
Key
]
ΔValue
...
...
@@ -683,13 +690,13 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
}
Bkqueue
.
Clear
()
trace
f
(
"
\n
"
)
trace
f
(
" Akq: %s
\n
"
,
Akqueue
)
debugfDif
f
(
"
\n
"
)
debugfDif
f
(
" Akq: %s
\n
"
,
Akqueue
)
for
_
,
r
:=
range
Akqueue
.
AllRanges
()
{
lo
:=
r
.
lo
for
{
a
,
err
:=
Av
.
GetToLeaf
(
ctx
,
lo
);
/*X*/
if
err
!=
nil
{
return
nil
,
nil
,
err
}
trace
f
(
" A k%d -> %s
\n
"
,
lo
,
a
)
debugfDif
f
(
" A k%d -> %s
\n
"
,
lo
,
a
)
// -bucket if that bucket is reached for the first time
if
!
a
.
done
{
var
δA
map
[
Key
]
ΔValue
...
...
@@ -727,8 +734,8 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackSet PPTreeSubSet)
// δMerge merges changes from δ2 into δ.
// δ is total-building diff, while δ2 is diff from comparing some subnodes.
func
δMerge
(
δ
,
δ2
map
[
Key
]
ΔValue
)
error
{
trace
f
(
" δmerge %v <- %v
\n
"
,
δ
,
δ2
)
defer
trace
f
(
" -> %v
\n
"
,
δ
)
debugfDif
f
(
" δmerge %v <- %v
\n
"
,
δ
,
δ2
)
defer
debugfDif
f
(
" -> %v
\n
"
,
δ
)
// merge δ <- δ2
for
k
,
δv2
:=
range
δ2
{
...
...
@@ -773,7 +780,7 @@ func δMerge(δ, δ2 map[Key]ΔValue) error {
δv
.
New
=
δv2
.
New
}
trace
f
(
" [%v] merge %s %s -> %s
\n
"
,
k
,
δv1
,
δv2
,
δv
)
debugfDif
f
(
" [%v] merge %s %s -> %s
\n
"
,
k
,
δv1
,
δv2
,
δv
)
if
δv
.
Old
!=
δv
.
New
{
δ
[
k
]
=
δv
}
else
{
...
...
@@ -787,7 +794,7 @@ func δMerge(δ, δ2 map[Key]ΔValue) error {
// diffB computes difference in between two buckets.
// see diffX for details.
func
diffB
(
ctx
context
.
Context
,
a
,
b
*
Bucket
)
(
δ
map
[
Key
]
ΔValue
,
err
error
)
{
tracef
(
" diffB %s %s
\n
"
,
xidOf
(
a
),
xidOf
(
b
))
tracef
Diff
(
" diffB %s %s
\n
"
,
xidOf
(
a
),
xidOf
(
b
))
defer
xerr
.
Contextf
(
&
err
,
"diffB %s %s"
,
xidOf
(
a
),
xidOf
(
b
))
// XXX oid can be InvalidOid for T/B... (i.e. B is part of T and is not yet committed separately)
...
...
@@ -805,9 +812,9 @@ func diffB(ctx context.Context, a, b *Bucket) (δ map[Key]ΔValue, err error) {
}
δ
=
map
[
Key
]
ΔValue
{}
defer
tracef
(
" -> δb: %v
\n
"
,
δ
)
//
trace
f(" av: %v", av)
//
trace
f(" bv: %v", bv)
defer
tracef
Diff
(
" -> δb: %v
\n
"
,
δ
)
//
debugfDif
f(" av: %v", av)
//
debugfDif
f(" bv: %v", bv)
for
len
(
av
)
>
0
||
len
(
bv
)
>
0
{
ka
,
va
:=
KeyMax
,
VDEL
...
...
@@ -961,3 +968,15 @@ func vnode(node Node) string {
}
return
kind
+
node
.
POid
()
.
String
()
}
func
tracefDiff
(
format
string
,
argv
...
interface
{})
{
if
traceDiff
{
fmt
.
Printf
(
format
,
argv
...
)
}
}
func
debugfDiff
(
format
string
,
argv
...
interface
{})
{
if
debugDiff
{
fmt
.
Printf
(
format
,
argv
...
)
}
}
wcfs/internal/xbtree/xbtree.go
View file @
f2d3cd40
...
...
@@ -36,13 +36,6 @@ type SetOid = set.SetOid
const
debug
=
false
func
tracef
(
format
string
,
argv
...
interface
{})
{
if
debug
{
fmt
.
Printf
(
format
,
argv
...
)
}
}
// nodePathToPath converts path from []Node to []Oid.
// XXX place = ?
func
nodePathToPath
(
nodePath
[]
Node
)
(
path
[]
zodb
.
Oid
)
{
...
...
wcfs/internal/xbtree/δbtail.go
View file @
f2d3cd40
...
...
@@ -22,6 +22,7 @@ package xbtree
import
(
"context"
"fmt"
"sort"
"strings"
...
...
@@ -36,6 +37,10 @@ import (
// TODO kill this after rebuild is finished
const
XXX_killWhenRebuildWorks
=
true
const
traceΔBtail
=
true
const
debugΔBtail
=
false
// ΔBtail represents tail of revisional changes to BTrees.
//
// It semantically consists of
...
...
@@ -217,7 +222,7 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, nodePath []Node) error {
pathv
:=
[]
string
{}
for
_
,
node
:=
range
nodePath
{
pathv
=
append
(
pathv
,
vnode
(
node
))
}
tracef
(
"Track [%v] %s
\n
"
,
key
,
strings
.
Join
(
pathv
,
" -> "
))
tracef
ΔBtail
(
"Track [%v] %s
\n
"
,
key
,
strings
.
Join
(
pathv
,
" -> "
))
return
δBtail
.
track
(
key
,
keyPresent
,
path
)
}
...
...
@@ -248,6 +253,9 @@ func (δBtail *ΔBtail) rebuild() (err error) {
defer
xerr
.
Context
(
&
err
,
"ΔBtail rebuild"
)
// XXX locking
// XXX tracefΔBtail rebuild @head
// XXX tracefΔBtail trackNew: ...
trackNew
:=
δBtail
.
trackNew
δBtail
.
trackNew
=
PPTreeSubSet
{}
...
...
@@ -272,11 +280,11 @@ func (δBtail *ΔBtail) rebuild() (err error) {
δZTC
,
δtopsByRoot
:=
δZConnectTracked
(
δZ
.
Changev
,
trackNew
)
tracef
(
"
\n
rebuild @%s <- @%s
\n
"
,
atPrev
,
δZ
.
Rev
)
tracef
(
"δZ:
\t
%v
\n
"
,
δZ
.
Changev
)
tracef
(
"trackNew: %v
\n
"
,
trackNew
)
tracef
(
"trackSet: %v
\n
"
,
δBtail
.
trackSet
)
// XXX needed?
defer
tracef
(
"
\n\n
"
)
debugfΔBtail
(
"
\n
rebuild @%s <- @%s
\n
"
,
atPrev
,
δZ
.
Rev
)
debugfΔBtail
(
"δZ:
\t
%v
\n
"
,
δZ
.
Changev
)
debugfΔBtail
(
"trackNew: %v
\n
"
,
trackNew
)
debugfΔBtail
(
"trackSet: %v
\n
"
,
δBtail
.
trackSet
)
// XXX needed?
defer
debugfΔBtail
(
"
\n\n
"
)
// XXX len(δtopsByRoot) == 0 -> skip
...
...
@@ -301,7 +309,7 @@ func (δBtail *ΔBtail) rebuild() (err error) {
return
err
}
tracef
(
"-> root<%s> δkv*: %v δtrack*: %v
\n
"
,
root
,
δT
,
δtrack
)
debugfΔBtail
(
"-> root<%s> δkv*: %v δtrack*: %v
\n
"
,
root
,
δT
,
δtrack
)
trackNew
.
ApplyΔ
(
δtrack
)
vδtrack
=
append
([]
*
ΔPPTreeSubSet
{
δtrack
},
vδtrack
...
)
...
...
@@ -387,9 +395,9 @@ if XXX_killWhenRebuildWorks {
}
}
tracef
(
"Update @%s -> @%s
\n
"
,
δBtail
.
Head
(),
δZ
.
Tid
)
tracef
(
"δZ:
\t
%v
\n
"
,
δZ
.
Changev
)
tracef
(
"trackSet: %v
\n
"
,
δBtail
.
trackSet
)
tracef
ΔBtail
(
"Update @%s -> @%s
\n
"
,
δBtail
.
Head
(),
δZ
.
Tid
)
tracef
ΔBtail
(
"δZ:
\t
%v
\n
"
,
δZ
.
Changev
)
debugfΔBtail
(
"trackSet: %v
\n
"
,
δBtail
.
trackSet
)
// XXX dup wrt rebuild?
...
...
@@ -423,7 +431,7 @@ if XXX_killWhenRebuildWorks {
return
ΔB
{},
err
}
tracef
(
"
\n
-> root<%s> δkv: %v δtrack: %v
\n
"
,
root
,
δT
,
δtrack
)
debugfΔBtail
(
"
\n
-> root<%s> δkv: %v δtrack: %v
\n
"
,
root
,
δT
,
δtrack
)
if
len
(
δT
)
>
0
{
// an object might be resaved without change
δB
.
ByRoot
[
root
]
=
δT
...
...
@@ -563,3 +571,16 @@ func (δBtail *ΔBtail) SliceByRootRev(root zodb.Oid, lo, hi zodb.Tid) /*readonl
func
(
δBtail
*
ΔBtail
)
ΔZtail
()
/*readonly*/
*
zodb
.
ΔTail
{
return
δBtail
.
δZtail
}
func
tracefΔBtail
(
format
string
,
argv
...
interface
{})
{
if
traceΔBtail
{
fmt
.
Printf
(
format
,
argv
...
)
}
}
func
debugfΔBtail
(
format
string
,
argv
...
interface
{})
{
if
debugΔBtail
{
fmt
.
Printf
(
format
,
argv
...
)
}
}
wcfs/internal/xbtree/δbtail_test.go
View file @
f2d3cd40
...
...
@@ -666,7 +666,7 @@ func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb
// tracked state defined by initialTrackedKeys.
func
xverifyΔBTail_Update1
(
t
*
testing
.
T
,
subj
string
,
db
*
zodb
.
DB
,
treeRoot
zodb
.
Oid
,
at1
,
at2
zodb
.
Tid
,
xkv1
,
xkv2
RBucketSet
,
δZ
*
zodb
.
EventCommit
,
d12
map
[
Key
]
Δstring
,
initialTrackedKeys
SetKey
,
kadj
KAdjMatrix
)
{
X
:=
exc
.
Raiseif
trace
f
(
"
\n
>>> Track=%s
\n
"
,
initialTrackedKeys
)
// t.Log
f("\n>>> Track=%s\n", initialTrackedKeys)
var
TrackedδZ
SetKey
=
nil
var
kadjTrackedδZ
SetKey
=
nil
...
...
@@ -902,7 +902,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// t1 := t2.prev
// t0 := t1.prev
t
.
Run
(
fmt
.
Sprintf
(
"rebuild/%s→%s"
,
t0
.
tree
,
t1
.
tree
),
func
(
t
*
testing
.
T
)
{
t
.
Skip
(
"TODO"
)
// FIXME rebuild is currently broken
//
t.Skip("TODO") // FIXME rebuild is currently broken
tAllKeys
:=
allTestKeys
(
t0
,
t1
,
t2
)
tAllKeyv
:=
tAllKeys
.
SortedElements
()
...
...
@@ -1354,7 +1354,7 @@ func testΔBTail(t *testing.T, testq chan ΔBTestEntry) {
t2
.
prev
=
t1
// XXX ----//----
subj
:=
fmt
.
Sprintf
(
"%s -> %s"
,
t1
.
tree
,
t2
.
tree
)
trace
f
(
"
\n\n\n
**** %s ****
\n\n
"
,
subj
)
// t.Log
f("\n\n\n**** %s ****\n\n", subj)
// KAdj
if
kadjOK
:=
test
.
kadjOK
;
kadjOK
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment