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
024dde83
Commit
024dde83
authored
Jul 20, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
190617f5
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
238 additions
and
17 deletions
+238
-17
wcfs/internal/xbtree/δbtail.go
wcfs/internal/xbtree/δbtail.go
+71
-1
wcfs/internal/zdata/zblk.go
wcfs/internal/zdata/zblk.go
+23
-6
wcfs/internal/zdata/δftail.go
wcfs/internal/zdata/δftail.go
+142
-8
wcfs/internal/zdata/δftail_test.go
wcfs/internal/zdata/δftail_test.go
+2
-2
No files found.
wcfs/internal/xbtree/δbtail.go
View file @
024dde83
...
...
@@ -760,6 +760,76 @@ func (δTtail *ΔTtail) forgetPast(revCut zodb.Tid) {
}
// GetAt tries to retrieve root[key]@at from δBtail data.
//
// If δBtail has δB entry that covers root[key]@at, corresponding value
// (VDEL means deletion) and valueExact=true are returned. If δBtail data
// allows to determine revision of root[key]@at value, corresponding revision
// and revExact=true are returned. If revision of root[key]@at cannot be
// determined (rev=δBtail.Tail, revExact=false) are returned.
//
// If δBtail has no δB entry that covers root[key]@at, return is
//
// (value=VDEL, valueExact=false, rev=δBtail.Tail, revExact=false)
//
// .rev and exact=true are returned:
//
// (δB[root/key].δvalue.New, δB.rev, exact=true)
//
// If δBtail has no δB entry for root[key] with .rev ≤ @at, return is
//
// (VDEL, δBtail.Tail, exact=false)
//
// key must be tracked
// at must ∈ (tail, head]
func
(
δBtail
*
ΔBtail
)
GetAt
(
root
zodb
.
Oid
,
key
Key
,
at
zodb
.
Tid
)
(
value
Value
,
rev
zodb
.
Tid
,
valueExact
,
revExact
bool
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"δBtail: root<%s>: get %d @%s"
,
root
,
key
,
at
)
// XXX key not tracked -> panic
tail
:=
δBtail
.
Tail
()
head
:=
δBtail
.
Head
()
if
!
(
tail
<
at
&&
at
<=
head
)
{
panicf
(
"at out of bounds: at: @%s, (tail, head] = (@%s, @%s]"
,
at
,
tail
,
head
)
}
// XXX locking
value
=
VDEL
valueExact
=
false
rev
=
tail
revExact
=
false
err
=
δBtail
.
rebuild1IfNeeded
(
root
)
if
err
!=
nil
{
return
value
,
rev
,
valueExact
,
revExact
,
err
}
δTtail
:=
δBtail
.
vδTbyRoot
[
root
]
if
δTtail
==
nil
{
panicf
(
"δBtail: root<%s> not tracked"
,
root
)
}
// XXX -> index lastXXXOf(key) | linear scan ↓ looking for change <= at
for
i
:=
len
(
δTtail
.
vδT
)
-
1
;
i
>=
0
;
i
--
{
δT
:=
δTtail
.
vδT
[
i
]
δvalue
,
ok_
:=
δT
.
ΔKV
[
key
]
if
ok_
{
valueExact
=
true
if
δT
.
Rev
>
at
{
value
=
δvalue
.
Old
}
else
{
value
=
δvalue
.
New
rev
=
δT
.
Rev
revExact
=
true
break
}
}
}
return
value
,
rev
,
valueExact
,
revExact
,
nil
}
// XXX kill
// Get returns root[key] as of @at database state plus revision that changed it.
//
// if revExact=False - rev is upper estimate for the revision.
...
...
@@ -768,7 +838,7 @@ func (δTtail *ΔTtail) forgetPast(revCut zodb.Tid) {
// at must ∈ (tail, head]
//
// XXX root -> Oid ?
func
(
δBtail
*
ΔBtail
)
GetAt
(
ctx
context
.
Context
,
root
*
Tree
,
key
Key
,
at
zodb
.
Tid
)
(
value
Value
,
ok
bool
,
rev
zodb
.
Tid
,
revExact
bool
,
err
error
)
{
func
(
δBtail
*
ΔBtail
)
XX
GetAt
(
ctx
context
.
Context
,
root
*
Tree
,
key
Key
,
at
zodb
.
Tid
)
(
value
Value
,
ok
bool
,
rev
zodb
.
Tid
,
revExact
bool
,
err
error
)
{
rootOid
:=
root
.
POid
()
defer
xerr
.
Contextf
(
&
err
,
"δBtail: root<%s>: get %d @%s"
,
rootOid
,
key
,
at
)
// XXX key not tracked -> panic
...
...
wcfs/internal/zdata/zblk.go
View file @
024dde83
...
...
@@ -390,9 +390,9 @@ func (bf *zBigFileState) PySetState(pystate interface{}) (err error) {
return
fmt
.
Errorf
(
"blksize: must be > 0; got %d"
,
blksize
)
}
blktab
,
ok
:=
t
[
1
]
.
(
*
btree
.
LOBTree
)
if
!
ok
{
return
fmt
.
Errorf
(
"blktab: expect LOBTree; got %s"
,
xzodb
.
TypeOf
(
t
[
1
]))
blktab
,
err
:=
vBlktab
(
t
[
1
]
)
if
err
!=
nil
{
return
err
}
bf
.
blksize
=
blksize
...
...
@@ -437,9 +437,9 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath
return
make
([]
byte
,
bf
.
blksize
),
treePath
,
nil
,
blkRevMax
,
nil
}
zblk
,
ok
=
xzblk
.
(
ZB
lk
)
if
!
ok
{
return
nil
,
nil
,
nil
,
0
,
fmt
.
Errorf
(
"expect ZBlk*; got %s"
,
xzodb
.
TypeOf
(
xzblk
))
zblk
,
err
=
vZBlk
(
xzb
lk
)
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
0
,
err
}
blkdata
,
zblkrev
,
err
:=
zblk
.
LoadBlkData
(
ctx
)
...
...
@@ -493,6 +493,23 @@ func (bf *ZBigFile) Size(ctx context.Context) (_ int64, treePath []btree.LONode,
return
size
,
treePath
,
nil
}
// vZBlk checks and converts xzblk to a ZBlk object.
func
vZBlk
(
xzblk
interface
{})
(
ZBlk
,
error
)
{
zblk
,
ok
:=
xzblk
.
(
ZBlk
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"expect ZBlk*; got %s"
,
xzodb
.
TypeOf
(
xzblk
))
}
return
zblk
,
nil
}
// vBlktab checks and converts xblktab to LOBTree object.
func
vBlktab
(
xblktab
interface
{})
(
*
btree
.
LOBTree
,
error
)
{
blktab
,
ok
:=
xblktab
.
(
*
btree
.
LOBTree
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"blktab: expect LOBTree; got %s"
,
xzodb
.
TypeOf
(
xblktab
))
}
return
blktab
,
nil
}
// ----------------------------------------
...
...
wcfs/internal/zdata/δftail.go
View file @
024dde83
...
...
@@ -67,7 +67,7 @@ type setOid = set.Oid
// .ForgetPast(revCut) - forget changes past revCut
// .SliceByRev(lo, hi) -> []δF - query for all files changes with rev ∈ (lo, hi]
// .SliceByFileRev(file, lo, hi) -> []δfile - query for changes of file with rev ∈ (lo, hi]
// .
LastBlkRev(file, #blk, at)
- query for what is last revision that changed
// .
BlkRevAt(file, #blk, at)
- query for what is last revision that changed
// file[#blk] as of @at database state.
//
// where δfile represents a change to one file
...
...
@@ -708,27 +708,161 @@ func (δFtail *ΔFtail) SliceByFileRev(zfile *ZBigFile, lo, hi zodb.Tid) /*reado
return
vδf
}
// XXX rename -> BlkRevAt
// BlkRevAt returns last revision that changed file[blk] as of @at database state.
//
// if exact=False - what is returned is only an upper bound for last block revision.
//
// zf must be any checkout from (tail, head]
// at must ∈ (tail, head]
// blk must be tracked
//
// XXX +ctx, error rebuild []δF here
func
(
δFtail
*
ΔFtail
)
BlkRevAt
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
)
{
rev
,
exact
,
err
:=
δFtail
.
_BlkRevAt
(
ctx
,
zf
,
blk
,
at
)
if
err
!=
nil
{
panic
(
err
)
// XXX
}
return
rev
,
exact
}
func
(
δFtail
*
ΔFtail
)
_BlkRevAt
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"blkrev f<%s> #%d @%s"
,
zf
.
POid
(),
blk
,
at
)
//fmt.Printf("\nblkrev #%d @%s\n", blk, at)
// assert at ∈ (tail, head]
tail
:=
δFtail
.
Tail
()
head
:=
δFtail
.
Head
()
if
!
(
tail
<
at
&&
at
<=
head
)
{
panicf
(
"at out of bounds: at: @%s, (tail, head] = (@%s, @%s]"
,
at
,
tail
,
head
)
}
// assert zf.at ∈ (tail, head]
zconn
:=
zf
.
PJar
()
zconnAt
:=
zconn
.
At
()
if
!
(
tail
<
zconnAt
&&
zconnAt
<=
head
)
{
panicf
(
"zconn.at out of bounds: zconn.at: @%s, (tail, head] = (@%s, @%s]"
,
zconnAt
,
tail
,
head
)
}
// XXX locking
δftail
,
err
:=
δFtail
.
rebuildIfNeeded
(
zf
.
POid
())
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
}
// find epoch that covers at and associated blktab root/object
vδE
:=
δftail
.
vδE
//fmt.Printf(" vδE: %v\n", vδE)
l
:=
len
(
vδE
)
i
:=
sort
.
Search
(
l
,
func
(
i
int
)
bool
{
return
at
<
vδE
[
i
]
.
Rev
})
// vδE[i] is next epoch
// vδE[i-1] is epoch that covers at
// root
var
root
zodb
.
Oid
if
i
==
l
{
root
=
δftail
.
root
}
else
{
root
=
vδE
[
i
]
.
oldRoot
}
// epoch
var
epoch
zodb
.
Tid
i
--
if
i
<
0
{
// i<0 - first epoch (no explicit start) - use δFtail.tail as lo
epoch
=
δFtail
.
Tail
()
}
else
{
epoch
=
vδE
[
i
]
.
Rev
}
//fmt.Printf(" epoch: @%s root: %s\n", epoch, root)
if
root
==
xbtree
.
VDEL
{
return
epoch
,
true
,
nil
}
zblk
,
tabRev
,
zblkExact
,
tabRevExact
,
err
:=
δFtail
.
δBtail
.
GetAt
(
root
,
blk
,
at
)
//fmt.Printf(" GetAt #%d @%s -> %s(%v), @%s(%v)\n", blk, at, zblk, zblkExact, tabRev, tabRevExact)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
}
if
tabRev
<
epoch
{
tabRev
=
epoch
tabRevExact
=
true
}
// if δBtail does not have entry that covers root[blk] - get it
// through zconn that has any .at ∈ (tail, head].
if
!
zblkExact
{
xblktab
,
err
:=
zconn
.
Get
(
ctx
,
root
)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
}
blktab
,
err
:=
vBlktab
(
xblktab
)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
}
xzblkObj
,
ok
,
err
:=
blktab
.
Get
(
ctx
,
blk
)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
}
if
!
ok
{
zblk
=
xbtree
.
VDEL
}
else
{
zblkObj
,
err
:=
vZBlk
(
xzblkObj
)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
fmt
.
Errorf
(
"blktab<%s>[#%d]: %s"
,
root
,
blk
,
err
)
}
zblk
=
zblkObj
.
POid
()
}
}
// block was removed
if
zblk
==
xbtree
.
VDEL
{
return
tabRev
,
tabRevExact
,
nil
}
// blktab[blk] was changed to point to a zblk @tabRev.
// blk revision is max rev and when zblk changed last in (rev, at] range.
zblkRev
,
zblkRevExact
:=
δFtail
.
δBtail
.
ΔZtail
()
.
LastRevOf
(
zblk
,
at
)
//fmt.Printf(" ZRevOf %s @%s -> @%s, %v\n", zblk, at, zblkRev, zblkRevExact)
if
zblkRev
>
tabRev
{
return
zblkRev
,
zblkRevExact
,
nil
}
else
{
return
tabRev
,
tabRevExact
,
nil
}
}
// XXX kill
// LastBlkRev returns last revision that changed file[blk] as of @at database state.
//
// if exact=False - what is returned is only an upper bound for last block revision.
//
// zf must be from @head
// zf must be from @head
.
// at must ∈ (tail, head]
// blk must be tracked
//
// XXX +ctx, error rebuild []δF here
func
(
δFtail
*
ΔFtail
)
LastBlkRev
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
)
{
rev
,
exact
,
err
:=
δFtail
.
_LastBlkRev
(
ctx
,
zf
,
blk
,
at
)
func
(
δFtail
*
ΔFtail
)
__
LastBlkRev
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
)
{
rev
,
exact
,
err
:=
δFtail
.
_
__
LastBlkRev
(
ctx
,
zf
,
blk
,
at
)
if
err
!=
nil
{
panic
(
err
)
// XXX
}
return
rev
,
exact
}
func
(
δFtail
*
ΔFtail
)
_LastBlkRev
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
,
err
error
)
{
func
(
δFtail
*
ΔFtail
)
_
__
LastBlkRev
(
ctx
context
.
Context
,
zf
*
ZBigFile
,
blk
int64
,
at
zodb
.
Tid
)
(
_
zodb
.
Tid
,
exact
bool
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"blkrev f<%s> #%d @%s"
,
zf
.
POid
(),
blk
,
at
)
//fmt.Printf("\nblkrev #%d @%s\n", blk, at)
// XXX assert at ∈ (tail, head]
// XXX assert zf.at == head (!)
// XXX locking
δftail
,
err
:=
δFtail
.
rebuildIfNeeded
(
zf
.
POid
())
...
...
@@ -780,7 +914,7 @@ func (δFtail *ΔFtail) _LastBlkRev(ctx context.Context, zf *ZBigFile, blk int64
//fmt.Printf(" epoch: @%s root: %s\n", epoch, root)
// get to rootObj (NOTE @head, because it is ΔBtail.GetAt requirement)
// get to rootObj (NOTE @head, because it is ΔBtail.GetAt requirement)
XXX
if
rootObj
==
nil
&&
root
!=
xbtree
.
VDEL
{
zconn
:=
zf
.
PJar
()
xrootObj
,
err
:=
zconn
.
Get
(
ctx
,
root
)
...
...
@@ -800,7 +934,7 @@ func (δFtail *ΔFtail) _LastBlkRev(ctx context.Context, zf *ZBigFile, blk int64
var
tabRev
zodb
.
Tid
var
tabRevExact
,
ok
bool
if
rootObj
!=
nil
{
zblkOid
,
ok
,
tabRev
,
tabRevExact
,
err
=
δFtail
.
δBtail
.
GetAt
(
ctx
,
rootObj
,
blk
,
at
)
zblkOid
,
ok
,
tabRev
,
tabRevExact
,
err
=
δFtail
.
δBtail
.
XX
GetAt
(
ctx
,
rootObj
,
blk
,
at
)
//fmt.Printf(" GetAt #%d @%s -> %s, %v, @%s, %v\n", blk, at, zblkOid, ok, tabRev, tabRevExact)
if
err
!=
nil
{
return
zodb
.
InvalidTid
,
false
,
err
...
...
wcfs/internal/zdata/δftail_test.go
View file @
024dde83
...
...
@@ -543,7 +543,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
}
//
LastBlkRev
//
BlkRevAt
blkv
:=
[]
int64
{}
// all blocks
if
l
:=
len
(
vδf
);
l
>
0
{
...
...
@@ -560,7 +560,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
at
:=
vδf
[
j
]
.
Rev
blkRev
:=
blkRevAt
[
at
]
for
_
,
blk
:=
range
blkv
{
rev
,
exact
:=
δFtail
.
LastBlkRev
(
ctx
,
zfile
,
blk
,
at
)
rev
,
exact
:=
δFtail
.
BlkRevAt
(
ctx
,
zfile
,
blk
,
at
)
revOK
,
ok
:=
blkRev
[
blk
]
if
!
ok
{
k
:=
len
(
epochv
)
-
1
...
...
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