mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-03 03:10:26 -05:00
go/store/prolly/tree: make node cursor pkg private
This commit is contained in:
@@ -153,11 +153,10 @@ func prollyChildSecDiffFkConstraintViolations(
|
||||
parentSecIdx := durable.ProllyMapFromIndex(postParent.IndexData)
|
||||
|
||||
parentSecIdxDesc, _ := parentSecIdx.Descriptors()
|
||||
partialDesc := parentSecIdxDesc.PrefixDesc(len(foreignKey.TableColumns))
|
||||
prefixDesc := parentSecIdxDesc.PrefixDesc(len(foreignKey.TableColumns))
|
||||
childPriKD, _ := postChildRowData.Descriptors()
|
||||
childPriKB := val.NewTupleBuilder(childPriKD)
|
||||
|
||||
var parentSecIdxCur *tree.Cursor
|
||||
err := prolly.DiffMaps(ctx, preChildSecIdx, postChildSecIdx, func(ctx context.Context, diff tree.Diff) error {
|
||||
switch diff.Type {
|
||||
case tree.AddedDiff, tree.ModifiedDiff:
|
||||
@@ -169,31 +168,14 @@ func prollyChildSecDiffFkConstraintViolations(
|
||||
}
|
||||
}
|
||||
|
||||
if parentSecIdxCur == nil {
|
||||
newCur, err := tree.NewCursorAtKey(ctx, parentSecIdx.NodeStore(), parentSecIdx.Node(), k, partialDesc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !newCur.Valid() {
|
||||
return createCVForSecIdx(ctx, k, childPriKD, childPriKB, postChildRowData, postChildRowData.Pool(), receiver)
|
||||
}
|
||||
parentSecIdxCur = newCur
|
||||
}
|
||||
|
||||
err := tree.Seek(ctx, parentSecIdxCur, k, partialDesc)
|
||||
ok, err := parentSecIdx.HasRange(ctx, prolly.PrefixRange(k, prefixDesc))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !parentSecIdxCur.Valid() {
|
||||
return createCVForSecIdx(ctx, k, childPriKD, childPriKB, postChildRowData, postChildRowData.Pool(), receiver)
|
||||
}
|
||||
|
||||
// possible that k is less than the smallest key in parentSecIdxCur, so still should compare
|
||||
key := val.Tuple(parentSecIdxCur.CurrentKey())
|
||||
if partialDesc.Compare(k, key) != 0 {
|
||||
} else if !ok {
|
||||
return createCVForSecIdx(ctx, k, childPriKD, childPriKB, postChildRowData, postChildRowData.Pool(), receiver)
|
||||
}
|
||||
return nil
|
||||
|
||||
case tree.RemovedDiff:
|
||||
default:
|
||||
panic("unhandled diff type")
|
||||
@@ -203,7 +185,6 @@ func prollyChildSecDiffFkConstraintViolations(
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -108,11 +108,7 @@ func (c CommitClosure) IsEmpty() bool {
|
||||
|
||||
func (c CommitClosure) ContainsKey(ctx context.Context, h hash.Hash, height uint64) (bool, error) {
|
||||
k := NewCommitClosureKey(c.closure.NodeStore.Pool(), height, h)
|
||||
cur, err := tree.NewCursorAtKey(ctx, c.closure.NodeStore, c.closure.Root, k, c.closure.Order)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return cur.Valid(), nil
|
||||
return c.closure.Has(ctx, k)
|
||||
}
|
||||
|
||||
func DecodeCommitClosureKey(key []byte) (height uint64, addr hash.Hash) {
|
||||
|
||||
@@ -33,7 +33,7 @@ type Chunker interface {
|
||||
}
|
||||
|
||||
type chunker[S message.Serializer] struct {
|
||||
cur *Cursor
|
||||
cur *cursor
|
||||
parent *chunker[S]
|
||||
level int
|
||||
done bool
|
||||
@@ -55,7 +55,7 @@ func newEmptyChunker[S message.Serializer](ctx context.Context, ns NodeStore, se
|
||||
return newChunker(ctx, nil, 0, ns, serializer)
|
||||
}
|
||||
|
||||
func newChunker[S message.Serializer](ctx context.Context, cur *Cursor, level int, ns NodeStore, serializer S) (*chunker[S], error) {
|
||||
func newChunker[S message.Serializer](ctx context.Context, cur *cursor, level int, ns NodeStore, serializer S) (*chunker[S], error) {
|
||||
// |cur| will be nil if this is a new Node, implying this is a new tree, or the tree has grown in height relative
|
||||
// to its original chunked form.
|
||||
|
||||
@@ -98,8 +98,8 @@ func (tc *chunker[S]) processPrefix(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
_, err = tc.append(ctx,
|
||||
tc.cur.CurrentKey(),
|
||||
tc.cur.CurrentValue(),
|
||||
tc.cur.currentKey(),
|
||||
tc.cur.currentValue(),
|
||||
sz)
|
||||
|
||||
// todo(andy): seek to correct chunk
|
||||
@@ -113,7 +113,7 @@ func (tc *chunker[S]) processPrefix(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tc.cur.Advance(ctx)
|
||||
err = tc.cur.advance(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (tc *chunker[S]) DeletePair(ctx context.Context, _, _ Item) error {
|
||||
return tc.skip(ctx)
|
||||
}
|
||||
|
||||
// AdvanceTo progresses the chunker until its tracking cursor catches up with
|
||||
// advanceTo progresses the chunker until its tracking cursor catches up with
|
||||
// |next|, a cursor indicating next key where an edit will be applied.
|
||||
//
|
||||
// The method proceeds from the deepest chunker recursively into its
|
||||
@@ -166,8 +166,8 @@ func (tc *chunker[S]) DeletePair(ctx context.Context, _, _ Item) error {
|
||||
// anticipation of impending edits that may edit the current chunk. Note that
|
||||
// processPrefix is only necessary for the "fast forward" case where we
|
||||
// synchronized the tree level before reaching |next|.
|
||||
func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
cmp := tc.cur.Compare(next)
|
||||
func (tc *chunker[S]) advanceTo(ctx context.Context, next *cursor) error {
|
||||
cmp := tc.cur.compare(next)
|
||||
if cmp == 0 { // step (1)
|
||||
return nil
|
||||
} else if cmp > 0 {
|
||||
@@ -175,8 +175,8 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
// we navigate to the end of the previous chunk rather than the
|
||||
// beginning of the next chunk. I think this is basically a one-off
|
||||
// error.
|
||||
for tc.cur.Compare(next) > 0 {
|
||||
if err := next.Advance(ctx); err != nil {
|
||||
for tc.cur.compare(next) > 0 {
|
||||
if err := next.advance(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -187,17 +187,17 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
split, err := tc.append(ctx, tc.cur.CurrentKey(), tc.cur.CurrentValue(), sz)
|
||||
split, err := tc.append(ctx, tc.cur.currentKey(), tc.cur.currentValue(), sz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for !(split && tc.cur.atNodeEnd()) { // step (2)
|
||||
err = tc.cur.Advance(ctx)
|
||||
err = tc.cur.advance(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if cmp = tc.cur.Compare(next); cmp >= 0 {
|
||||
if cmp = tc.cur.compare(next); cmp >= 0 {
|
||||
// we caught up before synchronizing
|
||||
return nil
|
||||
}
|
||||
@@ -205,7 +205,7 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
split, err = tc.append(ctx, tc.cur.CurrentKey(), tc.cur.CurrentValue(), sz)
|
||||
split, err = tc.append(ctx, tc.cur.currentKey(), tc.cur.currentValue(), sz)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -217,7 +217,7 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if tc.cur.parent.Compare(next.parent) == 0 { // step (3)
|
||||
if tc.cur.parent.compare(next.parent) == 0 { // step (3)
|
||||
// (rare) new tree synchronized with old tree at the
|
||||
// same time as the cursor caught up to the next mutation point
|
||||
tc.cur.copy(next)
|
||||
@@ -229,7 +229,7 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
// This optimization is logically equivalent to advancing
|
||||
// current cursor. Because we just wrote a chunk, we are
|
||||
// at a boundary and can simply increment the parent.
|
||||
err = tc.cur.parent.Advance(ctx)
|
||||
err = tc.cur.parent.advance(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -237,7 +237,7 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
|
||||
// no more pending chunks at this level, recurse
|
||||
// into parent
|
||||
err = tc.parent.AdvanceTo(ctx, next.parent)
|
||||
err = tc.parent.advanceTo(ctx, next.parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -254,7 +254,7 @@ func (tc *chunker[S]) AdvanceTo(ctx context.Context, next *Cursor) error {
|
||||
}
|
||||
|
||||
func (tc *chunker[S]) skip(ctx context.Context) error {
|
||||
err := tc.cur.Advance(ctx)
|
||||
err := tc.cur.advance(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ func (tc *chunker[S]) handleChunkBoundary(ctx context.Context) error {
|
||||
func (tc *chunker[S]) createParentChunker(ctx context.Context) (err error) {
|
||||
assertTrue(tc.parent == nil, "chunker parent must be nil")
|
||||
|
||||
var parent *Cursor
|
||||
var parent *cursor
|
||||
if tc.cur != nil && tc.cur.parent != nil {
|
||||
// todo(andy): does this comment make sense? cloning a pointer?
|
||||
// Clone the parent cursor because otherwise calling cur.forward() will affect our parent - and vice versa -
|
||||
@@ -416,7 +416,7 @@ func (tc *chunker[S]) Done(ctx context.Context) (Node, error) {
|
||||
// If we are mutating an existing Node, appending subsequent items in the Node until we reach a pre-existing chunk
|
||||
// boundary or the end of the Node.
|
||||
func (tc *chunker[S]) finalizeCursor(ctx context.Context) (err error) {
|
||||
for tc.cur.Valid() {
|
||||
for tc.cur.valid() {
|
||||
var sz uint64
|
||||
sz, err = tc.cur.currentSubtreeSize()
|
||||
if err != nil {
|
||||
@@ -424,8 +424,8 @@ func (tc *chunker[S]) finalizeCursor(ctx context.Context) (err error) {
|
||||
}
|
||||
var ok bool
|
||||
ok, err = tc.append(ctx,
|
||||
tc.cur.CurrentKey(),
|
||||
tc.cur.CurrentValue(),
|
||||
tc.cur.currentKey(),
|
||||
tc.cur.currentValue(),
|
||||
sz)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -434,14 +434,14 @@ func (tc *chunker[S]) finalizeCursor(ctx context.Context) (err error) {
|
||||
break // boundary occurred at same place in old & new Node
|
||||
}
|
||||
|
||||
err = tc.cur.Advance(ctx)
|
||||
err = tc.cur.advance(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if tc.cur.parent != nil {
|
||||
err := tc.cur.parent.Advance(ctx)
|
||||
err := tc.cur.parent.advance(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -37,8 +37,8 @@ type Diff struct {
|
||||
type DiffFn func(context.Context, Diff) error
|
||||
|
||||
type Differ[K ~[]byte, O Ordering[K]] struct {
|
||||
from, to *Cursor
|
||||
fromStop, toStop *Cursor
|
||||
from, to *cursor
|
||||
fromStop, toStop *cursor
|
||||
order O
|
||||
}
|
||||
|
||||
@@ -48,33 +48,33 @@ func DifferFromRoots[K ~[]byte, O Ordering[K]](
|
||||
from, to Node,
|
||||
order O,
|
||||
) (Differ[K, O], error) {
|
||||
var fc, tc *Cursor
|
||||
var fc, tc *cursor
|
||||
var err error
|
||||
|
||||
if !from.empty() {
|
||||
fc, err = NewCursorAtStart(ctx, fromNs, from)
|
||||
fc, err = newCursorAtStart(ctx, fromNs, from)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
} else {
|
||||
fc = &Cursor{}
|
||||
fc = &cursor{}
|
||||
}
|
||||
|
||||
if !to.empty() {
|
||||
tc, err = NewCursorAtStart(ctx, toNs, to)
|
||||
tc, err = newCursorAtStart(ctx, toNs, to)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
} else {
|
||||
tc = &Cursor{}
|
||||
tc = &cursor{}
|
||||
}
|
||||
|
||||
fs, err := NewCursorPastEnd(ctx, fromNs, from)
|
||||
fs, err := newCursorPastEnd(ctx, fromNs, from)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
|
||||
ts, err := NewCursorPastEnd(ctx, toNs, to)
|
||||
ts, err := newCursorPastEnd(ctx, toNs, to)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
@@ -89,10 +89,28 @@ func DifferFromRoots[K ~[]byte, O Ordering[K]](
|
||||
}
|
||||
|
||||
func DifferFromCursors[K ~[]byte, O Ordering[K]](
|
||||
fromStart, toStart,
|
||||
fromStop, toStop *Cursor,
|
||||
ctx context.Context,
|
||||
fromRoot, toRoot Node,
|
||||
findStart, findStop SearchFn,
|
||||
fromStore, toStore NodeStore,
|
||||
order O,
|
||||
) (Differ[K, O], error) {
|
||||
fromStart, err := newCursorFromSearchFn(ctx, fromStore, fromRoot, findStart)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
toStart, err := newCursorFromSearchFn(ctx, toStore, toRoot, findStart)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
fromStop, err := newCursorFromSearchFn(ctx, fromStore, fromRoot, findStop)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
toStop, err := newCursorFromSearchFn(ctx, toStore, toRoot, findStop)
|
||||
if err != nil {
|
||||
return Differ[K, O]{}, err
|
||||
}
|
||||
return Differ[K, O]{
|
||||
from: fromStart,
|
||||
to: toStart,
|
||||
@@ -103,10 +121,10 @@ func DifferFromCursors[K ~[]byte, O Ordering[K]](
|
||||
}
|
||||
|
||||
func (td Differ[K, O]) Next(ctx context.Context) (diff Diff, err error) {
|
||||
for td.from.Valid() && td.from.Compare(td.fromStop) < 0 && td.to.Valid() && td.to.Compare(td.toStop) < 0 {
|
||||
for td.from.valid() && td.from.compare(td.fromStop) < 0 && td.to.valid() && td.to.compare(td.toStop) < 0 {
|
||||
|
||||
f := td.from.CurrentKey()
|
||||
t := td.to.CurrentKey()
|
||||
f := td.from.currentKey()
|
||||
t := td.to.currentKey()
|
||||
cmp := td.order.Compare(K(f), K(t))
|
||||
|
||||
switch {
|
||||
@@ -117,7 +135,7 @@ func (td Differ[K, O]) Next(ctx context.Context) (diff Diff, err error) {
|
||||
return sendAdded(ctx, td.to)
|
||||
|
||||
case cmp == 0:
|
||||
if !equalCursorValues(td.from, td.to) {
|
||||
if !equalcursorValues(td.from, td.to) {
|
||||
return sendModified(ctx, td.from, td.to)
|
||||
}
|
||||
|
||||
@@ -128,65 +146,65 @@ func (td Differ[K, O]) Next(ctx context.Context) (diff Diff, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
if td.from.Valid() && td.from.Compare(td.fromStop) < 0 {
|
||||
if td.from.valid() && td.from.compare(td.fromStop) < 0 {
|
||||
return sendRemoved(ctx, td.from)
|
||||
}
|
||||
if td.to.Valid() && td.to.Compare(td.toStop) < 0 {
|
||||
if td.to.valid() && td.to.compare(td.toStop) < 0 {
|
||||
return sendAdded(ctx, td.to)
|
||||
}
|
||||
|
||||
return Diff{}, io.EOF
|
||||
}
|
||||
|
||||
func sendRemoved(ctx context.Context, from *Cursor) (diff Diff, err error) {
|
||||
func sendRemoved(ctx context.Context, from *cursor) (diff Diff, err error) {
|
||||
diff = Diff{
|
||||
Type: RemovedDiff,
|
||||
Key: from.CurrentKey(),
|
||||
From: from.CurrentValue(),
|
||||
Key: from.currentKey(),
|
||||
From: from.currentValue(),
|
||||
}
|
||||
|
||||
if err = from.Advance(ctx); err != nil {
|
||||
if err = from.advance(ctx); err != nil {
|
||||
return Diff{}, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendAdded(ctx context.Context, to *Cursor) (diff Diff, err error) {
|
||||
func sendAdded(ctx context.Context, to *cursor) (diff Diff, err error) {
|
||||
diff = Diff{
|
||||
Type: AddedDiff,
|
||||
Key: to.CurrentKey(),
|
||||
To: to.CurrentValue(),
|
||||
Key: to.currentKey(),
|
||||
To: to.currentValue(),
|
||||
}
|
||||
|
||||
if err = to.Advance(ctx); err != nil {
|
||||
if err = to.advance(ctx); err != nil {
|
||||
return Diff{}, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sendModified(ctx context.Context, from, to *Cursor) (diff Diff, err error) {
|
||||
func sendModified(ctx context.Context, from, to *cursor) (diff Diff, err error) {
|
||||
diff = Diff{
|
||||
Type: ModifiedDiff,
|
||||
Key: from.CurrentKey(),
|
||||
From: from.CurrentValue(),
|
||||
To: to.CurrentValue(),
|
||||
Key: from.currentKey(),
|
||||
From: from.currentValue(),
|
||||
To: to.currentValue(),
|
||||
}
|
||||
|
||||
if err = from.Advance(ctx); err != nil {
|
||||
if err = from.advance(ctx); err != nil {
|
||||
return Diff{}, err
|
||||
}
|
||||
if err = to.Advance(ctx); err != nil {
|
||||
if err = to.advance(ctx); err != nil {
|
||||
return Diff{}, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func skipCommon(ctx context.Context, from, to *Cursor) (err error) {
|
||||
func skipCommon(ctx context.Context, from, to *cursor) (err error) {
|
||||
// track when |from.parent| and |to.parent| change
|
||||
// to avoid unnecessary comparisons.
|
||||
parentsAreNew := true
|
||||
|
||||
for from.Valid() && to.Valid() {
|
||||
for from.valid() && to.valid() {
|
||||
if !equalItems(from, to) {
|
||||
// found the next difference
|
||||
return nil
|
||||
@@ -209,10 +227,10 @@ func skipCommon(ctx context.Context, from, to *Cursor) (err error) {
|
||||
// case we need to Compare parents again.
|
||||
parentsAreNew = from.atNodeEnd() || to.atNodeEnd()
|
||||
|
||||
if err = from.Advance(ctx); err != nil {
|
||||
if err = from.advance(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = to.Advance(ctx); err != nil {
|
||||
if err = to.advance(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -220,13 +238,13 @@ func skipCommon(ctx context.Context, from, to *Cursor) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func skipCommonParents(ctx context.Context, from, to *Cursor) (err error) {
|
||||
func skipCommonParents(ctx context.Context, from, to *cursor) (err error) {
|
||||
err = skipCommon(ctx, from.parent, to.parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if from.parent.Valid() {
|
||||
if from.parent.valid() {
|
||||
if err = from.fetchNode(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -235,7 +253,7 @@ func skipCommonParents(ctx context.Context, from, to *Cursor) (err error) {
|
||||
from.invalidateAtEnd()
|
||||
}
|
||||
|
||||
if to.parent.Valid() {
|
||||
if to.parent.valid() {
|
||||
if err = to.fetchNode(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -248,18 +266,18 @@ func skipCommonParents(ctx context.Context, from, to *Cursor) (err error) {
|
||||
}
|
||||
|
||||
// todo(andy): assumes equal byte representations
|
||||
func equalItems(from, to *Cursor) bool {
|
||||
return bytes.Equal(from.CurrentKey(), to.CurrentKey()) &&
|
||||
bytes.Equal(from.CurrentValue(), to.CurrentValue())
|
||||
func equalItems(from, to *cursor) bool {
|
||||
return bytes.Equal(from.currentKey(), to.currentKey()) &&
|
||||
bytes.Equal(from.currentValue(), to.currentValue())
|
||||
}
|
||||
|
||||
func equalParents(from, to *Cursor) (eq bool) {
|
||||
func equalParents(from, to *cursor) (eq bool) {
|
||||
if from.parent != nil && to.parent != nil {
|
||||
eq = equalItems(from.parent, to.parent)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func equalCursorValues(from, to *Cursor) bool {
|
||||
return bytes.Equal(from.CurrentValue(), to.CurrentValue())
|
||||
func equalcursorValues(from, to *cursor) bool {
|
||||
return bytes.Equal(from.currentValue(), to.currentValue())
|
||||
}
|
||||
|
||||
+80
-67
@@ -66,56 +66,59 @@ func DiffKeyRangeOrderedTrees[K, V ~[]byte, O Ordering[K]](
|
||||
start, stop K,
|
||||
cb DiffFn,
|
||||
) error {
|
||||
var fromStart, fromStop, toStart, toStop *Cursor
|
||||
var fromStart, fromStop, toStart, toStop *cursor
|
||||
var err error
|
||||
|
||||
if len(start) == 0 {
|
||||
fromStart, err = NewCursorAtStart(ctx, from.NodeStore, from.Root)
|
||||
fromStart, err = newCursorAtStart(ctx, from.NodeStore, from.Root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toStart, err = NewCursorAtStart(ctx, to.NodeStore, to.Root)
|
||||
toStart, err = newCursorAtStart(ctx, to.NodeStore, to.Root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fromStart, err = NewCursorAtKey(ctx, from.NodeStore, from.Root, start, from.Order)
|
||||
fromStart, err = newCursorAtKey(ctx, from.NodeStore, from.Root, start, from.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toStart, err = NewCursorAtKey(ctx, to.NodeStore, to.Root, start, to.Order)
|
||||
toStart, err = newCursorAtKey(ctx, to.NodeStore, to.Root, start, to.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(stop) == 0 {
|
||||
fromStop, err = NewCursorPastEnd(ctx, from.NodeStore, from.Root)
|
||||
fromStop, err = newCursorPastEnd(ctx, from.NodeStore, from.Root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toStop, err = NewCursorPastEnd(ctx, to.NodeStore, to.Root)
|
||||
toStop, err = newCursorPastEnd(ctx, to.NodeStore, to.Root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
fromStop, err = NewCursorAtKey(ctx, from.NodeStore, from.Root, stop, from.Order)
|
||||
fromStop, err = newCursorAtKey(ctx, from.NodeStore, from.Root, stop, from.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toStop, err = NewCursorAtKey(ctx, to.NodeStore, to.Root, stop, to.Order)
|
||||
toStop, err = newCursorAtKey(ctx, to.NodeStore, to.Root, stop, to.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
differ, err := DifferFromCursors[K](fromStart, toStart, fromStop, toStop, from.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
differ := Differ[K, O]{
|
||||
from: fromStart,
|
||||
to: toStart,
|
||||
fromStop: fromStop,
|
||||
toStop: toStop,
|
||||
order: from.Order,
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -157,28 +160,28 @@ func VisitMapLevelOrder[K, V ~[]byte, O Ordering[K]](
|
||||
cb func(h hash.Hash) (int64, error),
|
||||
) error {
|
||||
// get cursor to leaves
|
||||
cur, err := NewCursorAtStart(ctx, m.NodeStore, m.Root)
|
||||
cur, err := newCursorAtStart(ctx, m.NodeStore, m.Root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
first := cur.CurrentKey()
|
||||
first := cur.currentKey()
|
||||
|
||||
// start by iterating level 1 nodes,
|
||||
// then recurse upwards until we're at the root
|
||||
for cur.parent != nil {
|
||||
cur = cur.parent
|
||||
for cur.Valid() {
|
||||
_, err = cb(cur.CurrentRef())
|
||||
for cur.valid() {
|
||||
_, err = cb(cur.currentRef())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = cur.Advance(ctx); err != nil {
|
||||
if err = cur.advance(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// return cursor to the start of the map
|
||||
if err = Seek(ctx, cur, K(first), m.Order); err != nil {
|
||||
if err = seek(ctx, cur, K(first), m.Order); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -215,7 +218,7 @@ func (t StaticMap[K, V, O]) WalkNodes(ctx context.Context, cb NodeCb) error {
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) Get(ctx context.Context, query K, cb KeyValueFn[K, V]) (err error) {
|
||||
cur, err := NewLeafCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
cur, err := newLeafCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -223,10 +226,10 @@ func (t StaticMap[K, V, O]) Get(ctx context.Context, query K, cb KeyValueFn[K, V
|
||||
var key K
|
||||
var value V
|
||||
|
||||
if cur.Valid() {
|
||||
key = K(cur.CurrentKey())
|
||||
if cur.valid() {
|
||||
key = K(cur.currentKey())
|
||||
if t.Order.Compare(query, key) == 0 {
|
||||
value = V(cur.CurrentValue())
|
||||
value = V(cur.currentValue())
|
||||
} else {
|
||||
key = nil
|
||||
}
|
||||
@@ -235,13 +238,13 @@ func (t StaticMap[K, V, O]) Get(ctx context.Context, query K, cb KeyValueFn[K, V
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) Has(ctx context.Context, query K) (ok bool, err error) {
|
||||
cur, err := NewLeafCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
cur, err := newLeafCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if cur.Valid() {
|
||||
ok = t.Order.Compare(query, K(cur.CurrentKey())) == 0
|
||||
if cur.valid() {
|
||||
ok = t.Order.Compare(query, K(cur.currentKey())) == 0
|
||||
}
|
||||
|
||||
return
|
||||
@@ -258,18 +261,18 @@ func (t StaticMap[K, V, O]) LastKey(ctx context.Context) (key K) {
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) IterAll(ctx context.Context) (*OrderedTreeIter[K, V], error) {
|
||||
c, err := NewCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
c, err := newCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := NewCursorPastEnd(ctx, t.NodeStore, t.Root)
|
||||
s, err := newCursorPastEnd(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stop := func(curr *Cursor) bool {
|
||||
return curr.Compare(s) >= 0
|
||||
stop := func(curr *cursor) bool {
|
||||
return curr.compare(s) >= 0
|
||||
}
|
||||
|
||||
if stop(c) {
|
||||
@@ -277,26 +280,26 @@ func (t StaticMap[K, V, O]) IterAll(ctx context.Context) (*OrderedTreeIter[K, V]
|
||||
return &OrderedTreeIter[K, V]{curr: nil}, nil
|
||||
}
|
||||
|
||||
return &OrderedTreeIter[K, V]{curr: c, stop: stop, step: c.Advance}, nil
|
||||
return &OrderedTreeIter[K, V]{curr: c, stop: stop, step: c.advance}, nil
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) IterAllReverse(ctx context.Context) (*OrderedTreeIter[K, V], error) {
|
||||
beginning, err := NewCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
beginning, err := newCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = beginning.Retreat(ctx)
|
||||
err = beginning.retreat(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
end, err := NewCursorAtEnd(ctx, t.NodeStore, t.Root)
|
||||
end, err := newCursorAtEnd(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stop := func(curr *Cursor) bool {
|
||||
return curr.Compare(beginning) <= 0
|
||||
stop := func(curr *cursor) bool {
|
||||
return curr.compare(beginning) <= 0
|
||||
}
|
||||
|
||||
if stop(end) {
|
||||
@@ -304,7 +307,7 @@ func (t StaticMap[K, V, O]) IterAllReverse(ctx context.Context) (*OrderedTreeIte
|
||||
return &OrderedTreeIter[K, V]{curr: nil}, nil
|
||||
}
|
||||
|
||||
return &OrderedTreeIter[K, V]{curr: end, stop: stop, step: end.Retreat}, nil
|
||||
return &OrderedTreeIter[K, V]{curr: end, stop: stop, step: end.retreat}, nil
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) IterOrdinalRange(ctx context.Context, start, stop uint64) (*OrderedTreeIter[K, V], error) {
|
||||
@@ -323,21 +326,21 @@ func (t StaticMap[K, V, O]) IterOrdinalRange(ctx context.Context, start, stop ui
|
||||
}
|
||||
}
|
||||
|
||||
lo, err := NewCursorAtOrdinal(ctx, t.NodeStore, t.Root, start)
|
||||
lo, err := newCursorAtOrdinal(ctx, t.NodeStore, t.Root, start)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hi, err := NewCursorAtOrdinal(ctx, t.NodeStore, t.Root, stop)
|
||||
hi, err := newCursorAtOrdinal(ctx, t.NodeStore, t.Root, stop)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stopF := func(curr *Cursor) bool {
|
||||
return curr.Compare(hi) >= 0
|
||||
stopF := func(curr *cursor) bool {
|
||||
return curr.compare(hi) >= 0
|
||||
}
|
||||
|
||||
return &OrderedTreeIter[K, V]{curr: lo, stop: stopF, step: lo.Advance}, nil
|
||||
return &OrderedTreeIter[K, V]{curr: lo, stop: stopF, step: lo.advance}, nil
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) FetchOrdinalRange(ctx context.Context, start, stop uint64) (*orderedLeafSpanIter[K, V], error) {
|
||||
@@ -355,7 +358,7 @@ func (t StaticMap[K, V, O]) FetchOrdinalRange(ctx context.Context, start, stop u
|
||||
}
|
||||
}
|
||||
|
||||
span, err := FetchLeafNodeSpan(ctx, t.NodeStore, t.Root, start, stop)
|
||||
span, err := fetchLeafNodeSpan(ctx, t.NodeStore, t.Root, start, stop)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -381,15 +384,15 @@ func (t StaticMap[K, V, O]) IterKeyRange(ctx context.Context, start, stop K) (*O
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stopF := func(curr *Cursor) bool {
|
||||
return curr.Compare(hi) >= 0
|
||||
stopF := func(curr *cursor) bool {
|
||||
return curr.compare(hi) >= 0
|
||||
}
|
||||
|
||||
if stopF(lo) {
|
||||
return &OrderedTreeIter[K, V]{curr: nil}, nil
|
||||
}
|
||||
|
||||
return &OrderedTreeIter[K, V]{curr: lo, stop: stopF, step: lo.Advance}, nil
|
||||
return &OrderedTreeIter[K, V]{curr: lo, stop: stopF, step: lo.advance}, nil
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) GetKeyRangeCardinality(ctx context.Context, start, stop K) (uint64, error) {
|
||||
@@ -398,12 +401,12 @@ func (t StaticMap[K, V, O]) GetKeyRangeCardinality(ctx context.Context, start, s
|
||||
return 0, err
|
||||
}
|
||||
|
||||
startOrd, err := GetOrdinalOfCursor(lo)
|
||||
startOrd, err := getOrdinalOfCursor(lo)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
endOrd, err := GetOrdinalOfCursor(hi)
|
||||
endOrd, err := getOrdinalOfCursor(hi)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -411,68 +414,78 @@ func (t StaticMap[K, V, O]) GetKeyRangeCardinality(ctx context.Context, start, s
|
||||
if startOrd > endOrd {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return endOrd - startOrd, nil
|
||||
}
|
||||
|
||||
func (t StaticMap[K, V, O]) getKeyRangeCursors(ctx context.Context, startInclusive, stopExclusive K) (lo, hi *Cursor, err error) {
|
||||
func (t StaticMap[K, V, O]) getKeyRangeCursors(ctx context.Context, startInclusive, stopExclusive K) (lo, hi *cursor, err error) {
|
||||
if len(startInclusive) == 0 {
|
||||
lo, err = NewCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
lo, err = newCursorAtStart(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
lo, err = NewCursorAtKey(ctx, t.NodeStore, t.Root, startInclusive, t.Order)
|
||||
lo, err = newCursorAtKey(ctx, t.NodeStore, t.Root, startInclusive, t.Order)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(stopExclusive) == 0 {
|
||||
hi, err = NewCursorPastEnd(ctx, t.NodeStore, t.Root)
|
||||
hi, err = newCursorPastEnd(ctx, t.NodeStore, t.Root)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
hi, err = NewCursorAtKey(ctx, t.NodeStore, t.Root, stopExclusive, t.Order)
|
||||
hi, err = newCursorAtKey(ctx, t.NodeStore, t.Root, stopExclusive, t.Order)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetOrdinalForKey returns the smallest ordinal position at which the key >= |query|.
|
||||
func (t StaticMap[K, V, O]) GetOrdinalForKey(ctx context.Context, query K) (uint64, error) {
|
||||
cur, err := NewCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
cur, err := newCursorAtKey(ctx, t.NodeStore, t.Root, query, t.Order)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return GetOrdinalOfCursor(cur)
|
||||
return getOrdinalOfCursor(cur)
|
||||
}
|
||||
|
||||
type OrderedTreeIter[K, V ~[]byte] struct {
|
||||
// current tuple location
|
||||
curr *Cursor
|
||||
curr *cursor
|
||||
|
||||
// the function called to moved |curr| forward in the direction of iteration.
|
||||
step func(context.Context) error
|
||||
// should return |true| if the passed in cursor is past the iteration's stopping point.
|
||||
stop func(*Cursor) bool
|
||||
stop func(*cursor) bool
|
||||
}
|
||||
|
||||
func OrderedTreeIterFromCursors[K, V ~[]byte](start, stop *Cursor) *OrderedTreeIter[K, V] {
|
||||
stopF := func(curr *Cursor) bool {
|
||||
return curr.Compare(stop) >= 0
|
||||
func OrderedTreeIterFromCursors[K, V ~[]byte](
|
||||
ctx context.Context,
|
||||
root Node, ns NodeStore,
|
||||
findStart, findStop SearchFn,
|
||||
) (*OrderedTreeIter[K, V], error) {
|
||||
start, err := newCursorFromSearchFn(ctx, ns, root, findStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stop, err := newCursorFromSearchFn(ctx, ns, root, findStop)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if stopF(start) {
|
||||
stopFn := func(curr *cursor) bool {
|
||||
return curr.compare(stop) >= 0
|
||||
}
|
||||
|
||||
if stopFn(start) {
|
||||
start = nil // empty range
|
||||
}
|
||||
|
||||
return &OrderedTreeIter[K, V]{curr: start, stop: stopF, step: start.Advance}
|
||||
return &OrderedTreeIter[K, V]{curr: start, stop: stopFn, step: start.advance}, nil
|
||||
}
|
||||
|
||||
func (it *OrderedTreeIter[K, V]) Next(ctx context.Context) (key K, value V, err error) {
|
||||
@@ -480,7 +493,7 @@ func (it *OrderedTreeIter[K, V]) Next(ctx context.Context) (key K, value V, err
|
||||
return nil, nil, io.EOF
|
||||
}
|
||||
|
||||
k, v := CurrentCursorItems(it.curr)
|
||||
k, v := currentCursorItems(it.curr)
|
||||
key, value = K(k), V(v)
|
||||
|
||||
err = it.step(ctx)
|
||||
@@ -497,8 +510,8 @@ func (it *OrderedTreeIter[K, V]) Next(ctx context.Context) (key K, value V, err
|
||||
|
||||
func (it *OrderedTreeIter[K, V]) Current() (key K, value V) {
|
||||
// |it.curr| is set to nil when its range is exhausted
|
||||
if it.curr != nil && it.curr.Valid() {
|
||||
k, v := CurrentCursorItems(it.curr)
|
||||
if it.curr != nil && it.curr.valid() {
|
||||
k, v := currentCursorItems(it.curr)
|
||||
key, value = K(k), V(v)
|
||||
}
|
||||
return
|
||||
|
||||
@@ -69,12 +69,12 @@ func ApplyMutations[K ~[]byte, O Ordering[K], S message.Serializer](
|
||||
return root, nil // no mutations
|
||||
}
|
||||
|
||||
cur, err := NewCursorAtKey(ctx, ns, root, K(newKey), order)
|
||||
cur, err := newCursorAtKey(ctx, ns, root, K(newKey), order)
|
||||
if err != nil {
|
||||
return Node{}, err
|
||||
}
|
||||
|
||||
chkr, err := newChunker(ctx, cur.Clone(), 0, ns, serializer)
|
||||
chkr, err := newChunker(ctx, cur.clone(), 0, ns, serializer)
|
||||
if err != nil {
|
||||
return Node{}, err
|
||||
}
|
||||
@@ -82,17 +82,17 @@ func ApplyMutations[K ~[]byte, O Ordering[K], S message.Serializer](
|
||||
for newKey != nil {
|
||||
|
||||
// move |cur| to the NextMutation mutation point
|
||||
err = Seek(ctx, cur, K(newKey), order)
|
||||
err = seek(ctx, cur, K(newKey), order)
|
||||
if err != nil {
|
||||
return Node{}, err
|
||||
}
|
||||
|
||||
var oldValue Item
|
||||
if cur.Valid() {
|
||||
if cur.valid() {
|
||||
// Compare mutations |newKey| and |newValue|
|
||||
// to the existing pair from the cursor
|
||||
if order.Compare(K(newKey), K(cur.CurrentKey())) == 0 {
|
||||
oldValue = cur.CurrentValue()
|
||||
if order.Compare(K(newKey), K(cur.currentKey())) == 0 {
|
||||
oldValue = cur.currentValue()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ func ApplyMutations[K ~[]byte, O Ordering[K], S message.Serializer](
|
||||
}
|
||||
|
||||
// move |chkr| to the NextMutation mutation point
|
||||
err = chkr.AdvanceTo(ctx, cur)
|
||||
err = chkr.advanceTo(ctx, cur)
|
||||
if err != nil {
|
||||
return Node{}, err
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ import (
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
)
|
||||
|
||||
// Cursor explores a tree of Nodes.
|
||||
type Cursor struct {
|
||||
// cursor explores a tree of Nodes.
|
||||
type cursor struct {
|
||||
nd Node
|
||||
idx int
|
||||
parent *Cursor
|
||||
parent *cursor
|
||||
nrw NodeStore
|
||||
}
|
||||
|
||||
@@ -43,21 +43,21 @@ type Ordering[K ~[]byte] interface {
|
||||
Compare(left, right K) int
|
||||
}
|
||||
|
||||
func NewCursorAtStart(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor, err error) {
|
||||
cur = &Cursor{nd: nd, nrw: ns}
|
||||
func newCursorAtStart(ctx context.Context, ns NodeStore, nd Node) (cur *cursor, err error) {
|
||||
cur = &cursor{nd: nd, nrw: ns}
|
||||
var leaf bool
|
||||
leaf, err = cur.isLeaf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for !leaf {
|
||||
nd, err = fetchChild(ctx, ns, cur.CurrentRef())
|
||||
nd, err = fetchChild(ctx, ns, cur.currentRef())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parent := cur
|
||||
cur = &Cursor{nd: nd, parent: parent, nrw: ns}
|
||||
cur = &cursor{nd: nd, parent: parent, nrw: ns}
|
||||
leaf, err = cur.isLeaf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -66,8 +66,8 @@ func NewCursorAtStart(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor,
|
||||
return
|
||||
}
|
||||
|
||||
func NewCursorAtEnd(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor, err error) {
|
||||
cur = &Cursor{nd: nd, nrw: ns}
|
||||
func newCursorAtEnd(ctx context.Context, ns NodeStore, nd Node) (cur *cursor, err error) {
|
||||
cur = &cursor{nd: nd, nrw: ns}
|
||||
cur.skipToNodeEnd()
|
||||
|
||||
var leaf bool
|
||||
@@ -76,13 +76,13 @@ func NewCursorAtEnd(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor, er
|
||||
return nil, err
|
||||
}
|
||||
for !leaf {
|
||||
nd, err = fetchChild(ctx, ns, cur.CurrentRef())
|
||||
nd, err = fetchChild(ctx, ns, cur.currentRef())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parent := cur
|
||||
cur = &Cursor{nd: nd, parent: parent, nrw: ns}
|
||||
cur = &cursor{nd: nd, parent: parent, nrw: ns}
|
||||
cur.skipToNodeEnd()
|
||||
leaf, err = cur.isLeaf()
|
||||
if err != nil {
|
||||
@@ -92,14 +92,14 @@ func NewCursorAtEnd(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor, er
|
||||
return
|
||||
}
|
||||
|
||||
func NewCursorPastEnd(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor, err error) {
|
||||
cur, err = NewCursorAtEnd(ctx, ns, nd)
|
||||
func newCursorPastEnd(ctx context.Context, ns NodeStore, nd Node) (cur *cursor, err error) {
|
||||
cur, err = newCursorAtEnd(ctx, ns, nd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Advance |cur| past the end
|
||||
err = cur.Advance(ctx)
|
||||
err = cur.advance(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -110,17 +110,17 @@ func NewCursorPastEnd(ctx context.Context, ns NodeStore, nd Node) (cur *Cursor,
|
||||
return
|
||||
}
|
||||
|
||||
func NewCursorAtOrdinal(ctx context.Context, ns NodeStore, nd Node, ord uint64) (cur *Cursor, err error) {
|
||||
func newCursorAtOrdinal(ctx context.Context, ns NodeStore, nd Node, ord uint64) (cur *cursor, err error) {
|
||||
cnt, err := nd.TreeCount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ord >= uint64(cnt) {
|
||||
return NewCursorPastEnd(ctx, ns, nd)
|
||||
return newCursorPastEnd(ctx, ns, nd)
|
||||
}
|
||||
|
||||
distance := int64(ord)
|
||||
return NewCursorFromSearchFn(ctx, ns, nd, func(nd Node) (idx int) {
|
||||
return newCursorFromSearchFn(ctx, ns, nd, func(nd Node) (idx int) {
|
||||
if nd.IsLeaf() {
|
||||
return int(distance)
|
||||
}
|
||||
@@ -138,8 +138,8 @@ func NewCursorAtOrdinal(ctx context.Context, ns NodeStore, nd Node, ord uint64)
|
||||
})
|
||||
}
|
||||
|
||||
// GetOrdinalOfCursor returns the ordinal position of a Cursor.
|
||||
func GetOrdinalOfCursor(curr *Cursor) (ord uint64, err error) {
|
||||
// GetOrdinalOfCursor returns the ordinal position of a cursor.
|
||||
func getOrdinalOfCursor(curr *cursor) (ord uint64, err error) {
|
||||
leaf, err := curr.isLeaf()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -178,12 +178,12 @@ func GetOrdinalOfCursor(curr *Cursor) (ord uint64, err error) {
|
||||
return ord, nil
|
||||
}
|
||||
|
||||
func NewCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeStore, nd Node, key K, order O) (cur *Cursor, err error) {
|
||||
return NewCursorFromSearchFn(ctx, ns, nd, SearchForKey(key, order))
|
||||
func newCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeStore, nd Node, key K, order O) (cur *cursor, err error) {
|
||||
return newCursorFromSearchFn(ctx, ns, nd, searchForKey(key, order))
|
||||
}
|
||||
|
||||
func NewCursorFromSearchFn(ctx context.Context, ns NodeStore, nd Node, search SearchFn) (cur *Cursor, err error) {
|
||||
cur = &Cursor{nd: nd, nrw: ns}
|
||||
func newCursorFromSearchFn(ctx context.Context, ns NodeStore, nd Node, search SearchFn) (cur *cursor, err error) {
|
||||
cur = &cursor{nd: nd, nrw: ns}
|
||||
|
||||
cur.idx = search(cur.nd)
|
||||
var leaf bool
|
||||
@@ -196,13 +196,13 @@ func NewCursorFromSearchFn(ctx context.Context, ns NodeStore, nd Node, search Se
|
||||
// stay in bounds for internal nodes
|
||||
cur.keepInBounds()
|
||||
|
||||
nd, err = fetchChild(ctx, ns, cur.CurrentRef())
|
||||
nd, err = fetchChild(ctx, ns, cur.currentRef())
|
||||
if err != nil {
|
||||
return cur, err
|
||||
}
|
||||
|
||||
parent := cur
|
||||
cur = &Cursor{nd: nd, parent: parent, nrw: ns}
|
||||
cur = &cursor{nd: nd, parent: parent, nrw: ns}
|
||||
|
||||
cur.idx = search(cur.nd)
|
||||
leaf, err = cur.isLeaf()
|
||||
@@ -214,8 +214,8 @@ func NewCursorFromSearchFn(ctx context.Context, ns NodeStore, nd Node, search Se
|
||||
return
|
||||
}
|
||||
|
||||
func NewLeafCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeStore, nd Node, key K, order O) (Cursor, error) {
|
||||
cur := Cursor{nd: nd, nrw: ns}
|
||||
func newLeafCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeStore, nd Node, key K, order O) (cursor, error) {
|
||||
cur := cursor{nd: nd, nrw: ns}
|
||||
for {
|
||||
// binary search |cur.nd| for |key|
|
||||
i, j := 0, cur.nd.Count()
|
||||
@@ -241,7 +241,7 @@ func NewLeafCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeSt
|
||||
cur.keepInBounds()
|
||||
|
||||
// reuse |cur| object to keep stack alloc'd
|
||||
cur.nd, err = fetchChild(ctx, ns, cur.CurrentRef())
|
||||
cur.nd, err = fetchChild(ctx, ns, cur.currentRef())
|
||||
if err != nil {
|
||||
return cur, err
|
||||
}
|
||||
@@ -249,8 +249,8 @@ func NewLeafCursorAtKey[K ~[]byte, O Ordering[K]](ctx context.Context, ns NodeSt
|
||||
return cur, nil
|
||||
}
|
||||
|
||||
// SearchForKey returns a SearchFn for |key|.
|
||||
func SearchForKey[K ~[]byte, O Ordering[K]](key K, order O) SearchFn {
|
||||
// searchForKey returns a SearchFn for |key|.
|
||||
func searchForKey[K ~[]byte, O Ordering[K]](key K, order O) SearchFn {
|
||||
return func(nd Node) (idx int) {
|
||||
n := int(nd.Count())
|
||||
// Define f(-1) == false and f(n) == true.
|
||||
@@ -280,8 +280,8 @@ type LeafSpan struct {
|
||||
|
||||
// FetchLeafNodeSpan returns the leaf Node span for the ordinal range [start, stop). It fetches the span using
|
||||
// an eager breadth-first search and makes batch read calls to the persistence layer via NodeStore.ReadMany.
|
||||
func FetchLeafNodeSpan(ctx context.Context, ns NodeStore, root Node, start, stop uint64) (LeafSpan, error) {
|
||||
leaves, localStart, err := fetchLeafNodeSpan(ctx, ns, []Node{root}, start, stop)
|
||||
func fetchLeafNodeSpan(ctx context.Context, ns NodeStore, root Node, start, stop uint64) (LeafSpan, error) {
|
||||
leaves, localStart, err := recursiveFetchLeafNodeSpan(ctx, ns, []Node{root}, start, stop)
|
||||
if err != nil {
|
||||
return LeafSpan{}, err
|
||||
}
|
||||
@@ -298,7 +298,7 @@ func FetchLeafNodeSpan(ctx context.Context, ns NodeStore, root Node, start, stop
|
||||
}, nil
|
||||
}
|
||||
|
||||
func fetchLeafNodeSpan(ctx context.Context, ns NodeStore, nodes []Node, start, stop uint64) ([]Node, uint64, error) {
|
||||
func recursiveFetchLeafNodeSpan(ctx context.Context, ns NodeStore, nodes []Node, start, stop uint64) ([]Node, uint64, error) {
|
||||
if nodes[0].IsLeaf() {
|
||||
// verify leaf homogeneity
|
||||
for i := range nodes {
|
||||
@@ -342,20 +342,20 @@ func fetchLeafNodeSpan(ctx context.Context, ns NodeStore, nodes []Node, start, s
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return fetchLeafNodeSpan(ctx, ns, children, start, stop)
|
||||
return recursiveFetchLeafNodeSpan(ctx, ns, children, start, stop)
|
||||
}
|
||||
|
||||
func CurrentCursorItems(cur *Cursor) (key, value Item) {
|
||||
func currentCursorItems(cur *cursor) (key, value Item) {
|
||||
key = cur.nd.keys.GetItem(cur.idx, cur.nd.msg)
|
||||
value = cur.nd.values.GetItem(cur.idx, cur.nd.msg)
|
||||
return
|
||||
}
|
||||
|
||||
// Seek updates the cursor's node to one whose range spans the key's value, or the last
|
||||
// seek updates the cursor's node to one whose range spans the key's value, or the last
|
||||
// node if the key is greater than all existing keys.
|
||||
// If a node does not contain the key, we recurse upwards to the parent cursor. If the
|
||||
// node contains a key, we recurse downwards into child nodes.
|
||||
func Seek[K ~[]byte, O Ordering[K]](ctx context.Context, cur *Cursor, key K, order O) (err error) {
|
||||
func seek[K ~[]byte, O Ordering[K]](ctx context.Context, cur *cursor, key K, order O) (err error) {
|
||||
inBounds := true
|
||||
if cur.parent != nil {
|
||||
inBounds = inBounds && order.Compare(key, K(cur.firstKey())) >= 0
|
||||
@@ -364,44 +364,44 @@ func Seek[K ~[]byte, O Ordering[K]](ctx context.Context, cur *Cursor, key K, ord
|
||||
|
||||
if !inBounds {
|
||||
// |item| is outside the bounds of |cur.nd|, search up the tree
|
||||
err = Seek(ctx, cur.parent, key, order)
|
||||
err = seek(ctx, cur.parent, key, order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// stay in bounds for internal nodes
|
||||
cur.parent.keepInBounds()
|
||||
|
||||
cur.nd, err = fetchChild(ctx, cur.nrw, cur.parent.CurrentRef())
|
||||
cur.nd, err = fetchChild(ctx, cur.nrw, cur.parent.currentRef())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cur.idx = SearchForKey(key, order)(cur.nd)
|
||||
cur.idx = searchForKey(key, order)(cur.nd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (cur *Cursor) Valid() bool {
|
||||
func (cur *cursor) valid() bool {
|
||||
return cur.nd.count != 0 &&
|
||||
cur.nd.bytes() != nil &&
|
||||
cur.idx >= 0 &&
|
||||
cur.idx < int(cur.nd.count)
|
||||
}
|
||||
|
||||
func (cur *Cursor) CurrentKey() Item {
|
||||
func (cur *cursor) currentKey() Item {
|
||||
return cur.nd.GetKey(cur.idx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) CurrentValue() Item {
|
||||
func (cur *cursor) currentValue() Item {
|
||||
return cur.nd.GetValue(cur.idx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) CurrentRef() hash.Hash {
|
||||
func (cur *cursor) currentRef() hash.Hash {
|
||||
return cur.nd.getAddress(cur.idx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) currentSubtreeSize() (uint64, error) {
|
||||
func (cur *cursor) currentSubtreeSize() (uint64, error) {
|
||||
leaf, err := cur.isLeaf()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -416,25 +416,25 @@ func (cur *Cursor) currentSubtreeSize() (uint64, error) {
|
||||
return cur.nd.getSubtreeCount(cur.idx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) firstKey() Item {
|
||||
func (cur *cursor) firstKey() Item {
|
||||
return cur.nd.GetKey(0)
|
||||
}
|
||||
|
||||
func (cur *Cursor) lastKey() Item {
|
||||
func (cur *cursor) lastKey() Item {
|
||||
lastKeyIdx := int(cur.nd.count) - 1
|
||||
return cur.nd.GetKey(lastKeyIdx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) skipToNodeStart() {
|
||||
func (cur *cursor) skipToNodeStart() {
|
||||
cur.idx = 0
|
||||
}
|
||||
|
||||
func (cur *Cursor) skipToNodeEnd() {
|
||||
func (cur *cursor) skipToNodeEnd() {
|
||||
lastKeyIdx := int(cur.nd.count) - 1
|
||||
cur.idx = lastKeyIdx
|
||||
}
|
||||
|
||||
func (cur *Cursor) keepInBounds() {
|
||||
func (cur *cursor) keepInBounds() {
|
||||
if cur.idx < 0 {
|
||||
cur.skipToNodeStart()
|
||||
}
|
||||
@@ -444,18 +444,18 @@ func (cur *Cursor) keepInBounds() {
|
||||
}
|
||||
}
|
||||
|
||||
func (cur *Cursor) atNodeStart() bool {
|
||||
func (cur *cursor) atNodeStart() bool {
|
||||
return cur.idx == 0
|
||||
}
|
||||
|
||||
// atNodeEnd returns true if the cursor's current |idx|
|
||||
// points to the last node item
|
||||
func (cur *Cursor) atNodeEnd() bool {
|
||||
func (cur *cursor) atNodeEnd() bool {
|
||||
lastKeyIdx := int(cur.nd.count) - 1
|
||||
return cur.idx == lastKeyIdx
|
||||
}
|
||||
|
||||
func (cur *Cursor) isLeaf() (bool, error) {
|
||||
func (cur *cursor) isLeaf() (bool, error) {
|
||||
// todo(andy): cache Level
|
||||
lvl, err := cur.level()
|
||||
if err != nil {
|
||||
@@ -464,17 +464,17 @@ func (cur *Cursor) isLeaf() (bool, error) {
|
||||
return lvl == 0, nil
|
||||
}
|
||||
|
||||
func (cur *Cursor) level() (uint64, error) {
|
||||
func (cur *cursor) level() (uint64, error) {
|
||||
return uint64(cur.nd.level), nil
|
||||
}
|
||||
|
||||
// invalidateAtEnd sets the cursor's index to the node count.
|
||||
func (cur *Cursor) invalidateAtEnd() {
|
||||
func (cur *cursor) invalidateAtEnd() {
|
||||
cur.idx = int(cur.nd.count)
|
||||
}
|
||||
|
||||
// invalidateAtStart sets the cursor's index to -1.
|
||||
func (cur *Cursor) invalidateAtStart() {
|
||||
func (cur *cursor) invalidateAtStart() {
|
||||
cur.idx = -1
|
||||
}
|
||||
|
||||
@@ -482,24 +482,24 @@ func (cur *Cursor) invalidateAtStart() {
|
||||
// check the parent to know that the current cursor
|
||||
// has more keys. hasNext can be false even if parent
|
||||
// cursors are not exhausted.
|
||||
func (cur *Cursor) hasNext() bool {
|
||||
func (cur *cursor) hasNext() bool {
|
||||
return cur.idx < int(cur.nd.count)-1
|
||||
}
|
||||
|
||||
// hasPrev returns true if the current node has preceding
|
||||
// keys. hasPrev can be false even in a parent node has
|
||||
// preceding keys.
|
||||
func (cur *Cursor) hasPrev() bool {
|
||||
func (cur *cursor) hasPrev() bool {
|
||||
return cur.idx > 0
|
||||
}
|
||||
|
||||
// outOfBounds returns true if the current cursor and
|
||||
// all parents are exhausted.
|
||||
func (cur *Cursor) outOfBounds() bool {
|
||||
func (cur *cursor) outOfBounds() bool {
|
||||
return cur.idx < 0 || cur.idx >= int(cur.nd.count)
|
||||
}
|
||||
|
||||
// Advance either increments the current key index by one,
|
||||
// advance either increments the current key index by one,
|
||||
// or has reached the end of the current node and skips to the next
|
||||
// child of the parent cursor, recursively if necessary, returning
|
||||
// either an error or nil.
|
||||
@@ -516,7 +516,7 @@ func (cur *Cursor) outOfBounds() bool {
|
||||
//
|
||||
// 3) We've exhausted the current cursor and every |parent|. Jump
|
||||
// to an end state (idx = node.count).
|
||||
func (cur *Cursor) Advance(ctx context.Context) error {
|
||||
func (cur *cursor) advance(ctx context.Context) error {
|
||||
if cur.hasNext() {
|
||||
cur.idx++
|
||||
return nil
|
||||
@@ -528,7 +528,7 @@ func (cur *Cursor) Advance(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// recursively increment the parent
|
||||
err := cur.parent.Advance(ctx)
|
||||
err := cur.parent.advance(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -549,9 +549,9 @@ func (cur *Cursor) Advance(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Retreat decrements to the previous key, if necessary by
|
||||
// retreat decrements to the previous key, if necessary by
|
||||
// recursively decrementing parent nodes.
|
||||
func (cur *Cursor) Retreat(ctx context.Context) error {
|
||||
func (cur *cursor) retreat(ctx context.Context) error {
|
||||
if cur.hasPrev() {
|
||||
cur.idx--
|
||||
return nil
|
||||
@@ -563,7 +563,7 @@ func (cur *Cursor) Retreat(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// recursively decrement the parent
|
||||
err := cur.parent.Retreat(ctx)
|
||||
err := cur.parent.retreat(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -586,9 +586,9 @@ func (cur *Cursor) Retreat(ctx context.Context) error {
|
||||
|
||||
// fetchNode loads the Node that the cursor index points to.
|
||||
// It's called whenever the cursor advances/retreats to a different chunk.
|
||||
func (cur *Cursor) fetchNode(ctx context.Context) (err error) {
|
||||
func (cur *cursor) fetchNode(ctx context.Context) (err error) {
|
||||
assertTrue(cur.parent != nil, "cannot fetch node for cursor with nil parent")
|
||||
cur.nd, err = fetchChild(ctx, cur.nrw, cur.parent.CurrentRef())
|
||||
cur.nd, err = fetchChild(ctx, cur.nrw, cur.parent.currentRef())
|
||||
cur.idx = -1 // caller must set
|
||||
return err
|
||||
}
|
||||
@@ -608,25 +608,25 @@ func (cur *Cursor) fetchNode(ctx context.Context) (err error) {
|
||||
// other: L3 -> 4, L2 -> 3, L1 -> 5, L0 -> 4
|
||||
//
|
||||
// res => +1 (from level 2)
|
||||
func (cur *Cursor) Compare(other *Cursor) int {
|
||||
func (cur *cursor) compare(other *cursor) int {
|
||||
return compareCursors(cur, other)
|
||||
}
|
||||
|
||||
func (cur *Cursor) Clone() *Cursor {
|
||||
cln := Cursor{
|
||||
func (cur *cursor) clone() *cursor {
|
||||
cln := cursor{
|
||||
nd: cur.nd,
|
||||
idx: cur.idx,
|
||||
nrw: cur.nrw,
|
||||
}
|
||||
|
||||
if cur.parent != nil {
|
||||
cln.parent = cur.parent.Clone()
|
||||
cln.parent = cur.parent.clone()
|
||||
}
|
||||
|
||||
return &cln
|
||||
}
|
||||
|
||||
func (cur *Cursor) copy(other *Cursor) {
|
||||
func (cur *cursor) copy(other *cursor) {
|
||||
cur.nd = other.nd
|
||||
cur.idx = other.idx
|
||||
cur.nrw = other.nrw
|
||||
@@ -639,7 +639,7 @@ func (cur *Cursor) copy(other *Cursor) {
|
||||
}
|
||||
}
|
||||
|
||||
func compareCursors(left, right *Cursor) (diff int) {
|
||||
func compareCursors(left, right *cursor) (diff int) {
|
||||
diff = 0
|
||||
for {
|
||||
d := left.idx - right.idx
|
||||
|
||||
@@ -118,29 +118,10 @@ func DiffMaps(ctx context.Context, from, to Map, cb tree.DiffFn) error {
|
||||
// RangeDiffMaps returns diffs within a Range. See Range for which diffs are
|
||||
// returned.
|
||||
func RangeDiffMaps(ctx context.Context, from, to Map, rng Range, cb tree.DiffFn) error {
|
||||
fns, tns := from.tuples.NodeStore, to.tuples.NodeStore
|
||||
|
||||
fromStart, err := tree.NewCursorFromSearchFn(ctx, fns, from.tuples.Root, rangeStartSearchFn(rng))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
toStart, err := tree.NewCursorFromSearchFn(ctx, tns, to.tuples.Root, rangeStartSearchFn(rng))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fromStop, err := tree.NewCursorFromSearchFn(ctx, fns, from.tuples.Root, rangeStopSearchFn(rng))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
toStop, err := tree.NewCursorFromSearchFn(ctx, tns, to.tuples.Root, rangeStopSearchFn(rng))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
differ, err := tree.DifferFromCursors[val.Tuple, val.TupleDesc](
|
||||
fromStart, toStart,
|
||||
fromStop, toStop,
|
||||
ctx, from.tuples.Root, to.tuples.Root,
|
||||
rangeStartSearchFn(rng), rangeStopSearchFn(rng),
|
||||
from.NodeStore(), to.NodeStore(),
|
||||
from.tuples.Order,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -287,10 +268,28 @@ func (m Map) FetchOrdinalRange(ctx context.Context, start, stop uint64) (MapIter
|
||||
return m.tuples.FetchOrdinalRange(ctx, start, stop)
|
||||
}
|
||||
|
||||
// HasRange returns true if the Map contains a key in |rng|.
|
||||
func (m Map) HasRange(ctx context.Context, rng Range) (bool, error) {
|
||||
iter, err := m.IterRange(ctx, rng)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
k, _, err := iter.Next(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return rng.Matches(k), nil
|
||||
}
|
||||
|
||||
// IterRange returns a mutableMapIter that iterates over a Range.
|
||||
func (m Map) IterRange(ctx context.Context, rng Range) (MapIter, error) {
|
||||
if rng.IsPointLookup(m.keyDesc) {
|
||||
return m.pointLookupFromRange(ctx, rng)
|
||||
var iter MapIter
|
||||
err := m.Get(ctx, rng.Tup, func(key val.Tuple, value val.Tuple) error {
|
||||
iter = &pointLookup{k: key, v: value}
|
||||
return nil
|
||||
})
|
||||
return iter, err
|
||||
}
|
||||
|
||||
iter, err := treeIterFromRange(ctx, m.tuples.Root, m.tuples.NodeStore, rng)
|
||||
@@ -300,13 +299,6 @@ func (m Map) IterRange(ctx context.Context, rng Range) (MapIter, error) {
|
||||
return filteredIter{iter: iter, rng: rng}, nil
|
||||
}
|
||||
|
||||
// IterKeyRange iterates over a physical key range defined by |start| and
|
||||
// |stop|. If |startInclusive| and/or |stop| is nil, the range will be open
|
||||
// towards that end.
|
||||
func (m Map) IterKeyRange(ctx context.Context, start, stop val.Tuple) (MapIter, error) {
|
||||
return m.tuples.IterKeyRange(ctx, start, stop)
|
||||
}
|
||||
|
||||
// GetOrdinalForKey returns the smallest ordinal position at which the key >=
|
||||
// |query|.
|
||||
func (m Map) GetOrdinalForKey(ctx context.Context, query val.Tuple) (uint64, error) {
|
||||
@@ -332,49 +324,14 @@ func (m Map) CompareItems(left, right tree.Item) int {
|
||||
return m.keyDesc.Compare(val.Tuple(left), val.Tuple(right))
|
||||
}
|
||||
|
||||
func (m Map) pointLookupFromRange(ctx context.Context, rng Range) (*pointLookup, error) {
|
||||
cur, err := tree.NewCursorFromSearchFn(ctx, m.tuples.NodeStore, m.tuples.Root, rangeStartSearchFn(rng))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !cur.Valid() {
|
||||
// map does not contain |rng|
|
||||
return &pointLookup{}, nil
|
||||
}
|
||||
|
||||
key := val.Tuple(cur.CurrentKey())
|
||||
value := val.Tuple(cur.CurrentValue())
|
||||
|
||||
if !rng.Matches(key) {
|
||||
return &pointLookup{}, nil
|
||||
}
|
||||
|
||||
return &pointLookup{k: key, v: value}, nil
|
||||
}
|
||||
|
||||
func treeIterFromRange(
|
||||
ctx context.Context,
|
||||
root tree.Node,
|
||||
ns tree.NodeStore,
|
||||
rng Range,
|
||||
) (*tree.OrderedTreeIter[val.Tuple, val.Tuple], error) {
|
||||
var (
|
||||
err error
|
||||
start *tree.Cursor
|
||||
stop *tree.Cursor
|
||||
)
|
||||
|
||||
start, err = tree.NewCursorFromSearchFn(ctx, ns, root, rangeStartSearchFn(rng))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stop, err = tree.NewCursorFromSearchFn(ctx, ns, root, rangeStopSearchFn(rng))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tree.OrderedTreeIterFromCursors[val.Tuple, val.Tuple](start, stop), nil
|
||||
findStart, findStop := rangeStartSearchFn(rng), rangeStopSearchFn(rng)
|
||||
return tree.OrderedTreeIterFromCursors[val.Tuple, val.Tuple](ctx, root, ns, findStart, findStop)
|
||||
}
|
||||
|
||||
func NewPointLookup(k, v val.Tuple) *pointLookup {
|
||||
|
||||
Reference in New Issue
Block a user