Commit 54192026 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent c673f1b1
......@@ -446,6 +446,8 @@ func (bfroot *BigFileRoot) Mkdir(name string, mode uint32, fctx *fuse.Context) (
// /bigfile/<bigfileX>/head/data -> Getattr serves stat.
func (bfdata *BigFileData) GetAttr(out *fuse.Attr, _ nodefs.File, fctx *fuse.Context) fuse.Status {
// XXX locking
out.Mode = fuse.S_IFREG | 0444
out.Size = 0 // FIXME
// .Blocks
......@@ -461,20 +463,18 @@ func (bfdata *BigFileData) GetAttr(out *fuse.Attr, _ nodefs.File, fctx *fuse.Con
}
// Read implements reading from /bigfile/<bigfileX>/head/data.
// XXX and from /bigfile/<bigfileX>/@<tidX>/data.
/*
func (bf *BigFileData) Read(_ nodefs.File, dest []byte, off int64, _ fuse.Context) (fuse.ReadResult, fuse.Status) {
.at
.topoid
// XXX
// /bigfile/<bigfileX>/head/data -> Read serves read.
func (bf *BigFileData) Read(_ nodefs.File, dest []byte, off int64, _ *fuse.Context) (fuse.ReadResult, fuse.Status) {
// XXX locking
panic("TODO")
//bf.zbf.blksize
}
*/
// /bigfile/<bigfileX>/head/at -> served by readAt.
// /bigfile/<bigfileX>/head/at -> readAt serves read.
func (bf *BigFile) readAt() []byte {
// XXX locking
// XXX zconn -> zbf.PJar() ?
return []byte(bf.zconn.At().String())
}
......
......@@ -156,7 +156,7 @@ def test_bigfile_empty():
# head/at = last txn of whole db
assert readfile(fpath + "/head/at") == tid2.encode('hex')
# TODO check head/at syncs to later non-bigfile commits
wc.close()
......
......@@ -20,6 +20,7 @@
package main
// ZBlk* + ZBigFile loading
// module: "wendelin.bigfile.file_zodb"
//
// ZBigFile
......@@ -35,8 +36,6 @@ package main
// ZData
// str (chunk)
import (
"context"
"fmt"
......@@ -47,6 +46,7 @@ import (
"golang.org/x/sync/errgroup"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/zodb/btree"
pickle "github.com/kisielk/og-rek"
......@@ -54,6 +54,15 @@ import (
"./internal/pycompat"
)
// zBlkLoader is the interface that every ZBlk* block implements internally for
// loading its data.
type zBlkLoader interface {
// loadBlkData loads from database and returns data block stored by this ZBlk.
//
// XXX trailing \0 can be stripped.
loadBlkData(ctx context.Context) ([]byte, error)
}
// module of Wendelin ZODB py objects
const zwendelin = "wendelin.bigfile.file_zodb"
......@@ -63,6 +72,7 @@ const zwendelin = "wendelin.bigfile.file_zodb"
type ZBlk0 struct {
zodb.Persistent
// XXX py source uses bytes(buf) but on python2 it still results in str
blkdata string
}
......@@ -82,7 +92,7 @@ func (zb *zBlk0State) PySetState(pystate interface{}) error {
return nil
}
func (zb *ZBlk0) LoadBlkData(ctx context.Context) ([]byte, error) {
func (zb *ZBlk0) loadBlkData(ctx context.Context) ([]byte, error) {
// XXX err ctx
err := zb.PActivate(ctx)
......@@ -100,6 +110,7 @@ func (zb *ZBlk0) LoadBlkData(ctx context.Context) ([]byte, error) {
type ZData struct {
zodb.Persistent
// XXX py source uses bytes(buf) but on python2 it still results in str
data string
}
......@@ -142,7 +153,7 @@ func (zb *zBlk1State) PySetState(pystate interface{}) error {
return nil
}
func (zb *ZBlk1) LoadBlkData(ctx context.Context) ([]byte, error) {
func (zb *ZBlk1) loadBlkData(ctx context.Context) ([]byte, error) {
// XXX errctx
err := zb.PActivate(ctx)
......@@ -178,7 +189,6 @@ func (zb *ZBlk1) LoadBlkData(ctx context.Context) ([]byte, error) {
// no PDeactivate, zd remains live
//fmt.Printf("@%d -> zdata #%s (%d)\n", offset, zd.POid(), len(zd.data))
mu.Lock()
defer mu.Unlock()
......@@ -200,6 +210,7 @@ func (zb *ZBlk1) LoadBlkData(ctx context.Context) ([]byte, error) {
// XXX off + len > blksize !ok
//fmt.Printf("\nbucket: %v\n\n", b.Entryv())
for _, e := range b.Entryv() {
zd, ok := e.Value().(*ZData)
if !ok {
......@@ -215,7 +226,6 @@ func (zb *ZBlk1) LoadBlkData(ctx context.Context) ([]byte, error) {
return nil
}
// loadBTree spawns loading of all BTree children.
var loadBTree func(t *btree.IOBTree) error
loadBTree = func(t *btree.IOBTree) error {
......@@ -351,6 +361,44 @@ func (bf *zBigFileState) PySetState(pystate interface{}) (err error) {
return nil
}
// LoadBlk loads data for file block #blk.
//
// XXX better load into user-provided buf?
func (bf *ZBigFile) LoadBlk(ctx context.Context, blk int64) (_ []byte, err error) {
defer xerr.Contextf(&err, "bigfile %s: loadblk %d", bf.POid(), blk)
err = bf.PActivate(ctx)
if err != nil {
return nil, err
}
defer bf.PDeactivate()
xzblk, ok, err := bf.blktab.Get(ctx, blk)
if err != nil {
return nil, err
}
if !ok {
return make([]byte, bf.blksize), nil
}
zblk, ok := xzblk.(zBlkLoader)
if !ok {
return nil, fmt.Errorf("expect ZBlk*; got %s", typeOf(xzblk))
}
blkdata, err := zblk.loadBlkData(ctx)
if err != nil {
return nil, err
}
if l := int64(len(blkdata)); l > bf.blksize {
return nil, fmt.Errorf("invalid blk: size = %d (> blksize = %d)", l, bf.blksize)
}
// XXX append trailing \0 to reach .blksize ?
return blkdata, nil
}
// ----------------------------------------
......
......@@ -86,10 +86,10 @@ func TestZBlk(t *testing.T) {
binary.BigEndian.PutUint32(data[i*4:], i)
}
z0Data, err := z0.LoadBlkData(ctx); X(err)
z0Data, err := z0.loadBlkData(ctx); X(err)
assert.Equal(z0Data, data, "ZBlk0 data wrong")
z1Data, err := z1.LoadBlkData(ctx); X(err)
z1Data, err := z1.loadBlkData(ctx); X(err)
if false {
fmt.Printf("%#v\n", z1Data)
}
......@@ -113,4 +113,6 @@ func TestZBlk(t *testing.T) {
}
// XXX check zf.blktab.MaxKey ?
// XXX check zf.LoadBlk()
}
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