mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-08-28 10:54:59 +00:00
Stack allocate return from rbf.Tx.cursor()
This commit is contained in:
parent
be944a6247
commit
5b72a68628
3 changed files with 57 additions and 64 deletions
|
|
@ -1015,8 +1015,8 @@ func TestCursor_PlayContainer(t *testing.T) {
|
|||
}
|
||||
cur, _ := tx.Cursor("x")
|
||||
offset := uint64(0)
|
||||
many(cur, 0, rbf.ArrayMaxSize+offset)
|
||||
many(cur, 65536, rbf.ArrayMaxSize+offset)
|
||||
many(&cur, 0, rbf.ArrayMaxSize+offset)
|
||||
many(&cur, 65536, rbf.ArrayMaxSize+offset)
|
||||
/*
|
||||
many(cur, 2*65536, rbf.ArrayMaxSize+offset)
|
||||
many(cur, 3*65536, rbf.ArrayMaxSize) //+offset)
|
||||
|
|
|
|||
99
rbf/tx.go
99
rbf/tx.go
|
|
@ -502,10 +502,10 @@ func (tx *Tx) Remove(name string, a ...uint64) (changeCount int, err error) {
|
|||
}
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, v := range a {
|
||||
if vchanged, err := c.Remove(v); err != nil {
|
||||
|
|
@ -529,38 +529,36 @@ func (tx *Tx) Contains(name string, v uint64) (bool, error) {
|
|||
}
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return false, nil
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return c.Contains(v)
|
||||
}
|
||||
|
||||
// Cursor returns an instance of a cursor this bitmap.
|
||||
func (tx *Tx) Cursor(name string) (*Cursor, error) {
|
||||
func (tx *Tx) Cursor(name string) (Cursor, error) {
|
||||
tx.mu.RLock()
|
||||
defer tx.mu.RUnlock()
|
||||
return tx.cursor(name)
|
||||
}
|
||||
|
||||
func (tx *Tx) cursor(name string) (*Cursor, error) {
|
||||
func (tx *Tx) cursor(name string) (Cursor, error) {
|
||||
if tx.db == nil {
|
||||
return nil, ErrTxClosed
|
||||
return Cursor{}, ErrTxClosed
|
||||
} else if name == "" {
|
||||
return nil, ErrBitmapNameRequired
|
||||
return Cursor{}, ErrBitmapNameRequired
|
||||
}
|
||||
|
||||
root, err := tx.root(name)
|
||||
if err == ErrBitmapNotFound {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return Cursor{}, err
|
||||
}
|
||||
|
||||
c := Cursor{tx: tx}
|
||||
c.stack.elems[0] = stackElem{pgno: root}
|
||||
return &c, nil
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// RoaringBitmap returns a bitmap as a Roaring bitmap.
|
||||
|
|
@ -575,10 +573,10 @@ func (tx *Tx) RoaringBitmap(name string) (*roaring.Bitmap, error) {
|
|||
}
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return roaring.NewSliceBitmap(), nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
other := roaring.NewSliceBitmap()
|
||||
|
|
@ -615,9 +613,9 @@ func (tx *Tx) container(name string, key uint64) (*roaring.Container, error) {
|
|||
}
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
} else if exact, err := c.Seek(key); err != nil || !exact {
|
||||
return nil, err
|
||||
|
|
@ -671,10 +669,10 @@ func (tx *Tx) RemoveContainer(name string, key uint64) error {
|
|||
|
||||
func (tx *Tx) removeContainer(name string, key uint64) error {
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else if exact, err := c.Seek(key); err != nil || !exact {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1007,14 +1005,12 @@ func (tx *Tx) ContainerIterator(name string, key uint64) (citer roaring.Containe
|
|||
defer tx.mu.RUnlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if c == nil && err == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return &emptyContainerIterator{}, false, nil // nothing available.
|
||||
} else if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
// INVAR: c is not nil
|
||||
|
||||
exact, err := c.Seek(key)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
|
|
@ -1031,10 +1027,10 @@ func (tx *Tx) ForEachRange(name string, start, end uint64, fn func(uint64) error
|
|||
defer tx.mu.RUnlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
} else if _, err := c.Seek(highbits(start)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1099,10 +1095,10 @@ func (tx *Tx) Count(name string) (uint64, error) {
|
|||
defer tx.mu.RUnlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
} else if err := c.First(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -1125,10 +1121,10 @@ func (tx *Tx) Max(name string) (uint64, error) {
|
|||
defer tx.mu.RUnlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
} else if err := c.Last(); err == io.EOF {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
|
|
@ -1144,10 +1140,10 @@ func (tx *Tx) Min(name string) (uint64, bool, error) {
|
|||
defer tx.mu.RUnlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
} else if c == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return 0, false, nil
|
||||
} else if err != nil {
|
||||
return 0, false, err
|
||||
} else if err := c.First(); err == io.EOF {
|
||||
return 0, false, nil
|
||||
} else if err != nil {
|
||||
|
|
@ -1192,10 +1188,10 @@ func (tx *Tx) CountRange(name string, start, end uint64) (uint64, error) {
|
|||
ekey := highbits(end)
|
||||
|
||||
csr, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if csr == nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
exact, err := csr.Seek(skey)
|
||||
|
|
@ -1262,7 +1258,9 @@ func (tx *Tx) OffsetRange(name string, offset, start, endx uint64) (*roaring.Bit
|
|||
defer tx.mu.Unlock()
|
||||
|
||||
c, err := tx.cursor(name)
|
||||
if err != nil {
|
||||
if err == ErrBitmapNotFound {
|
||||
return roaring.NewSliceBitmap(), nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -1270,11 +1268,6 @@ func (tx *Tx) OffsetRange(name string, offset, start, endx uint64) (*roaring.Bit
|
|||
off := highbits(offset)
|
||||
hi0, hi1 := highbits(start), highbits(endx)
|
||||
|
||||
if c == nil {
|
||||
// bitmap not found. Match what roaring does and return nil in this case.
|
||||
return other, nil
|
||||
}
|
||||
|
||||
if _, err := c.Seek(hi0); err == io.EOF {
|
||||
return other, nil
|
||||
} else if err != nil {
|
||||
|
|
@ -1302,7 +1295,7 @@ func (tx *Tx) OffsetRange(name string, offset, start, endx uint64) (*roaring.Bit
|
|||
|
||||
// containerIterator wraps Cursor to implement roaring.ContainerIterator.
|
||||
type containerIterator struct {
|
||||
cursor *Cursor
|
||||
cursor Cursor
|
||||
}
|
||||
|
||||
// Close is a no-op. It exists to implement the roaring.ContainerIterator interface.
|
||||
|
|
@ -1496,7 +1489,7 @@ func (tx *Tx) ImportRoaringBits(name string, itr roaring.RoaringIterator, clear
|
|||
changed += nsynth
|
||||
rowSet[currRow] += nsynth
|
||||
|
||||
if err := tx.putContainerWithCursor(cur, itrKey, synthC); err != nil {
|
||||
if err := tx.putContainerWithCursor(&cur, itrKey, synthC); err != nil {
|
||||
return changed, rowSet, err
|
||||
}
|
||||
continue
|
||||
|
|
@ -1517,7 +1510,7 @@ func (tx *Tx) ImportRoaringBits(name string, itr roaring.RoaringIterator, clear
|
|||
changes := int(existN - newC.N())
|
||||
changed += changes
|
||||
rowSet[currRow] -= changes
|
||||
err = tx.putContainerWithCursor(cur, itrKey, newC)
|
||||
err = tx.putContainerWithCursor(&cur, itrKey, newC)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -1535,7 +1528,7 @@ func (tx *Tx) ImportRoaringBits(name string, itr roaring.RoaringIterator, clear
|
|||
// can nsynth be zero? No, because of the continue/invariant above where nsynth > 0
|
||||
changed += nsynth
|
||||
rowSet[currRow] += nsynth
|
||||
err = tx.putContainerWithCursor(cur, itrKey, synthC)
|
||||
err = tx.putContainerWithCursor(&cur, itrKey, synthC)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -1552,7 +1545,7 @@ func (tx *Tx) ImportRoaringBits(name string, itr roaring.RoaringIterator, clear
|
|||
changed += changes
|
||||
rowSet[currRow] += changes
|
||||
|
||||
err = tx.putContainerWithCursor(cur, itrKey, newC)
|
||||
err = tx.putContainerWithCursor(&cur, itrKey, newC)
|
||||
if err != nil {
|
||||
panicOn(err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -362,13 +362,13 @@ func TestTx_CursorCrashArray(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
//setArray(t, 0, 2379, c)
|
||||
//setArray(t, 1, 2337, c)
|
||||
setArray(t, 32, 1216, c)
|
||||
setArray(t, 33, 1195, c)
|
||||
setArray(t, 48, 1186, c)
|
||||
setArray(t, 49, 1223, c)
|
||||
setArray(t, 50, 1223, c)
|
||||
//setArray(t, 0, 2379, &c)
|
||||
//setArray(t, 1, 2337, &c)
|
||||
setArray(t, 32, 1216, &c)
|
||||
setArray(t, 33, 1195, &c)
|
||||
setArray(t, 48, 1186, &c)
|
||||
setArray(t, 49, 1223, &c)
|
||||
setArray(t, 50, 1223, &c)
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -388,8 +388,8 @@ func TestTx_CursorCrashBitmap(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
setArray(t, 0, 22510, c)
|
||||
setArray(t, 1, 23584, c)
|
||||
setArray(t, 0, 22510, &c)
|
||||
setArray(t, 1, 23584, &c)
|
||||
}
|
||||
|
||||
func setArray(tb testing.TB, key, num int, c *rbf.Cursor) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue