From 78391c92be8cf43eb3487484548751abd36fe1c7 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov <kirr@nexedi.com> Date: Tue, 14 Feb 2017 19:56:47 +0300 Subject: [PATCH] . --- t/neo/storage/fs1/fsb/cmp.go | 15 ++++++++ t/neo/storage/fs1/fsb/fsbtree.go | 12 +++--- t/neo/storage/fs1/fsb/gen-fsbtree | 9 ++++- t/neo/storage/fs1/index.go | 61 +++++++++++++++++-------------- t/neo/storage/fs1/index_test.go | 9 ++++- 5 files changed, 69 insertions(+), 37 deletions(-) create mode 100644 t/neo/storage/fs1/fsb/cmp.go diff --git a/t/neo/storage/fs1/fsb/cmp.go b/t/neo/storage/fs1/fsb/cmp.go new file mode 100644 index 00000000..9d60b8d1 --- /dev/null +++ b/t/neo/storage/fs1/fsb/cmp.go @@ -0,0 +1,15 @@ +package fsb + +import "../../../zodb" + +// comparison function for fsbTree +// kept short & inlineable +func oidCmp(a, b zodb.Oid) int { + if a < b { + return -1 + } else if a > b { + return +1 + } else { + return 0 + } +} diff --git a/t/neo/storage/fs1/fsb/fsbtree.go b/t/neo/storage/fs1/fsb/fsbtree.go index 4f8b1367..541c9dbb 100644 --- a/t/neo/storage/fs1/fsb/fsbtree.go +++ b/t/neo/storage/fs1/fsb/fsbtree.go @@ -40,9 +40,8 @@ var ( type btTpool struct{ sync.Pool } -func (p *btTpool) get(cmp Cmp) *Tree { +func (p *btTpool) get() *Tree { x := p.Get().(*Tree) - x.cmp = cmp return x } @@ -96,7 +95,6 @@ type ( // Tree is a B+tree. Tree struct { c int - cmp Cmp first *d last *d r interface{} @@ -202,8 +200,8 @@ func (l *d) mvR(r *d, c int) { // TreeNew returns a newly created, empty Tree. The compare function is used // for key collation. -func TreeNew(cmp Cmp) *Tree { - return btTPool.get(cmp) +func TreeNew() *Tree { + return btTPool.get() } // Clear removes all K/V pairs from the tree. @@ -359,7 +357,7 @@ func (t *Tree) find(q interface{}, k zodb.Oid) (i int, ok bool) { for l <= h { m := (l + h) >> 1 mk = x.x[m].k - switch cmp := t.cmp(k, mk); { + switch cmp := oidCmp(k, mk); { case cmp > 0: l = m + 1 case cmp == 0: @@ -373,7 +371,7 @@ func (t *Tree) find(q interface{}, k zodb.Oid) (i int, ok bool) { for l <= h { m := (l + h) >> 1 mk = x.d[m].k - switch cmp := t.cmp(k, mk); { + switch cmp := oidCmp(k, mk); { case cmp > 0: l = m + 1 case cmp == 0: diff --git a/t/neo/storage/fs1/fsb/gen-fsbtree b/t/neo/storage/fs1/fsb/gen-fsbtree index 6ccda692..d8f7daf9 100755 --- a/t/neo/storage/fs1/fsb/gen-fsbtree +++ b/t/neo/storage/fs1/fsb/gen-fsbtree @@ -1,5 +1,5 @@ #!/bin/sh -e -# generate b.Tree with compile-time KEY=zodb.Oid, VALUE=int64 +# generate b.Tree with compile-time KEY=zodb.Oid, VALUE=int64 and direct oidCmp calls KEY=zodb.Oid VALUE=int64 @@ -18,4 +18,11 @@ make -s -C $Bdir generic |sed \ -e 's/package b/package fsb/g' \ -e "s/KEY/$KEY/g" \ -e "s/VALUE/$VALUE/g" \ + \ + -e '/cmp *Cmp$/d' \ + -e 's/t\.cmp(/oidCmp(/g' \ + -e 's/func TreeNew(cmp Cmp)/func TreeNew()/g' \ + -e 's/btTPool.get(cmp)/btTPool.get()/g' \ + -e 's/func (p \*btTpool) get(cmp Cmp)/func (p *btTpool) get()/g' \ + -e '/x\.cmp = cmp$/d' \ >>$out diff --git a/t/neo/storage/fs1/index.go b/t/neo/storage/fs1/index.go index 2f2b038b..25102cbb 100644 --- a/t/neo/storage/fs1/index.go +++ b/t/neo/storage/fs1/index.go @@ -37,7 +37,11 @@ import ( // fsIndex is Oid -> Tid's position mapping used to associate Oid with latest // transaction which changed it. type fsIndex struct { - fsb.Tree + *fsb.Tree +} + +func fsIndexNew() *fsIndex { + return &fsIndex{fsb.TreeNew()} } @@ -62,24 +66,23 @@ type fsIndex struct { const oidPrefixMask zodb.Oid = ((1<<64-1) ^ (1<<16 -1)) // 0xffffffffffff0000 -// IndexIOError is the error type returned by index save and load routines -type IndexIOError struct { - Op string // operation performed - "save" or "load" - Err error // error that occured during the operation +// IndexSaveError is the error type returned by index save routines +type IndexSaveError struct { + Err error // error that occured during the operation } -func (e *IndexIOError) Error() string { - s := "index " + e.Op + ": " + e.Err.Error() - return s +func (e *IndexSaveError) Error() string { + return "index save: " + e.Err.Error() } // Save saves the index to a writer func (fsi *fsIndex) Save(topPos int64, w io.Writer) error { - p := pickle.NewEncoder(w) - - err := p.Encode(topPos) + var err error { + p := pickle.NewEncoder(w) + + err = p.Encode(topPos) if err != nil { goto out } @@ -144,11 +147,14 @@ out: // otherwise it is an error returned by writer, which should already // have filename & op as context. - return &IndexIOError{"save", err} + return &IndexSaveError{err} } +// XXX do we need it? +// func (fsi *fsIndex) SaveFile(topPos int64, path string) error { +// } -// IndexLoadError is the errortype returned by index load routines +// IndexLoadError is the error type returned by index load routines type IndexLoadError struct { Filename string Pos int64 @@ -160,6 +166,7 @@ func (e *IndexLoadError) Error() string { if s != "" { s += ": " } + s += "index load: " s += "pickle @" + strconv.FormatInt(e.Pos, 10) + ": " s += e.Err.Error() return s @@ -167,33 +174,36 @@ func (e *IndexLoadError) Error() string { // LoadIndex loads index from a reader func LoadIndex(r io.Reader) (topPos int64, fsi *fsIndex, err error) { - xr := NewBufReader(r) - // by passing bufio.Reader directly we make sure it won't create one internally - p := pickle.NewDecoder(xr.Reader) var picklePos int64 { + var ok bool + var xtopPos, xv interface{} + + xr := NewBufReader(r) + // by passing bufio.Reader directly we make sure it won't create one internally + p := pickle.NewDecoder(xr.Reader) + picklePos = xr.InputOffset() - xtopPos, err := p.Decode() + xtopPos, err = p.Decode() if err != nil { goto out } - var ok bool topPos, ok = xtopPos.(int64) if !ok { err = fmt.Errorf("topPos is %T (expected int64)", xtopPos) goto out } - fsi = &fsIndex{} // TODO cmpFunc ... + fsi = fsIndexNew() var oidb [8]byte var posb [8]byte -loop: + loop: for { // load/decode next entry picklePos = xr.InputOffset() - xv, err := p.Decode() + xv, err = p.Decode() if err != nil { goto out } @@ -269,9 +279,10 @@ out: return 0, nil, &IndexLoadError{IOName(r), picklePos, err} } +// XXX LoadIndexFile - do we need it ? -// CountReader is an io.Reader that count total bytes read. +// CountReader is an io.Reader that count total bytes read type CountReader struct { io.Reader nread int64 @@ -306,7 +317,6 @@ func NewBufReader(r io.Reader) *BufReader { cr = &CountReader{r, 0} } - return &BufReader{bufio.NewReader(cr), cr} } @@ -338,10 +348,7 @@ func IOName(f interface {}) string { return "pipe" // XXX SectionReader MultiReader TeeReader - - // bufio.Reader bufio.Writer bufio.Scanner - - + // XXX bufio.Reader bufio.Writer bufio.Scanner default: return "" } diff --git a/t/neo/storage/fs1/index_test.go b/t/neo/storage/fs1/index_test.go index f71657f3..d393ed1c 100644 --- a/t/neo/storage/fs1/index_test.go +++ b/t/neo/storage/fs1/index_test.go @@ -6,6 +6,11 @@ import ( "testing" ) -func TestXXX(t *testing.T) { - // TODO +func TestIndexLookup(t *testing.T) { + // the lookup is tested in cznic.b itself + // here we only lightly excersize it +} + + +func TestIndexSaveLoad(t *testing.T) { } -- 2.30.9