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
dac682a1
Commit
dac682a1
authored
Apr 09, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
a1299792
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
69 additions
and
80 deletions
+69
-80
wcfs/wcfs.go
wcfs/wcfs.go
+1
-1
wcfs/zblk.go
wcfs/zblk.go
+21
-74
wcfs/δbtail_test.go
wcfs/δbtail_test.go
+2
-2
wcfs/δftail.go
wcfs/δftail.go
+45
-3
No files found.
wcfs/wcfs.go
View file @
dac682a1
...
@@ -1472,7 +1472,7 @@ func (w *Watch) _pin(ctx context.Context, blk int64, rev zodb.Tid) (err error) {
...
@@ -1472,7 +1472,7 @@ func (w *Watch) _pin(ctx context.Context, blk int64, rev zodb.Tid) (err error) {
// XXX do we really need to use/propagate caller context here? ideally update
// XXX do we really need to use/propagate caller context here? ideally update
// watchers should be synchronous, and in practice we just use 30s timeout.
// watchers should be synchronous, and in practice we just use 30s timeout.
// Should a READ interrupt cause watch update failure? -> probably no
// Should a READ interrupt cause watch update failure? -> probably no
func
(
f
*
BigFile
)
readPinWatchers
(
ctx
context
.
Context
,
blk
int64
,
treepath
[]
btree
.
LONode
,
zblk
z
Blk
,
blkrevMax
zodb
.
Tid
)
{
func
(
f
*
BigFile
)
readPinWatchers
(
ctx
context
.
Context
,
blk
int64
,
treepath
[]
btree
.
LONode
,
zblk
Z
Blk
,
blkrevMax
zodb
.
Tid
)
{
// only head/ is being watched for
// only head/ is being watched for
if
f
.
head
.
rev
!=
0
{
if
f
.
head
.
rev
!=
0
{
return
return
...
...
wcfs/zblk.go
View file @
dac682a1
...
@@ -55,9 +55,10 @@ import (
...
@@ -55,9 +55,10 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/pycompat"
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/pycompat"
)
)
//
z
Blk is the interface that every ZBlk* block implements.
//
Z
Blk is the interface that every ZBlk* block implements.
type
z
Blk
interface
{
type
Z
Blk
interface
{
zodb
.
IPersistent
zodb
.
IPersistent
_IZBlkInΔFtail
// loadBlkData loads from database and returns data block stored by this ZBlk.
// loadBlkData loads from database and returns data block stored by this ZBlk.
//
//
...
@@ -66,82 +67,17 @@ type zBlk interface {
...
@@ -66,82 +67,17 @@ type zBlk interface {
//
//
// returns data and revision of ZBlk.
// returns data and revision of ZBlk.
loadBlkData
(
ctx
context
.
Context
)
(
data
[]
byte
,
rev
zodb
.
Tid
,
_
error
)
loadBlkData
(
ctx
context
.
Context
)
(
data
[]
byte
,
rev
zodb
.
Tid
,
_
error
)
// inΔFtail returns pointer to struct zblkInΔFtail embedded into this ZBlk.
inΔFtail
()
*
zblkInΔFtail
// XXX kill - in favour of inΔFtail
/*
// bindFile associates ZBlk as being used by file to store block #blk.
//
// A ZBlk may be bound to several blocks inside one file, and to
// several files.
//
// The information is preserved even when ZBlk comes to ghost
// state, but is lost if ZBlk is garbage collected.
//
// it is safe to call multiple bindFile simultaneously.
// it is not safe to call bindFile and boundTo simultaneously.
//
// XXX link to overview.
bindFile(file *BigFile, blk int64)
// XXX unbindFile
// XXX zfile -> bind map for it
// blkBoundTo returns ZBlk association with file(s)/#blk(s).
//
// The association returned is that was previously set by bindFile.
//
// blkBoundTo must not be called simultaneously wrt bindFile.
blkBoundTo() map[*BigFile]SetI64
*/
}
var
_
zBlk
=
(
*
ZBlk0
)(
nil
)
var
_
zBlk
=
(
*
ZBlk1
)(
nil
)
// XXX kill
/*
// ---- zBlkBase ----
// zBlkBase provides common functionality to implement ZBlk* -> zfile, #blk binding.
//
// The data stored by zBlkBase is transient - it is _not_ included into
// persistent state.
type zBlkBase struct {
bindMu sync.Mutex // used only for binding to support multiple loaders
infile map[*BigFile]SetI64 // {} file -> set(#blk)
}
// bindFile implements zBlk.
func (zb *zBlkBase) bindFile(file *BigFile, blk int64) {
zb.bindMu.Lock()
defer zb.bindMu.Unlock()
blkmap, ok := zb.infile[file]
if !ok {
blkmap = make(SetI64, 1)
if zb.infile == nil {
zb.infile = make(map[*BigFile]SetI64)
}
zb.infile[file] = blkmap
}
blkmap.Add(blk)
}
}
// blkBoundTo implementss zBlk.
var
_
ZBlk
=
(
*
ZBlk0
)(
nil
)
func (zb *zBlkBase) blkBoundTo() map[*BigFile]SetI64 {
var
_
ZBlk
=
(
*
ZBlk1
)(
nil
)
return zb.infile
}
*/
// ---- ZBlk0 ----
// ---- ZBlk0 ----
// ZBlk0 mimics ZBlk0 from python.
// ZBlk0 mimics ZBlk0 from python.
type
ZBlk0
struct
{
type
ZBlk0
struct
{
zblkInΔFtail
zodb
.
Persistent
zodb
.
Persistent
zblkInΔFtail
// NOTE py source uses bytes(buf) but on python2 it still results in str
// NOTE py source uses bytes(buf) but on python2 it still results in str
blkdata
string
blkdata
string
...
@@ -149,14 +85,17 @@ type ZBlk0 struct {
...
@@ -149,14 +85,17 @@ type ZBlk0 struct {
type
zBlk0State
ZBlk0
// hide state methods from public API
type
zBlk0State
ZBlk0
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zb
*
zBlk0State
)
DropState
()
{
func
(
zb
*
zBlk0State
)
DropState
()
{
zb
.
blkdata
=
""
zb
.
blkdata
=
""
}
}
// PyGetState implements zodb.PyStateful.
func
(
zb
*
zBlk0State
)
PyGetState
()
interface
{}
{
func
(
zb
*
zBlk0State
)
PyGetState
()
interface
{}
{
return
zb
.
blkdata
return
zb
.
blkdata
}
}
// PySetState implements zodb.PyStateful.
func
(
zb
*
zBlk0State
)
PySetState
(
pystate
interface
{})
error
{
func
(
zb
*
zBlk0State
)
PySetState
(
pystate
interface
{})
error
{
blkdata
,
ok
:=
pystate
.
(
string
)
blkdata
,
ok
:=
pystate
.
(
string
)
if
!
ok
{
if
!
ok
{
...
@@ -167,6 +106,7 @@ func (zb *zBlk0State) PySetState(pystate interface{}) error {
...
@@ -167,6 +106,7 @@ func (zb *zBlk0State) PySetState(pystate interface{}) error {
return
nil
return
nil
}
}
// loadBlkData implements _ZBlk.
func
(
zb
*
ZBlk0
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
func
(
zb
*
ZBlk0
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"ZBlk0(%s): loadBlkData"
,
zb
.
POid
())
defer
xerr
.
Contextf
(
&
err
,
"ZBlk0(%s): loadBlkData"
,
zb
.
POid
())
...
@@ -191,14 +131,17 @@ type ZData struct {
...
@@ -191,14 +131,17 @@ type ZData struct {
type
zDataState
ZData
// hide state methods from public API
type
zDataState
ZData
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zd
*
zDataState
)
DropState
()
{
func
(
zd
*
zDataState
)
DropState
()
{
zd
.
data
=
""
zd
.
data
=
""
}
}
// PyGetState implements zodb.PyStateful.
func
(
zd
*
zDataState
)
PyGetState
()
interface
{}
{
func
(
zd
*
zDataState
)
PyGetState
()
interface
{}
{
return
zd
.
data
return
zd
.
data
}
}
// PySetState implements zodb.PyStateful.
func
(
zd
*
zDataState
)
PySetState
(
pystate
interface
{})
error
{
func
(
zd
*
zDataState
)
PySetState
(
pystate
interface
{})
error
{
data
,
ok
:=
pystate
.
(
string
)
data
,
ok
:=
pystate
.
(
string
)
if
!
ok
{
if
!
ok
{
...
@@ -211,22 +154,25 @@ func (zd *zDataState) PySetState(pystate interface{}) error {
...
@@ -211,22 +154,25 @@ func (zd *zDataState) PySetState(pystate interface{}) error {
// ZBlk1 mimics ZBlk1 from python.
// ZBlk1 mimics ZBlk1 from python.
type
ZBlk1
struct
{
type
ZBlk1
struct
{
zblkInΔFtail
zodb
.
Persistent
zodb
.
Persistent
zblkInΔFtail
chunktab
*
btree
.
IOBTree
// {} offset -> ZData(chunk)
chunktab
*
btree
.
IOBTree
// {} offset -> ZData(chunk)
}
}
type
zBlk1State
ZBlk1
// hide state methods from public API
type
zBlk1State
ZBlk1
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zb
*
zBlk1State
)
DropState
()
{
func
(
zb
*
zBlk1State
)
DropState
()
{
zb
.
chunktab
=
nil
zb
.
chunktab
=
nil
}
}
// PyGetState implements zodb.PyStateful.
func
(
zb
*
zBlk1State
)
PyGetState
()
interface
{}
{
func
(
zb
*
zBlk1State
)
PyGetState
()
interface
{}
{
return
zb
.
chunktab
return
zb
.
chunktab
}
}
// PySetState implements zodb.PyStateful.
func
(
zb
*
zBlk1State
)
PySetState
(
pystate
interface
{})
error
{
func
(
zb
*
zBlk1State
)
PySetState
(
pystate
interface
{})
error
{
chunktab
,
ok
:=
pystate
.
(
*
btree
.
IOBTree
)
chunktab
,
ok
:=
pystate
.
(
*
btree
.
IOBTree
)
if
!
ok
{
if
!
ok
{
...
@@ -237,6 +183,7 @@ func (zb *zBlk1State) PySetState(pystate interface{}) error {
...
@@ -237,6 +183,7 @@ func (zb *zBlk1State) PySetState(pystate interface{}) error {
return
nil
return
nil
}
}
// loadBlkData implements ZBlk.
func
(
zb
*
ZBlk1
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
func
(
zb
*
ZBlk1
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"ZBlk1(%s): loadBlkData"
,
zb
.
POid
())
defer
xerr
.
Contextf
(
&
err
,
"ZBlk1(%s): loadBlkData"
,
zb
.
POid
())
...
@@ -416,7 +363,7 @@ type ZBigFile struct {
...
@@ -416,7 +363,7 @@ type ZBigFile struct {
type
zBigFileState
ZBigFile
// hide state methods from public API
type
zBigFileState
ZBigFile
// hide state methods from public API
// DropState implements zodb.
Stateful
.
// DropState implements zodb.
Ghostable
.
func
(
bf
*
zBigFileState
)
DropState
()
{
func
(
bf
*
zBigFileState
)
DropState
()
{
bf
.
blksize
=
0
bf
.
blksize
=
0
bf
.
blktab
=
nil
bf
.
blktab
=
nil
...
@@ -464,7 +411,7 @@ func (bf *zBigFileState) PySetState(pystate interface{}) (err error) {
...
@@ -464,7 +411,7 @@ func (bf *zBigFileState) PySetState(pystate interface{}) (err error) {
// which provides a rough upper-bound estimate for file[blk] revision.
// which provides a rough upper-bound estimate for file[blk] revision.
//
//
// TODO load into user-provided buf.
// TODO load into user-provided buf.
func
(
bf
*
ZBigFile
)
LoadBlk
(
ctx
context
.
Context
,
blk
int64
)
(
_
[]
byte
,
treePath
[]
btree
.
LONode
,
zblk
z
Blk
,
blkRevMax
zodb
.
Tid
,
err
error
)
{
func
(
bf
*
ZBigFile
)
LoadBlk
(
ctx
context
.
Context
,
blk
int64
)
(
_
[]
byte
,
treePath
[]
btree
.
LONode
,
zblk
Z
Blk
,
blkRevMax
zodb
.
Tid
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"bigfile %s: loadblk %d"
,
bf
.
POid
(),
blk
)
defer
xerr
.
Contextf
(
&
err
,
"bigfile %s: loadblk %d"
,
bf
.
POid
(),
blk
)
err
=
bf
.
PActivate
(
ctx
)
err
=
bf
.
PActivate
(
ctx
)
...
@@ -485,7 +432,7 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath
...
@@ -485,7 +432,7 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath
return
make
([]
byte
,
bf
.
blksize
),
treePath
,
nil
,
blkRevMax
,
nil
return
make
([]
byte
,
bf
.
blksize
),
treePath
,
nil
,
blkRevMax
,
nil
}
}
zblk
,
ok
=
xzblk
.
(
z
Blk
)
zblk
,
ok
=
xzblk
.
(
Z
Blk
)
if
!
ok
{
if
!
ok
{
return
nil
,
nil
,
nil
,
0
,
fmt
.
Errorf
(
"expect ZBlk*; got %s"
,
typeOf
(
xzblk
))
return
nil
,
nil
,
nil
,
0
,
fmt
.
Errorf
(
"expect ZBlk*; got %s"
,
typeOf
(
xzblk
))
}
}
...
...
wcfs/δbtail_test.go
View file @
dac682a1
...
@@ -461,7 +461,7 @@ func _xwalkDFS(ctx context.Context, lo, hi_ Key, ztree *Tree, rparent *RTree, bv
...
@@ -461,7 +461,7 @@ func _xwalkDFS(ctx context.Context, lo, hi_ Key, ztree *Tree, rparent *RTree, bv
for
_
,
__
:=
range
bentryv
{
for
_
,
__
:=
range
bentryv
{
k
:=
__
.
Key
()
k
:=
__
.
Key
()
xv
:=
__
.
Value
()
xv
:=
__
.
Value
()
zv
,
ok
:=
xv
.
(
z
Blk
)
zv
,
ok
:=
xv
.
(
Z
Blk
)
if
!
ok
{
if
!
ok
{
exc
.
Raisef
(
"[%d] -> %s; want ZBlk"
,
k
,
typeOf
(
xv
))
exc
.
Raisef
(
"[%d] -> %s; want ZBlk"
,
k
,
typeOf
(
xv
))
}
}
...
@@ -506,7 +506,7 @@ func xzgetBlkData(ctx context.Context, zconn *zodb.Connection, zblkOid zodb.Oid)
...
@@ -506,7 +506,7 @@ func xzgetBlkData(ctx context.Context, zconn *zodb.Connection, zblkOid zodb.Oid)
}
}
xblk
,
err
:=
zconn
.
Get
(
ctx
,
zblkOid
);
X
(
err
)
xblk
,
err
:=
zconn
.
Get
(
ctx
,
zblkOid
);
X
(
err
)
zblk
:=
xblk
.
(
z
Blk
)
zblk
:=
xblk
.
(
Z
Blk
)
data
,
_
,
err
:=
zblk
.
loadBlkData
(
ctx
);
X
(
err
)
data
,
_
,
err
:=
zblk
.
loadBlkData
(
ctx
);
X
(
err
)
return
string
(
data
)
return
string
(
data
)
}
}
...
...
wcfs/δftail.go
View file @
dac682a1
...
@@ -94,6 +94,44 @@ type ΔFile struct {
...
@@ -94,6 +94,44 @@ type ΔFile struct {
}
}
// XXX doc
/*
// bindFile associates ZBlk as being used by file to store block #blk.
//
// A ZBlk may be bound to several blocks inside one file, and to
// several files.
//
// The information is preserved even when ZBlk comes to ghost
// state, but is lost if ZBlk is garbage collected.
//
// it is safe to call multiple bindFile simultaneously.
// it is not safe to call bindFile and boundTo simultaneously.
//
// XXX link to overview.
bindFile(file *BigFile, blk int64)
// XXX unbindFile
// XXX zfile -> bind map for it
// blkBoundTo returns ZBlk association with file(s)/#blk(s).
//
// The association returned is that was previously set by bindFile.
//
// blkBoundTo must not be called simultaneously wrt bindFile.
blkBoundTo() map[*BigFile]SetI64
*/
// XXX -> _IInΔFtail ?
type
_IZBlkInΔFtail
interface
{
// inΔFtail returns pointer to struct zblkInΔFtail embedded into this ZBlk.
//
// this structure is volatile in-RAM only and is used to track
// ZBlk->File|parent(XXX) relation for data blocks loaded with this ZBlk.
//
// XXX data stored by zBlkBase is transient - it is _not_ included into persistent state
inΔFtail
()
*
zblkInΔFtail
}
// zblkInΔFtail is part of ΔFtail embedded into ZBlk*.
// zblkInΔFtail is part of ΔFtail embedded into ZBlk*.
//
//
// The data stored by zblkInΔFtail is transient - it is _not_ included into
// The data stored by zblkInΔFtail is transient - it is _not_ included into
...
@@ -101,7 +139,11 @@ type ΔFile struct {
...
@@ -101,7 +139,11 @@ type ΔFile struct {
type
zblkInΔFtail
struct
{
type
zblkInΔFtail
struct
{
mu
sync
.
Mutex
// used only for binding to support multiple loaders
mu
sync
.
Mutex
// used only for binding to support multiple loaders
// with which files/blocks this ZBlk is associated. XXX as of @head state?
// XXX change vvv to intree_parent? {} Bucket -> set(#blk)
// (this is uniform with building in-RAM reverse child->parents relation for
// tree nodes and for tree_root->file)
// with which files/blocks this ZBlk is associated with as of @head state
infile
map
[
*
BigFile
]
SetI64
// {} file -> set(#blk)
infile
map
[
*
BigFile
]
SetI64
// {} file -> set(#blk)
}
}
...
@@ -136,7 +178,7 @@ func (δFtail *ΔFtail) Tail() zodb.Tid { return δFtail.δBtail.Tail() }
...
@@ -136,7 +178,7 @@ func (δFtail *ΔFtail) Tail() zodb.Tid { return δFtail.δBtail.Tail() }
// XXX text
// XXX text
//
//
// A root can be associated with several files (each provided on different Track call).
// A root can be associated with several files (each provided on different Track call).
func
(
δFtail
*
ΔFtail
)
Track
(
file
*
BigFile
,
blk
int64
,
path
[]
btree
.
LONode
,
zblk
z
Blk
)
{
func
(
δFtail
*
ΔFtail
)
Track
(
file
*
BigFile
,
blk
int64
,
path
[]
btree
.
LONode
,
zblk
Z
Blk
)
{
if
blk
==
-
1
{
if
blk
==
-
1
{
// XXX blk = ∞ from beginning ?
// XXX blk = ∞ from beginning ?
blk
=
KeyMax
blk
=
KeyMax
...
@@ -251,7 +293,7 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit, zhead *ZConn) (_ ΔF, err
...
@@ -251,7 +293,7 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit, zhead *ZConn) (_ ΔF, err
//fmt.Printf("%s: in cache (%s)\n", oid, typeOf(obj))
//fmt.Printf("%s: in cache (%s)\n", oid, typeOf(obj))
switch
obj
:=
obj
.
(
type
)
{
switch
obj
:=
obj
.
(
type
)
{
case
z
Blk
:
// ZBlk*
case
Z
Blk
:
// ZBlk*
// z.infile locking: since we write-locked head.zheadMu
// z.infile locking: since we write-locked head.zheadMu
// - no other fuse reads are running, and thus no one
// - no other fuse reads are running, and thus no one
// is mutating z.infile. XXX recheck
// is mutating z.infile. XXX recheck
...
...
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