Commit dac682a1 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent a1299792
......@@ -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 zBlk, blkrevMax zodb.Tid) {
func (f *BigFile) readPinWatchers(ctx context.Context, blk int64, treepath []btree.LONode, zblk ZBlk, blkrevMax zodb.Tid) {
// only head/ is being watched for
if f.head.rev != 0 {
return
......
......@@ -55,9 +55,10 @@ import (
"lab.nexedi.com/nexedi/wendelin.core/wcfs/internal/pycompat"
)
// zBlk is the interface that every ZBlk* block implements.
type zBlk interface {
// ZBlk is the interface that every ZBlk* block implements.
type ZBlk 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 zBlk, blkRevMax zodb.Tid, err error) {
func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath []btree.LONode, zblk ZBlk, 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.(zBlk)
zblk, ok = xzblk.(ZBlk)
if !ok {
return nil, nil, nil, 0, fmt.Errorf("expect ZBlk*; got %s", typeOf(xzblk))
}
......
......@@ -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.(zBlk)
zv, ok := xv.(ZBlk)
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.(zBlk)
zblk := xblk.(ZBlk)
data, _, err := zblk.loadBlkData(ctx); X(err)
return string(data)
}
......
......@@ -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 zBlk) {
func (δFtail *ΔFtail) Track(file *BigFile, blk int64, path []btree.LONode, zblk ZBlk) {
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 zBlk: // ZBlk*
case ZBlk: // 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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment