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
0480d21d
Commit
0480d21d
authored
Sep 07, 2020
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
05c78d30
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
29 deletions
+83
-29
wcfs/δbtail.go
wcfs/δbtail.go
+67
-16
wcfs/δbtail_test.go
wcfs/δbtail_test.go
+16
-13
No files found.
wcfs/δbtail.go
View file @
0480d21d
...
...
@@ -174,8 +174,8 @@ type ΔBtail struct {
// tracked nodes index: node -> parent + accessed holes under this node XXX -> holeIdx
// we only allow single parent/root case and report "tree corrupt" otherwise.
// trackIdx describes @head state
//
XXX -> parentIdx map[zodb.Oid]zodb.Oid ?
trackIdx
map
[
zodb
.
Oid
]
nodeTrack
//
trackIdx map[zodb.Oid]nodeTrack
trackIdx
trackIndex
// XXX tracked holes
holeIdx
treeSetKey
...
...
@@ -184,17 +184,25 @@ type ΔBtail struct {
// trackNew SetOid
}
// XXX place
type
trackIndex
map
[
zodb
.
Oid
]
*
nodeTrack
// XXX place
// nodeTrack represents tracking information about a node.
// XXX kill (parentIdx is just {} oid -> oid)
//
//
XXX kill (parentIdx is just {} oid -> oid)
type
nodeTrack
struct
{
parent
zodb
.
Oid
// parent node | InvalidOid for root
nchild
int
// number of direct children in trackIdx referring to this node
/*
holes SetKey // missing keys tracked under this node; nil for !leaf
// XXX move holes into separate ΔBtail..holeIdx
*/
}
func
(
tidx
trackIndex
)
DelLeaf
(
oid
zodb
.
Oid
)
{
panic
(
"TODO"
)
}
// treeSetKey represents ordered set of keys.
// it can be point-queried and range-accessed.
// TODO -> btree
...
...
@@ -259,7 +267,7 @@ func NewΔBtail(at0 zodb.Tid, db *zodb.DB) *ΔBtail {
return
&
ΔBtail
{
δZtail
:
zodb
.
NewΔTail
(
at0
),
byRoot
:
map
[
zodb
.
Oid
]
*
ΔTtail
{},
trackIdx
:
map
[
zodb
.
Oid
]
nodeTrack
{},
trackIdx
:
trackIndex
{},
holeIdx
:
treeSetKey
{
SetKey
{}},
db
:
db
,
}
...
...
@@ -308,19 +316,17 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { //
tracef
(
"Track [%v] %s
\n
"
,
key
,
strings
.
Join
(
pathv
,
" -> "
))
parent
:=
zodb
.
InvalidOid
var
track
nodeTrack
var
ptrack
*
nodeTrack
=
nil
var
track
*
nodeTrack
// XXX kill here
var
oldTrack
bool
for
_
,
node
:=
range
path
{
oid
:=
node
.
POid
()
// XXX skip InvalidOid ?
// InvalidOid means embedded bucket - e.g. T/B1:a with bucket not having its own oid.
//if oid == zodb.InvalidOid {
// // XXX verify node is leaf; else panic
// continue
//}
track
,
oldTrack
=
δBtail
.
trackIdx
[
oid
]
if
!
oldTrack
{
track
=
nodeTrack
{
parent
:
parent
}
track
=
&
nodeTrack
{
parent
:
parent
,
nchild
:
0
}
// XXX
/*
if i == l-1 { // leaf
track.holes = SetKey{}
...
...
@@ -334,7 +340,13 @@ func (δBtail *ΔBtail) Track(key Key, keyPresent bool, path []Node) error { //
panicf
(
"node %s is reachable from multiple parents: %s %s"
,
oid
,
track
.
parent
,
parent
)
}
if
ptrack
!=
nil
{
ptrack
.
nchild
++
}
parent
=
oid
ptrack
=
track
}
// track is track of path[-1] (i.e. leaf)
...
...
@@ -489,7 +501,7 @@ func (δBtail *ΔBtail) δZConnectTracked(δZv *zodb.EventCommit) (δZTC SetOid,
// XXX place
// nodeInRange represents a Node coming under [lo, hi_] key range in its tree.
type
nodeInRange
struct
{
// XXX +parent?
parent
*
nodeInRange
lo
,
hi_
Key
// [lo, hi_] NOTE _not_ hi) not to overflow at ∞
node
Node
done
bool
// whether this node was already taken into account while computing diff
...
...
@@ -641,13 +653,14 @@ func (rs rangeSplit) String() string {
// δtops is set of top nodes for changed subtrees.
// δZTC is connected(δZ/T) - connected closure for subset of δZ(old..new) that
// touches tracked nodes of T.
func
treediff
(
ctx
context
.
Context
,
root
zodb
.
Oid
,
δtops
SetOid
,
δZTC
SetOid
,
trackIdx
map
[
zodb
.
Oid
]
nodeTrack
,
holeIdx
treeSetKey
,
zconnOld
,
zconnNew
*
zodb
.
Connection
)
(
δT
map
[
Key
]
ΔValue
,
err
error
)
{
func
treediff
(
ctx
context
.
Context
,
root
zodb
.
Oid
,
δtops
SetOid
,
δZTC
SetOid
,
trackIdx
trackIndex
,
holeIdx
treeSetKey
,
zconnOld
,
zconnNew
*
zodb
.
Connection
)
(
δT
map
[
Key
]
ΔValue
,
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
{}
trackDel
:=
SetOid
{}
for
top
:=
range
δtops
{
// XXX -> sorted?
a
,
err1
:=
zgetNode
(
ctx
,
zconnOld
,
top
)
...
...
@@ -683,7 +696,38 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
}
}
// XXX adjust trackIdx
// adjust trackIdx
for
oid
:=
range
trackDel
{
_
,
present
:=
trackIdx
[
oid
]
if
!
present
{
continue
}
trackIdx
.
DelLeaf
(
oid
)
}
/*
for leaf := range trackAdd {
node := leaf
for node != nil {
parent := node.parent
oid := node.node.POid()
poid := zodb.InvalidOid
if parent != nil {
poid = parent.node.POid()
}
track, already := trackIdx[oid]
if !already {
track = nodeTrack{parent: poid}
trackIdx[oid] = track
}
if track.parent != poid {
// XXX -> error (e.g. data corruption in ZODB)
panicf("node %s has multiple parents: %s %s", oid, poid, track.parent)
}
// XXX incref trackIdx[track.parent]
node = parent
}
}
*/
return
δT
,
nil
}
...
...
@@ -696,7 +740,7 @@ func treediff(ctx context.Context, root zodb.Oid, δtops SetOid, δZTC SetOid, t
// δZTC is connected set of objects covering δZT (objects changed in this tree in old..new).
//
// a/b can be nil; a=nil means addition, b=nil means deletion.
func
diffX
(
ctx
context
.
Context
,
a
,
b
Node
,
δZTC
SetOid
,
trackIdx
map
[
zodb
.
Oid
]
nodeTrack
,
holeIdx
treeSetKey
)
(
δ
map
[
Key
]
ΔValue
,
err
error
)
{
func
diffX
(
ctx
context
.
Context
,
a
,
b
Node
,
δZTC
SetOid
,
trackIdx
trackIndex
,
holeIdx
treeSetKey
)
(
δ
map
[
Key
]
ΔValue
,
err
error
)
{
if
a
==
nil
&&
b
==
nil
{
panic
(
"BUG: both a & b == nil"
)
}
...
...
@@ -744,7 +788,7 @@ func diffX(ctx context.Context, a, b Node, δZTC SetOid, trackIdx map[zodb.Oid]n
//
// XXX trackIdx -> just pass δBtail?
// XXX ----//---- holeIdx
func
diffT
(
ctx
context
.
Context
,
A
,
B
*
Tree
,
δZTC
SetOid
,
trackIdx
map
[
zodb
.
Oid
]
nodeTrack
,
holeIdx
treeSetKey
)
(
δ
map
[
Key
]
ΔValue
,
err
error
)
{
func
diffT
(
ctx
context
.
Context
,
A
,
B
*
Tree
,
δZTC
SetOid
,
trackIdx
trackIndex
,
holeIdx
treeSetKey
)
(
δ
map
[
Key
]
ΔValue
,
err
error
)
{
tracef
(
" diffT %s %s
\n
"
,
xidOf
(
A
),
xidOf
(
B
))
defer
xerr
.
Contextf
(
&
err
,
"diffT %s %s"
,
xidOf
(
A
),
xidOf
(
B
))
...
...
@@ -782,8 +826,12 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// {} oid -> parent for all nodes in Bv: current and previously expanded - up till top B
// XXX
// XXX requires A.oid == B.oid
// XXX -> trackIndex
BtrackIdx
:=
map
[
zodb
.
Oid
]
nodeTrack
{
B
.
POid
()
:
nodeTrack
{
parent
:
trackIdx
[
B
.
POid
()]
.
parent
}}
trackDel
:=
SetOid
{}
// leaf nodes to be removed from trackIdx after treediff
// trackAdd := SetNode{} // leaf nodes to be added to trackIdx after treediff
// phase 1: expand A top->down driven by δZTC.
// by default a node contributes to δ-
// a node ac does not contribute to δ- and can be skipped, if:
...
...
@@ -805,6 +853,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// a is bucket -> δ-
δA
,
err
:=
diffB
(
ctx
,
a
,
nil
);
/*X*/
if
err
!=
nil
{
return
nil
,
err
}
err
=
δMerge
(
δ
,
δA
);
/*X*/
if
err
!=
nil
{
return
nil
,
err
}
trackDel
.
Add
(
a
.
POid
())
// Bkqueue <- δA
for
k
:=
range
δA
{
...
...
@@ -927,6 +976,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δB
err
=
δMerge
(
δ
,
δB
);
/*X*/
if
err
!=
nil
{
return
nil
,
err
}
// trackAdd.Add(b)
// Akqueue <- δB
for
k_
:=
range
δB
{
...
...
@@ -956,6 +1006,7 @@ func diffT(ctx context.Context, A, B *Tree, δZTC SetOid, trackIdx map[zodb.Oid]
// δ <- δA
err
=
δMerge
(
δ
,
δA
);
/*X*/
if
err
!=
nil
{
return
nil
,
err
}
trackDel
.
Add
(
a
.
node
.
POid
())
// Bkqueue <- δA
for
k_
:=
range
δA
{
...
...
@@ -1286,7 +1337,7 @@ func (rn nodeInRange) String() string {
func
(
track
nodeTrack
)
String
()
string
{
//return fmt.Sprintf("{p%s h%s}", track.parent, track.holes)
return
fmt
.
Sprintf
(
"{p%s
}"
,
track
.
parent
)
return
fmt
.
Sprintf
(
"{p%s
c%d}"
,
track
.
parent
,
track
.
nchild
)
}
...
...
wcfs/δbtail_test.go
View file @
0480d21d
...
...
@@ -67,6 +67,7 @@ import (
)
const
kInf
Key
=
10000
// inf key (TeX hack)
//const kInf Key = KeyMax
// XXX move infrastructure -> δbtail_treegen_test.go ?
...
...
@@ -334,17 +335,18 @@ func (rbs RBucketSet) holeIdx(tracked SetKey) SetKey {
}
// trackIdx returns what should be ΔBtree.trackIdx for specified tracked key set.
func
(
rbs
RBucketSet
)
trackIdx
(
tracked
SetKey
)
map
[
zodb
.
Oid
]
nodeTrack
{
trackIdx
:=
map
[
zodb
.
Oid
]
nodeTrack
{}
func
(
rbs
RBucketSet
)
trackIdx
(
tracked
SetKey
)
trackIndex
{
trackIdx
:=
trackIndex
{}
for
k
:=
range
tracked
{
kb
:=
rbs
.
Get
(
k
)
// trackIdx records regular buckets or non-empty embedded bucket
// (empty embedded bucket means there is just empty tree node
// and only that is recorded in trackIdx)
if
kb
.
oid
!=
zodb
.
InvalidOid
||
len
(
kb
.
kv
)
!=
0
{
// ( empty embedded bucket means there is just empty tree node
// and only that empty tree node is recorded in trackIdx )
trackKB
:=
(
kb
.
oid
!=
zodb
.
InvalidOid
||
len
(
kb
.
kv
)
!=
0
)
if
trackKB
{
track
,
already
:=
trackIdx
[
kb
.
oid
]
if
!
already
{
track
=
nodeTrack
{
parent
:
kb
.
parent
.
oid
}
track
=
&
nodeTrack
{
parent
:
kb
.
parent
.
oid
,
nchild
:
0
}
trackIdx
[
kb
.
oid
]
=
track
}
if
track
.
parent
!=
kb
.
parent
.
oid
{
...
...
@@ -361,13 +363,16 @@ func (rbs RBucketSet) trackIdx(tracked SetKey) map[zodb.Oid]nodeTrack {
pt
,
already
:=
trackIdx
[
p
.
oid
]
if
!
already
{
pt
=
nodeTrack
{
parent
:
ppoid
}
pt
=
&
nodeTrack
{
parent
:
ppoid
,
nchild
:
0
}
trackIdx
[
p
.
oid
]
=
pt
}
if
pt
.
parent
!=
ppoid
{
panicf
(
"BUG: %s: T%s -> multiple parents: %s %s"
,
rbs
.
coverage
(),
p
.
oid
,
pt
.
parent
,
ppoid
)
}
if
trackKB
{
pt
.
nchild
++
}
p
=
p
.
parent
}
}
...
...
@@ -616,7 +621,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
emsg
+=
strings
.
Join
(
badv
,
"
\n
"
)
emsg
+=
"
\n
"
t
.
Error
(
emsg
)
t
.
Fatal
(
emsg
)
}
}()
...
...
@@ -678,7 +683,7 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
// trackIdx1 = xkv1[tracked1]
trackIdx1
:=
xkv1
.
trackIdx
(
initialTrackedKeys
)
if
!
reflect
.
DeepEqual
(
trackIdx1
,
δbtail
.
trackIdx
)
{
badf
(
"δbtail.trackIdx1 wrong
; trackIdx=%v trackIdxOK=
%v"
,
δbtail
.
trackIdx
,
trackIdx1
)
badf
(
"δbtail.trackIdx1 wrong
:
\n\t
have: %v
\n\t
want:
%v"
,
δbtail
.
trackIdx
,
trackIdx1
)
}
...
...
@@ -696,14 +701,12 @@ func xverifyΔBTail1(t *testing.T, subj string, db *zodb.DB, treeRoot zodb.Oid,
badf
(
"δbtail.holeIdx2 wrong ; holeIdx=%v holeIdxOK=%v"
,
δbtail
.
holeIdx
,
holes2
)
}
// verify δbtail.trac
i
Idx against @at2
// verify δbtail.trac
k
Idx against @at2
// trackIdx2 = xkv2[tracked2] ( = xkv2[kadj[tracked1]]
/* XXX reenable
trackIdx2
:=
xkv2
.
trackIdx
(
kadjTracked
)
if
!
reflect
.
DeepEqual
(
trackIdx2
,
δbtail
.
trackIdx
)
{
badf("δbtail.trackIdx2 wrong
; trackIdx=%v trackIdxOK=
%v", δbtail.trackIdx, trackIdx2)
badf
(
"δbtail.trackIdx2 wrong
:
\n\t
have: %v
\n\t
want:
%v"
,
δbtail
.
trackIdx
,
trackIdx2
)
}
*/
// assert δB.ByRoot == {treeRoot -> ...} if δTok != ø
...
...
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