mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-22 02:50:04 -05:00
added prolly tree implementation for conflicts map
This commit is contained in:
@@ -85,7 +85,7 @@ func runShow(ctx context.Context, args []string) int {
|
||||
chunk, err := cs.Get(ctx, sp.Path.Hash)
|
||||
util.CheckErrorNoUsage(err)
|
||||
|
||||
value = tree.MapNodeFromBytes(chunk.Data())
|
||||
value = tree.NodeFromBytes(chunk.Data())
|
||||
} else {
|
||||
util.CheckErrorNoUsage(err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
// Copyright 2021 Dolthub, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package prolly
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/prolly/tree"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
"github.com/dolthub/dolt/go/store/val"
|
||||
)
|
||||
|
||||
type Conflict val.Triple[val.Tuple]
|
||||
|
||||
func (c Conflict) OurValue() val.Tuple {
|
||||
return val.Tuple(val.Triple(c).First())
|
||||
}
|
||||
|
||||
func (c Conflict) TheirValue() val.Tuple {
|
||||
return val.Tuple(val.Triple(c).Second())
|
||||
}
|
||||
|
||||
func (c Conflict) BaseValue() val.Tuple {
|
||||
return val.Tuple(val.Triple(c).Third())
|
||||
}
|
||||
|
||||
type ConflictIter kvIter[val.Tuple, Conflict]
|
||||
|
||||
type ConflictMap struct {
|
||||
conflicts orderedTree[val.Tuple, Conflict, val.TupleDesc]
|
||||
keyDesc val.TupleDesc
|
||||
ourDesc val.TupleDesc
|
||||
theirDesc val.TupleDesc
|
||||
baseDesc val.TupleDesc
|
||||
}
|
||||
|
||||
func NewConflictMap(ns tree.NodeStore, key, ours, theirs, base val.TupleDesc) ConflictMap {
|
||||
conflicts := orderedTree[val.Tuple, Conflict, val.TupleDesc]{
|
||||
root: tree.NewEmptyNode(ns.Pool()),
|
||||
ns: ns,
|
||||
order: key,
|
||||
}
|
||||
return ConflictMap{
|
||||
conflicts: conflicts,
|
||||
keyDesc: key,
|
||||
ourDesc: ours,
|
||||
theirDesc: theirs,
|
||||
baseDesc: base,
|
||||
}
|
||||
}
|
||||
|
||||
// Count returns the number of key-value pairs in the Map.
|
||||
func (c ConflictMap) Count() int {
|
||||
return c.conflicts.count()
|
||||
}
|
||||
|
||||
func (c ConflictMap) Height() int {
|
||||
return c.conflicts.height()
|
||||
}
|
||||
|
||||
// HashOf returns the Hash of this Map.
|
||||
func (c ConflictMap) HashOf() hash.Hash {
|
||||
return c.conflicts.hashOf()
|
||||
}
|
||||
|
||||
// Format returns the NomsBinFormat of this Map.
|
||||
func (c ConflictMap) Format() *types.NomsBinFormat {
|
||||
return c.conflicts.ns.Format()
|
||||
}
|
||||
|
||||
// Descriptors returns the TupleDesc's from this Map.
|
||||
func (c ConflictMap) Descriptors() (key, ours, theirs, base val.TupleDesc) {
|
||||
return c.keyDesc, c.ourDesc, c.theirDesc, c.baseDesc
|
||||
}
|
||||
|
||||
func (c ConflictMap) WalkAddresses(ctx context.Context, cb tree.AddressCb) error {
|
||||
return c.conflicts.walkAddresses(ctx, cb)
|
||||
}
|
||||
|
||||
func (c ConflictMap) WalkNodes(ctx context.Context, cb tree.NodeCb) error {
|
||||
return c.conflicts.walkNodes(ctx, cb)
|
||||
}
|
||||
|
||||
func (c ConflictMap) Get(ctx context.Context, key val.Tuple, cb KeyValueFn[val.Tuple, Conflict]) (err error) {
|
||||
return c.conflicts.get(ctx, key, cb)
|
||||
}
|
||||
|
||||
func (c ConflictMap) Has(ctx context.Context, key val.Tuple) (ok bool, err error) {
|
||||
return c.conflicts.has(ctx, key)
|
||||
}
|
||||
|
||||
// IterAll returns a mutableMapIter that iterates over the entire Map.
|
||||
func (c ConflictMap) IterAll(ctx context.Context) (ConflictIter, error) {
|
||||
return c.conflicts.iterAll(ctx)
|
||||
}
|
||||
|
||||
// IterOrdinalRange returns a MapIter for the ordinal range beginning at |start| and ending before |stop|.
|
||||
func (c ConflictMap) IterOrdinalRange(ctx context.Context, start, stop uint64) (ConflictIter, error) {
|
||||
return c.conflicts.iterOrdinalRange(ctx, start, stop)
|
||||
}
|
||||
|
||||
func (c ConflictMap) Writer() ConflictWriter {
|
||||
return ConflictWriter{
|
||||
conflicts: c.conflicts.mutate(),
|
||||
keyDesc: c.keyDesc,
|
||||
ourDesc: c.ourDesc,
|
||||
theirDesc: c.theirDesc,
|
||||
baseDesc: c.baseDesc,
|
||||
}
|
||||
}
|
||||
|
||||
type ConflictWriter struct {
|
||||
conflicts orderedMap[val.Tuple, Conflict, val.TupleDesc]
|
||||
keyDesc val.TupleDesc
|
||||
ourDesc val.TupleDesc
|
||||
theirDesc val.TupleDesc
|
||||
baseDesc val.TupleDesc
|
||||
}
|
||||
|
||||
func (wr ConflictWriter) AddConflict(ctx context.Context, key, ourVal, theirVal, baseVal val.Tuple) error {
|
||||
p := wr.conflicts.tree.ns.Pool()
|
||||
c := val.NewTriple(p, ourVal, theirVal, baseVal)
|
||||
return wr.conflicts.put(ctx, key, c)
|
||||
}
|
||||
|
||||
func (wr ConflictWriter) DeleteConflict(ctx context.Context, key val.Tuple) error {
|
||||
return wr.conflicts.delete(ctx, key)
|
||||
}
|
||||
|
||||
func (wr ConflictWriter) Flush(ctx context.Context) (ConflictMap, error) {
|
||||
root, err := wr.conflicts.makeTree(ctx)
|
||||
if err != nil {
|
||||
return ConflictMap{}, err
|
||||
}
|
||||
return ConflictMap{
|
||||
conflicts: root,
|
||||
keyDesc: wr.keyDesc,
|
||||
ourDesc: wr.ourDesc,
|
||||
theirDesc: wr.theirDesc,
|
||||
baseDesc: wr.baseDesc,
|
||||
}, nil
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
)
|
||||
|
||||
func NodeFromValue(v types.Value) tree.Node {
|
||||
return tree.MapNodeFromBytes(v.(types.TupleRowStorage))
|
||||
return tree.NodeFromBytes(v.(types.TupleRowStorage))
|
||||
}
|
||||
|
||||
func ValueFromMap(m Map) types.Value {
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/pool"
|
||||
|
||||
fb "github.com/google/flatbuffers/go"
|
||||
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
@@ -82,12 +84,17 @@ func WalkNodes(ctx context.Context, nd Node, ns NodeStore, cb NodeCb) error {
|
||||
})
|
||||
}
|
||||
|
||||
func MapNodeFromBytes(buf []byte) Node {
|
||||
msg := serial.GetRootAsProllyTreeNode(buf, 0)
|
||||
return mapNodeFromFlatbuffer(*msg)
|
||||
func NewEmptyNode(pool pool.BuffPool) Node {
|
||||
bld := &nodeBuilder{}
|
||||
return bld.build(pool)
|
||||
}
|
||||
|
||||
func mapNodeFromFlatbuffer(msg serial.ProllyTreeNode) Node {
|
||||
func NodeFromBytes(buf []byte) Node {
|
||||
msg := serial.GetRootAsProllyTreeNode(buf, 0)
|
||||
return nodeFromFlatbuffer(*msg)
|
||||
}
|
||||
|
||||
func nodeFromFlatbuffer(msg serial.ProllyTreeNode) Node {
|
||||
keys := val.SlicedBuffer{
|
||||
Buf: msg.KeyItemsBytes(),
|
||||
Offs: getKeyOffsetsVector(msg),
|
||||
|
||||
@@ -143,7 +143,7 @@ func (nb *nodeBuilder) build(pool pool.BuffPool) (node Node) {
|
||||
b.Finish(serial.ProllyTreeNodeEnd(b))
|
||||
|
||||
buf := b.FinishedBytes()
|
||||
return MapNodeFromBytes(buf)
|
||||
return NodeFromBytes(buf)
|
||||
}
|
||||
|
||||
func newSubtreeCounts(count int) subtreeCounts {
|
||||
|
||||
@@ -70,7 +70,7 @@ func NewNodeStore(cs chunks.ChunkStore) NodeStore {
|
||||
func (ns nodeStore) Read(ctx context.Context, ref hash.Hash) (Node, error) {
|
||||
c, ok := ns.cache.get(ref)
|
||||
if ok {
|
||||
return MapNodeFromBytes(c.Data()), nil
|
||||
return NodeFromBytes(c.Data()), nil
|
||||
}
|
||||
|
||||
c, err := ns.store.Get(ctx, ref)
|
||||
@@ -81,7 +81,7 @@ func (ns nodeStore) Read(ctx context.Context, ref hash.Hash) (Node, error) {
|
||||
|
||||
ns.cache.insert(c)
|
||||
|
||||
return MapNodeFromBytes(c.Data()), err
|
||||
return NodeFromBytes(c.Data()), err
|
||||
}
|
||||
|
||||
// Write implements NodeStore.
|
||||
|
||||
@@ -107,6 +107,15 @@ func TestCountArray(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewEmptyNode(t *testing.T) {
|
||||
empty := NewEmptyNode(sharedPool)
|
||||
assert.Equal(t, 0, empty.Level())
|
||||
assert.Equal(t, 0, empty.Count())
|
||||
assert.Equal(t, 72, empty.Size())
|
||||
assert.Equal(t, 0, empty.TreeCount())
|
||||
assert.True(t, empty.IsLeaf())
|
||||
}
|
||||
|
||||
func randomNodeItemPairs(t *testing.T, count int) (keys, values []Item) {
|
||||
keys = make([]Item, count)
|
||||
for i := range keys {
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
package val
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewTriple(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user