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
Show 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) {
// 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.
// 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
if
f
.
head
.
rev
!=
0
{
return
...
...
wcfs/zblk.go
View file @
dac682a1
...
...
@@ -55,9 +55,10 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/pycompat"
)
//
z
Blk is the interface that every ZBlk* block implements.
type
z
Blk
interface
{
//
Z
Blk is the interface that every ZBlk* block implements.
type
Z
Blk
interface
{
zodb
.
IPersistent
_IZBlkInΔFtail
// loadBlkData loads from database and returns data block stored by this ZBlk.
//
...
...
@@ -66,82 +67,17 @@ type zBlk interface {
//
// returns data and revision of ZBlk.
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.
func (zb *zBlkBase) blkBoundTo() map[*BigFile]SetI64 {
return zb.infile
}
*/
var
_
ZBlk
=
(
*
ZBlk0
)(
nil
)
var
_
ZBlk
=
(
*
ZBlk1
)(
nil
)
// ---- ZBlk0 ----
// ZBlk0 mimics ZBlk0 from python.
type
ZBlk0
struct
{
zblkInΔFtail
zodb
.
Persistent
zblkInΔFtail
// NOTE py source uses bytes(buf) but on python2 it still results in str
blkdata
string
...
...
@@ -149,14 +85,17 @@ type ZBlk0 struct {
type
zBlk0State
ZBlk0
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zb
*
zBlk0State
)
DropState
()
{
zb
.
blkdata
=
""
}
// PyGetState implements zodb.PyStateful.
func
(
zb
*
zBlk0State
)
PyGetState
()
interface
{}
{
return
zb
.
blkdata
}
// PySetState implements zodb.PyStateful.
func
(
zb
*
zBlk0State
)
PySetState
(
pystate
interface
{})
error
{
blkdata
,
ok
:=
pystate
.
(
string
)
if
!
ok
{
...
...
@@ -167,6 +106,7 @@ func (zb *zBlk0State) PySetState(pystate interface{}) error {
return
nil
}
// loadBlkData implements _ZBlk.
func
(
zb
*
ZBlk0
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"ZBlk0(%s): loadBlkData"
,
zb
.
POid
())
...
...
@@ -191,14 +131,17 @@ type ZData struct {
type
zDataState
ZData
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zd
*
zDataState
)
DropState
()
{
zd
.
data
=
""
}
// PyGetState implements zodb.PyStateful.
func
(
zd
*
zDataState
)
PyGetState
()
interface
{}
{
return
zd
.
data
}
// PySetState implements zodb.PyStateful.
func
(
zd
*
zDataState
)
PySetState
(
pystate
interface
{})
error
{
data
,
ok
:=
pystate
.
(
string
)
if
!
ok
{
...
...
@@ -211,22 +154,25 @@ func (zd *zDataState) PySetState(pystate interface{}) error {
// ZBlk1 mimics ZBlk1 from python.
type
ZBlk1
struct
{
zblkInΔFtail
zodb
.
Persistent
zblkInΔFtail
chunktab
*
btree
.
IOBTree
// {} offset -> ZData(chunk)
}
type
zBlk1State
ZBlk1
// hide state methods from public API
// DropState implements zodb.Ghostable.
func
(
zb
*
zBlk1State
)
DropState
()
{
zb
.
chunktab
=
nil
}
// PyGetState implements zodb.PyStateful.
func
(
zb
*
zBlk1State
)
PyGetState
()
interface
{}
{
return
zb
.
chunktab
}
// PySetState implements zodb.PyStateful.
func
(
zb
*
zBlk1State
)
PySetState
(
pystate
interface
{})
error
{
chunktab
,
ok
:=
pystate
.
(
*
btree
.
IOBTree
)
if
!
ok
{
...
...
@@ -237,6 +183,7 @@ func (zb *zBlk1State) PySetState(pystate interface{}) error {
return
nil
}
// loadBlkData implements ZBlk.
func
(
zb
*
ZBlk1
)
loadBlkData
(
ctx
context
.
Context
)
(
_
[]
byte
,
_
zodb
.
Tid
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"ZBlk1(%s): loadBlkData"
,
zb
.
POid
())
...
...
@@ -416,7 +363,7 @@ type ZBigFile struct {
type
zBigFileState
ZBigFile
// hide state methods from public API
// DropState implements zodb.
Stateful
.
// DropState implements zodb.
Ghostable
.
func
(
bf
*
zBigFileState
)
DropState
()
{
bf
.
blksize
=
0
bf
.
blktab
=
nil
...
...
@@ -464,7 +411,7 @@ func (bf *zBigFileState) PySetState(pystate interface{}) (err error) {
// which provides a rough upper-bound estimate for file[blk] revision.
//
// 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
)
err
=
bf
.
PActivate
(
ctx
)
...
...
@@ -485,7 +432,7 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath
return
make
([]
byte
,
bf
.
blksize
),
treePath
,
nil
,
blkRevMax
,
nil
}
zblk
,
ok
=
xzblk
.
(
z
Blk
)
zblk
,
ok
=
xzblk
.
(
Z
Blk
)
if
!
ok
{
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
for
_
,
__
:=
range
bentryv
{
k
:=
__
.
Key
()
xv
:=
__
.
Value
()
zv
,
ok
:=
xv
.
(
z
Blk
)
zv
,
ok
:=
xv
.
(
Z
Blk
)
if
!
ok
{
exc
.
Raisef
(
"[%d] -> %s; want ZBlk"
,
k
,
typeOf
(
xv
))
}
...
...
@@ -506,7 +506,7 @@ func xzgetBlkData(ctx context.Context, zconn *zodb.Connection, zblkOid zodb.Oid)
}
xblk
,
err
:=
zconn
.
Get
(
ctx
,
zblkOid
);
X
(
err
)
zblk
:=
xblk
.
(
z
Blk
)
zblk
:=
xblk
.
(
Z
Blk
)
data
,
_
,
err
:=
zblk
.
loadBlkData
(
ctx
);
X
(
err
)
return
string
(
data
)
}
...
...
wcfs/δftail.go
View file @
dac682a1
...
...
@@ -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*.
//
// The data stored by zblkInΔFtail is transient - it is _not_ included into
...
...
@@ -101,7 +139,11 @@ type ΔFile struct {
type
zblkInΔFtail
struct
{
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)
}
...
...
@@ -136,7 +178,7 @@ func (δFtail *ΔFtail) Tail() zodb.Tid { return δFtail.δBtail.Tail() }
// XXX text
//
// 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
{
// XXX blk = ∞ from beginning ?
blk
=
KeyMax
...
...
@@ -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))
switch
obj
:=
obj
.
(
type
)
{
case
z
Blk
:
// ZBlk*
case
Z
Blk
:
// ZBlk*
// z.infile locking: since we write-locked head.zheadMu
// - no other fuse reads are running, and thus no one
// 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