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
2970dd7d
Commit
2970dd7d
authored
Jul 08, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
c7f1e3c9
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
145 additions
and
29 deletions
+145
-29
wcfs/internal/xbtree/xbtreetest/kvdiff.go
wcfs/internal/xbtree/xbtreetest/kvdiff.go
+4
-4
wcfs/internal/xbtree/xbtreetest/kvdiff_test.go
wcfs/internal/xbtree/xbtreetest/kvdiff_test.go
+1
-1
wcfs/internal/xbtree/xbtreetest/rtree.go
wcfs/internal/xbtree/xbtreetest/rtree.go
+1
-1
wcfs/internal/xbtree/xbtreetest/treeenv.go
wcfs/internal/xbtree/xbtreetest/treeenv.go
+6
-6
wcfs/internal/xbtree/xbtreetest/treegen.go
wcfs/internal/xbtree/xbtreetest/treegen.go
+5
-5
wcfs/internal/xbtree/xbtreetest/treegen.py
wcfs/internal/xbtree/xbtreetest/treegen.py
+23
-2
wcfs/internal/xbtree/δbtail.go
wcfs/internal/xbtree/δbtail.go
+0
-1
wcfs/internal/zdata/δftail_test.go
wcfs/internal/zdata/δftail_test.go
+81
-9
wcfs/internal/zdata/δftail_x_test.go
wcfs/internal/zdata/δftail_x_test.go
+24
-0
No files found.
wcfs/internal/xbtree/xbtreetest/kvdiff.go
View file @
2970dd7d
...
...
@@ -26,13 +26,13 @@ import (
"strings"
)
//
kvd
iff returns difference in between kv1 and kv2.
//
KVD
iff returns difference in between kv1 and kv2.
const
DEL
=
"ø"
// DEL means deletion
type
Δstring
struct
{
Old
string
New
string
}
func
kvd
iff
(
kv1
,
kv2
map
[
Key
]
string
)
map
[
Key
]
Δstring
{
func
KVD
iff
(
kv1
,
kv2
map
[
Key
]
string
)
map
[
Key
]
Δstring
{
delta
:=
map
[
Key
]
Δstring
{}
keys
:=
setKey
{}
for
k
:=
range
kv1
{
keys
.
Add
(
k
)
}
...
...
@@ -51,8 +51,8 @@ func kvdiff(kv1, kv2 map[Key]string) map[Key]Δstring {
return
delta
}
//
kvt
xt returns string representation of {} kv.
func
kvt
xt
(
kv
map
[
Key
]
string
)
string
{
//
KVT
xt returns string representation of {} kv.
func
KVT
xt
(
kv
map
[
Key
]
string
)
string
{
if
len
(
kv
)
==
0
{
return
"ø"
}
...
...
wcfs/internal/xbtree/xbtreetest/kvdiff_test.go
View file @
2970dd7d
...
...
@@ -27,7 +27,7 @@ import (
func
TestKVDiff
(
t
*
testing
.
T
)
{
kv1
:=
map
[
Key
]
string
{
1
:
"a"
,
3
:
"c"
,
4
:
"d"
}
kv2
:=
map
[
Key
]
string
{
1
:
"b"
,
4
:
"d"
,
5
:
"e"
}
got
:=
kvd
iff
(
kv1
,
kv2
)
got
:=
KVD
iff
(
kv1
,
kv2
)
want
:=
map
[
Key
]
Δstring
{
1
:
{
"a"
,
"b"
},
3
:
{
"c"
,
DEL
},
5
:
{
DEL
,
"e"
}}
if
!
reflect
.
DeepEqual
(
got
,
want
)
{
t
.
Fatalf
(
"error:
\n
got: %v
\n
want: %v"
,
got
,
want
)
...
...
wcfs/internal/xbtree/xbtreetest/rtree.go
View file @
2970dd7d
...
...
@@ -104,5 +104,5 @@ func (xkv RBucketSet) Flatten() map[Key]string {
}
func
(
b
*
RBucket
)
String
()
string
{
return
fmt
.
Sprintf
(
"%sB%s{%s}"
,
b
.
Keycov
,
b
.
Oid
,
kvt
xt
(
b
.
KV
))
return
fmt
.
Sprintf
(
"%sB%s{%s}"
,
b
.
Keycov
,
b
.
Oid
,
KVT
xt
(
b
.
KV
))
}
wcfs/internal/xbtree/xbtreetest/treeenv.go
View file @
2970dd7d
...
...
@@ -35,7 +35,7 @@ import (
// T is tree-based testing environment.
//
// It combines TreeSrv and client side access to ZODB with committed trees.
// It should be created it
via
NewT().
// It should be created it NewT().
type
T
struct
{
*
testing
.
T
...
...
@@ -56,7 +56,7 @@ type Commit struct {
ΔZ
*
zodb
.
EventCommit
// raw ZODB changes; δZ.tid == at
Xkv
RBucketSet
// full tree state as of @at
Δxkv
map
[
Key
]
Δstring
// full tree-diff against parent
zb
lkDataTab
map
[
zodb
.
Oid
]
string
// full snapshot of all ZBlk data @at
ZB
lkDataTab
map
[
zodb
.
Oid
]
string
// full snapshot of all ZBlk data @at
// δzblkData map[zodb.Oid]Δstring // full diff for zblkData against parent XXX ?
}
...
...
@@ -97,7 +97,7 @@ func NewT(t *testing.T) *T {
Prev
:
nil
,
At
:
head
,
Xkv
:
xGetTree
(
tt
.
DB
,
head
,
tt
.
Root
()),
zb
lkDataTab
:
xGetBlkDataTab
(
tt
.
DB
,
head
),
ZB
lkDataTab
:
xGetBlkDataTab
(
tt
.
DB
,
head
),
ΔZ
:
nil
,
Δxkv
:
nil
,
}
...
...
@@ -182,12 +182,12 @@ func (t *T) CommitTree(tree string) *Commit {
At
:
δZ
.
Tid
,
ΔZ
:
δZ
,
Xkv
:
xkv
,
zb
lkDataTab
:
xGetBlkDataTab
(
t
.
DB
,
δZ
.
Tid
),
ZB
lkDataTab
:
xGetBlkDataTab
(
t
.
DB
,
δZ
.
Tid
),
}
tprev
:=
t
.
Head
()
ttree
.
Prev
=
tprev
ttree
.
Δxkv
=
kvd
iff
(
tprev
.
Xkv
.
Flatten
(),
ttree
.
Xkv
.
Flatten
())
ttree
.
Δxkv
=
KVD
iff
(
tprev
.
Xkv
.
Flatten
(),
ttree
.
Xkv
.
Flatten
())
t
.
commitv
=
append
(
t
.
commitv
,
ttree
)
...
...
@@ -249,7 +249,7 @@ func (t *Commit) XGetBlkData(oid zodb.Oid) string {
if
oid
==
VDEL
{
return
DEL
}
data
,
ok
:=
t
.
zb
lkDataTab
[
oid
]
data
,
ok
:=
t
.
ZB
lkDataTab
[
oid
]
if
!
ok
{
exc
.
Raisef
(
"getBlkData ZBlk<%s> @%s: no such ZBlk"
,
oid
,
t
.
At
)
}
...
...
wcfs/internal/xbtree/xbtreetest/treegen.go
View file @
2970dd7d
...
...
@@ -69,8 +69,8 @@ type AllStructsSrv struct {
*
TreeGenSrv
}
//
S
tartTreeGenSrv spawns `treegen ...` server.
func
S
tartTreeGenSrv
(
argv
...
string
)
(
_
*
TreeGenSrv
,
hello
string
,
err
error
)
{
//
s
tartTreeGenSrv spawns `treegen ...` server.
func
s
tartTreeGenSrv
(
argv
...
string
)
(
_
*
TreeGenSrv
,
hello
string
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"treesrv %v: start"
,
argv
)
// spawn `treegen ...`
...
...
@@ -125,7 +125,7 @@ func (tg *TreeGenSrv) Close() (err error) {
// StartTreeSrv spawns `treegen trees` server.
func
StartTreeSrv
(
zurl
string
)
(
_
*
TreeSrv
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"tree.srv %s: start"
,
zurl
)
tgSrv
,
hello
,
err
:=
S
tartTreeGenSrv
(
"trees"
,
zurl
)
tgSrv
,
hello
,
err
:=
s
tartTreeGenSrv
(
"trees"
,
zurl
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -160,7 +160,7 @@ func StartTreeSrv(zurl string) (_ *TreeSrv, err error) {
func
StartAllStructsSrv
()
(
_
*
AllStructsSrv
,
err
error
)
{
defer
xerr
.
Context
(
&
err
,
"allstructs.srv: start"
)
tgSrv
,
hello
,
err
:=
S
tartTreeGenSrv
(
"allstructs"
)
tgSrv
,
hello
,
err
:=
s
tartTreeGenSrv
(
"allstructs"
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -209,7 +209,7 @@ func (tg *TreeSrv) Commit(tree string) (_ zodb.Tid, err error) {
// AllStructs returns response from `treegen allstructs`
func
(
tg
*
AllStructsSrv
)
AllStructs
(
kv
map
[
Key
]
string
,
maxdepth
,
maxsplit
,
n
int
,
seed
int64
)
(
_
[]
string
,
err
error
)
{
req
:=
fmt
.
Sprintf
(
"%d %d %d/%d %s"
,
maxdepth
,
maxsplit
,
n
,
seed
,
kvt
xt
(
kv
))
req
:=
fmt
.
Sprintf
(
"%d %d %d/%d %s"
,
maxdepth
,
maxsplit
,
n
,
seed
,
KVT
xt
(
kv
))
defer
xerr
.
Contextf
(
&
err
,
"allstructs.srv: %s "
,
req
)
_
,
err
=
io
.
WriteString
(
tg
.
pyin
,
req
+
"
\n
"
)
...
...
wcfs/internal/xbtree/xbtreetest/treegen.py
View file @
2970dd7d
...
...
@@ -20,7 +20,7 @@
# See https://www.nexedi.com/licensing for rationale and options.
"""Program treegen provides infrastructure to generate ZODB BTree states.
It is used as helper for ΔBtail tests.
It is used as helper for ΔBtail
and ΔFtail
tests.
The following subcommands are provided:
...
...
@@ -108,6 +108,9 @@ session example:
T3/T-T/B1:a,2:b-B3:c
# ----
XXX ΔFtail support
--------
(*) 300-500ms, see https://github.com/pypa/setuptools/issues/510.
...
...
@@ -127,7 +130,7 @@ import random
import
six
from
wendelin.wcfs.internal
import
xbtree
,
xbtree_test
from
wendelin.bigfile.file_zodb
import
ZBlk
from
wendelin.bigfile.file_zodb
import
ZBlk
,
ZBigFile
from
zodbtools.util
import
storageFromURL
,
ashex
from
persistent
import
CHANGED
...
...
@@ -197,6 +200,8 @@ def TreesSrv(zstor, r):
defer
(
zctx
.
close
)
ztree
=
zctx
.
root
[
'treegen/tree'
]
=
LOBTree
()
zfile
=
zctx
.
root
[
'treegen/file'
]
=
ZBigFile
(
blksize
=
4
)
# for ΔFtail tests
zfile
.
blktab
=
ztree
head
=
commit
(
'treegen/tree: init'
)
xprint
(
"tree.srv start @%s root=%s"
%
(
ashex
(
head
),
ashex
(
ztree
.
_p_oid
)))
treetxtPrev
=
zctx
.
ztreetxt
(
ztree
)
...
...
@@ -210,6 +215,22 @@ def TreesSrv(zstor, r):
xprint
(
"%s"
%
ashex
(
head
))
continue
# t... D... commands to natively commit updates to tree and values
if
treetxt
.
startswith
(
't'
):
t
,
D
=
treetxt
.
split
()
assert
D
.
startswith
(
'D'
)
kv
=
kvDecode
(
t
[
1
:],
zctx
.
vdecode
)
zv
=
kvDecode
(
D
[
1
:],
lambda
vtxt
:
vtxt
)
zdataTab
=
zctx
.
root
[
'treegen/values'
]
patch
(
ztree
,
diff
(
ztree
,
kv
),
kv
)
patch
(
zdataTab
,
diff
(
zdataTab
,
zv
),
zv
)
# XXX v->ZBlk(v)
head
=
commit
(
subj
)
xprint
(
"%s"
%
ashex
(
head
))
continue
# everything else is considerd to be a tree topology
# mark tree as changed if the same topology is requested twice.
# this ensures we can actually make a non-empty commit
if
treetxt
==
treetxtPrev
:
...
...
wcfs/internal/xbtree/δbtail.go
View file @
2970dd7d
...
...
@@ -84,7 +84,6 @@ const debugΔBtail = false
// XXX -> multiple readers / single writer?
//
// See also zodb.ΔTail
// XXX naming -> ΔBTail ?
type
ΔBtail
struct
{
// raw ZODB changes; Kept to rebuild .vδTbyRoot after new Track.
// includes all changed objects, not only tracked ones.
...
...
wcfs/internal/zdata/δftail_test.go
View file @
2970dd7d
...
...
@@ -18,24 +18,38 @@
// See https://www.nexedi.com/licensing for rationale and options.
package
zdata
// tests for δftail.go
//
// This are the main tests for ΔFtail functionality.
// XXX overview
// XXX we assume that ΔBtail works correctly (this is covered by ΔBtail tests)
// XXX -> no need to exercise many different topologies and tracking sets.
import
(
"context"
"fmt"
"testing"
"lab.nexedi.com/kirr/go123/exc"
"lab.nexedi.com/kirr/neo/go/transaction"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/set"
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xbtree/xbtreetest"
)
type
setStr
=
set
.
Str
// ΔFTestEntry represents one entry in ΔFtail tests.
type
ΔFTestEntry
struct
{
δblkTab
map
[
int64
]
string
// change
in tree part
{} #blk -> ZBlk<oid>
δblkData
setStr
// change to ZBlk objects
δblkTab
map
[
int64
]
string
// change
s in tree part
{} #blk -> ZBlk<oid>
δblkData
setStr
// change
s
to ZBlk objects
}
func
TestΔFtail
(
t
*
testing
.
T
)
{
func
TestΔFtail
(
t_
*
testing
.
T
)
{
t
:=
xbtreetest
.
NewT
(
t_
)
X
:=
exc
.
Raiseif
// δT is shorthand to create δblkTab.
type
δT
=
map
[
int64
]
string
...
...
@@ -56,14 +70,49 @@ func TestΔFtail(t *testing.T) {
{
δT
{
2
:
c
},
δD
(
a
,
b
)},
}
vδf
:=
[]
ΔFile
{}
// (rev↑, {}blk) XXX +.Size?
blkTab
:=
map
[
int64
]
string
{}
// #blk -> ZBlk<oid>
Zinblk
:=
map
[
string
]
setI64
{}
// ZBlk<oid> -> which #blk refer to it
for
_
,
test
:=
range
testv
{
δftail
:=
NewΔFtail
(
t
.
Head
()
.
At
,
t
.
DB
)
// load zfile via root['treegen/file']
txn
,
ctx
:=
transaction
.
New
(
context
.
Background
())
defer
txn
.
Abort
()
zconn
,
err
:=
t
.
DB
.
Open
(
ctx
,
&
zodb
.
ConnOptions
{
At
:
t
.
Head
()
.
At
});
X
(
err
)
xzroot
,
err
:=
zconn
.
Get
(
ctx
,
0
);
X
(
err
)
zroot
:=
xzroot
.
(
*
zodb
.
Map
)
err
=
zroot
.
PActivate
(
ctx
);
X
(
err
)
defer
zroot
.
PDeactivate
()
zfile
:=
zroot
.
Data
[
"treegen/file"
]
.
(
*
ZBigFile
)
err
=
zfile
.
PActivate
(
ctx
);
X
(
err
)
defer
zfile
.
PDeactivate
()
if
treeOid
:=
zfile
.
blktab
.
POid
();
treeOid
!=
t
.
Root
()
{
t
.
Fatalf
(
"BUG: zfile.blktab (%s) != treeroot (%s)"
,
treeOid
,
t
.
Root
())
}
// track zfile[-∞,∞) from the beginning
// this should make ΔFtail to see all zfile changes
size
,
path
,
err
:=
zfile
.
Size
(
ctx
);
X
(
err
)
δftail
.
Track
(
zfile
,
/*blk*/
-
1
,
path
,
/*zblk*/
nil
)
if
size
!=
0
{
t
.
Fatalf
(
"BUG: zfile is not initially empty: size=%d"
,
size
)
}
// data built via applying changes from testv
vδf
:=
[]
ΔFile
{}
// (rev↑, {}blk) XXX +.Size?
blkTab
:=
map
[
int64
]
string
{}
// #blk -> ZBlk<oid>
blkData
:=
map
[
string
]
string
{}
// ZBlk<oid> -> data
Zinblk
:=
map
[
string
]
setI64
{}
// ZBlk<oid> -> which #blk refer to it
// initialize blkData from root['treegen/values']
for
/*oid*/
_
,
zblk
:=
range
t
.
Head
()
.
ZBlkDataTab
{
// treegen initializes values[x] = ZBlk(x)
blkData
[
zblk
]
=
zblk
}
for
i
,
test
:=
range
testv
{
δf
:=
setI64
{}
// rebuild blkTab/Zinblk
for
blk
,
zblk
:=
range
test
.
δblkTab
{
// rebuild blkTab/Zinblk
zprev
,
ok
:=
blkTab
[
blk
]
if
ok
{
delete
(
Zinblk
[
zprev
],
blk
)
...
...
@@ -87,8 +136,16 @@ func TestΔFtail(t *testing.T) {
}
}
//
update δf due to change in ZBlk d
ata
//
rebuild blkD
ata
for
zblk
:=
range
test
.
δblkData
{
data
,
ok
:=
blkData
[
zblk
]
// e.g. a -> a2
if
!
ok
{
t
.
Fatalf
(
"BUG: blk %s not in blkData
\n
blkData: %v"
,
zblk
,
blkData
)
}
data
=
fmt
.
Sprintf
(
"%s%d"
,
data
[
:
1
],
i
)
// e.g. a4
blkData
[
zblk
]
=
data
// update δf due to change in ZBlk data
for
blk
:=
range
Zinblk
[
zblk
]
{
δf
.
Add
(
blk
)
}
...
...
@@ -99,8 +156,23 @@ func TestΔFtail(t *testing.T) {
Blocks
:
δf
,
Size
:
false
/*XXX*/
,
})
// commit updated blkTab + blkData
tdTxt
:=
fmt
.
Sprintf
(
"t%s D%s"
,
xbtreetest
.
KVTxt
(
blkTab
),
blkDataTxt
(
blkData
))
commit
:=
t
.
CommitTree
(
tdTxt
)
fmt
.
Printf
(
"@%s %s
\n
"
,
commit
.
At
,
commit
.
Tree
)
// XXX assert
}
}
// XXX TestΔFtailRandom(t *testing.T) {
//}
// blkDataTxt returns string representation of {} blkData.
//
// it is similar to xbtreetest.KVTxt but uses string instead of Key for keys.
func
blkDataTxt
(
dataTab
map
[
string
]
string
)
string
{
panic
(
"TODO"
)
}
wcfs/internal/zdata/δftail_x_test.go
0 → 100644
View file @
2970dd7d
// Copyright (C) 2021 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
package
zdata_test
import
(
_
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/xbtree/xbtreetest/init"
)
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