Commit b3163ad6 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent be0fed1e
...@@ -882,13 +882,13 @@ retry: ...@@ -882,13 +882,13 @@ retry:
// XXX -> parallel // XXX -> parallel
// XXX locking // XXX locking
for file := range toinvalidate { for file := range toinvalidate {
size, treePath, err := file.zfile.Size(ctx) size, sizePath, err := file.zfile.Size(ctx)
if err != nil { if err != nil {
panic(err) // XXX panic(err) // XXX
} }
file.size = size file.size = size
bfdir.δFtail.Track(file, treePath) bfdir.δFtail.Track(file, -1, sizePath, nil)
file.rev = zhead.At() file.rev = zhead.At()
} }
...@@ -1173,16 +1173,18 @@ func (f *BigFile) updateWatchers(ctx context.Context, blk int64, treepath []btre ...@@ -1173,16 +1173,18 @@ func (f *BigFile) updateWatchers(ctx context.Context, blk int64, treepath []btre
return return
} }
// update δbtree index // update δFtail index
bfdir := f.head.bfdir bfdir := f.head.bfdir
bfdir.δFmu.Lock() // XXX locking correct? bfdir.δFmu.Lock() // XXX locking correct? XXX -> better push down?
bfdir.δFtail.Track(f, treepath) // XXX pass in zblk.oid / zblk.rev here? bfdir.δFtail.Track(f, blk, treepath, zblk) // XXX pass in zblk.rev here?
bfdir.δFmu.Unlock() bfdir.δFmu.Unlock()
/* XXX kill
// associate zblk with file, if data was not hole // associate zblk with file, if data was not hole
if zblk != nil { if zblk != nil {
zblk.bindFile(f, blk) zblk.bindFile(f, blk)
} }
*/
// makes sure that file[blk] on clients side stays as of @w.at state. // makes sure that file[blk] on clients side stays as of @w.at state.
...@@ -1743,7 +1745,7 @@ func (head *Head) bigopen(ctx context.Context, oid zodb.Oid) (_ *BigFile, err er ...@@ -1743,7 +1745,7 @@ func (head *Head) bigopen(ctx context.Context, oid zodb.Oid) (_ *BigFile, err er
rev := zfile.PSerial() rev := zfile.PSerial()
zfile.PDeactivate() zfile.PDeactivate()
size, treePath, err := zfile.Size(ctx) size, sizePath, err := zfile.Size(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -1764,7 +1766,7 @@ func (head *Head) bigopen(ctx context.Context, oid zodb.Oid) (_ *BigFile, err er ...@@ -1764,7 +1766,7 @@ func (head *Head) bigopen(ctx context.Context, oid zodb.Oid) (_ *BigFile, err er
// only head/ needs δFtail & f.δtail. // only head/ needs δFtail & f.δtail.
if head.rev == 0 { if head.rev == 0 {
head.bfdir.δFmu.Lock() // XXX locking ok? head.bfdir.δFmu.Lock() // XXX locking ok?
head.bfdir.δFtail.Track(f, treePath) head.bfdir.δFtail.Track(f, -1, sizePath, nil)
head.bfdir.δFmu.Unlock() head.bfdir.δFmu.Unlock()
f.δtail = NewΔTailI64(zconn.At()) f.δtail = NewΔTailI64(zconn.At())
......
...@@ -67,6 +67,10 @@ type zBlk interface { ...@@ -67,6 +67,10 @@ 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
/*
// bindFile associates ZBlk as being used by file to store block #blk. // 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 // A ZBlk may be bound to several blocks inside one file, and to
...@@ -90,11 +94,13 @@ type zBlk interface { ...@@ -90,11 +94,13 @@ type zBlk interface {
// //
// blkBoundTo must not be called simultaneously wrt bindFile. // blkBoundTo must not be called simultaneously wrt bindFile.
blkBoundTo() map[*BigFile]SetI64 blkBoundTo() map[*BigFile]SetI64
*/
} }
var _ zBlk = (*ZBlk0)(nil) var _ zBlk = (*ZBlk0)(nil)
var _ zBlk = (*ZBlk1)(nil) var _ zBlk = (*ZBlk1)(nil)
/*
// ---- zBlkBase ---- // ---- zBlkBase ----
// zBlkBase provides common functionality to implement ZBlk* -> zfile, #blk binding. // zBlkBase provides common functionality to implement ZBlk* -> zfile, #blk binding.
...@@ -103,7 +109,7 @@ var _ zBlk = (*ZBlk1)(nil) ...@@ -103,7 +109,7 @@ var _ zBlk = (*ZBlk1)(nil)
// persistent state. // persistent state.
type zBlkBase struct { type zBlkBase struct {
bindMu sync.Mutex // used only for binding to support multiple loaders bindMu sync.Mutex // used only for binding to support multiple loaders
infile map[*BigFile]SetI64 // {} zfile -> set(#blk) infile map[*BigFile]SetI64 // {} file -> set(#blk)
} }
// bindFile implements zBlk. // bindFile implements zBlk.
...@@ -126,12 +132,13 @@ func (zb *zBlkBase) bindFile(file *BigFile, blk int64) { ...@@ -126,12 +132,13 @@ func (zb *zBlkBase) bindFile(file *BigFile, blk int64) {
func (zb *zBlkBase) blkBoundTo() map[*BigFile]SetI64 { func (zb *zBlkBase) blkBoundTo() map[*BigFile]SetI64 {
return zb.infile return zb.infile
} }
*/
// ---- ZBlk0 ---- // ---- ZBlk0 ----
// ZBlk0 mimics ZBlk0 from python. // ZBlk0 mimics ZBlk0 from python.
type ZBlk0 struct { type ZBlk0 struct {
zBlkBase zblkInΔFtail
zodb.Persistent zodb.Persistent
// XXX py source uses bytes(buf) but on python2 it still results in str // XXX py source uses bytes(buf) but on python2 it still results in str
...@@ -204,7 +211,7 @@ func (zd *zDataState) PySetState(pystate interface{}) error { ...@@ -204,7 +211,7 @@ func (zd *zDataState) PySetState(pystate interface{}) error {
// ZBlk1 mimics ZBlk1 from python. // ZBlk1 mimics ZBlk1 from python.
type ZBlk1 struct { type ZBlk1 struct {
zBlkBase zblkInΔFtail
zodb.Persistent zodb.Persistent
chunktab *btree.IOBTree // {} offset -> ZData(chunk) chunktab *btree.IOBTree // {} offset -> ZData(chunk)
...@@ -501,7 +508,7 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath ...@@ -501,7 +508,7 @@ func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, treePath
// Size returns whole file size. // Size returns whole file size.
// //
// it also returns BTree path scaned to obtain size. // it also returns BTree path scaned to obtain the size.
func (bf *ZBigFile) Size(ctx context.Context) (_ int64, treePath []btree.LONode, err error) { func (bf *ZBigFile) Size(ctx context.Context) (_ int64, treePath []btree.LONode, err error) {
defer xerr.Contextf(&err, "bigfile %s: size", bf.POid()) defer xerr.Contextf(&err, "bigfile %s: size", bf.POid())
......
...@@ -22,6 +22,7 @@ package main ...@@ -22,6 +22,7 @@ package main
import ( import (
"context" "context"
"runtime" "runtime"
"sync"
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/zodb/btree" "lab.nexedi.com/kirr/neo/go/zodb/btree"
...@@ -79,6 +80,20 @@ type Δfile struct { ...@@ -79,6 +80,20 @@ type Δfile struct {
Change SetI64 // changed blocks Change SetI64 // changed blocks
} }
// zblkInΔFtail is ΔFtail knowledge embedded into ZBlk*.
//
// The data stored by zBlkBase is transient - it is _not_ included into
// persistent state.
type zblkInΔFtail struct {
mu sync.Mutex // used only for binding to support multiple loaders
// with which files/blocks this ZBlk is associated.
infile map[*BigFile]SetI64 // {} file -> set(#blk)
}
func (z *zblkInΔFtail) inΔFtail() *zblkInΔFtail { return z }
// NewΔFtail creates new ΔFtail object. // NewΔFtail creates new ΔFtail object.
// //
// Initial tracked set is empty. // Initial tracked set is empty.
...@@ -95,12 +110,17 @@ func (δFtail *ΔFtail) Head() zodb.Tid { return δFtail.δBtail.Head() } ...@@ -95,12 +110,17 @@ func (δFtail *ΔFtail) Head() zodb.Tid { return δFtail.δBtail.Head() }
func (δFtail *ΔFtail) Tail() zodb.Tid { return δFtail.δBtail.Tail() } func (δFtail *ΔFtail) Tail() zodb.Tid { return δFtail.δBtail.Tail() }
// Track adds tree path to tracked set and associates path root with file. // Track associates file[blk] with tree path and zblk object there.
//
// zblk can be nil, which represents a hole.
// XXX blk=-1 is used for tracking after Size (no zblk is accessed at all).
//
// XXX Track adds tree path to tracked set and associates path root with file.
// //
// 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, path []btree.LONode) { func (δFtail *ΔFtail) Track(file *BigFile, blk int64, path []btree.LONode, zblk zBlk) {
δFtail.δBtail.Track(path) δFtail.δBtail.Track(path)
root := path[0].(*btree.LOBTree) root := path[0].(*btree.LOBTree)
files, ok := δFtail.fileIdx[root] files, ok := δFtail.fileIdx[root]
...@@ -110,6 +130,22 @@ func (δFtail *ΔFtail) Track(file *BigFile, path []btree.LONode) { ...@@ -110,6 +130,22 @@ func (δFtail *ΔFtail) Track(file *BigFile, path []btree.LONode) {
} }
files.Add(file) files.Add(file)
// associate zblk with file, if it was not hole
if zblk != nil {
z := zblk.inΔFtail()
z.mu.Lock()
blocks, ok := z.infile[file]
if !ok {
blocks = make(SetI64, 1)
if z.infile == nil {
z.infile = make(map[*BigFile]SetI64)
}
z.infile[file] = blocks
}
blocks.Add(blk)
z.mu.Unlock()
}
// XXX mark something dirty so that LastBlkRev and Slice* know what to rebuild? // XXX mark something dirty so that LastBlkRev and Slice* know what to rebuild?
// XXX debug // XXX debug
...@@ -167,21 +203,18 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) ΔF { ...@@ -167,21 +203,18 @@ func (δFtail *ΔFtail) Update(δZ *zodb.EventCommit) ΔF {
continue // object not related to any bigfile continue // object not related to any bigfile
case zBlk: // ZBlk* case zBlk: // ZBlk*
// blkBoundTo locking: no other bindFile are running, // z.infile locking: since we write-locked head.zconnMu
// since we write-locked head.zconnMu and bindFile is // - no other fuse reads are running, and thus no one
// run when loading objects - thus when head.zconnMu is // is mutating z.infile. XXX recheck
// read-locked. XXX comment -> proper place? z := obj.inΔFtail()
// for file, blocks := range z.infile {
// bfdir locking: similarly not needed, since we are
// exclusively holding head lock.
for file, objBlk := range obj.blkBoundTo() {
δfile, ok := δF.Change[file] δfile, ok := δF.Change[file]
if !ok { if !ok {
δfile = make(SetI64) δfile = make(SetI64)
δF.Change[file] = δfile δF.Change[file] = δfile
} }
δfile.Update(objBlk) δfile.Update(blocks)
} }
case *ZBigFile: case *ZBigFile:
......
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