mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-26 02:58:44 -06:00
164 lines
4.5 KiB
Go
164 lines
4.5 KiB
Go
// Copyright 2022 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 (
|
|
"bytes"
|
|
"context"
|
|
"encoding/binary"
|
|
|
|
"github.com/dolthub/dolt/go/store/hash"
|
|
"github.com/dolthub/dolt/go/store/pool"
|
|
"github.com/dolthub/dolt/go/store/prolly/message"
|
|
"github.com/dolthub/dolt/go/store/prolly/tree"
|
|
"github.com/dolthub/dolt/go/store/types"
|
|
)
|
|
|
|
type CommitClosureValue []byte
|
|
|
|
type CommitClosure struct {
|
|
closure tree.StaticMap[CommitClosureKey, CommitClosureValue, commitClosureKeyOrdering]
|
|
}
|
|
|
|
type commitClosureKeyOrdering struct{}
|
|
|
|
var _ tree.Ordering[CommitClosureKey] = commitClosureKeyOrdering{}
|
|
|
|
func (o commitClosureKeyOrdering) Compare(left, right CommitClosureKey) int {
|
|
lh, rh := left.Height(), right.Height()
|
|
if lh == rh {
|
|
return bytes.Compare(left[8:], right[8:])
|
|
} else if lh < rh {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
|
|
func NewEmptyCommitClosure(ns tree.NodeStore) (CommitClosure, error) {
|
|
serializer := message.NewCommitClosureSerializer(ns.Pool())
|
|
msg := serializer.Serialize(nil, nil, nil, 0)
|
|
node, err := tree.NodeFromBytes(msg)
|
|
if err != nil {
|
|
return CommitClosure{}, err
|
|
}
|
|
return NewCommitClosure(node, ns)
|
|
}
|
|
|
|
func NewCommitClosure(node tree.Node, ns tree.NodeStore) (CommitClosure, error) {
|
|
return CommitClosure{
|
|
closure: tree.StaticMap[CommitClosureKey, CommitClosureValue, commitClosureKeyOrdering]{
|
|
Root: node,
|
|
NodeStore: ns,
|
|
Order: commitClosureKeyOrdering{},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (c CommitClosure) Count() (int, error) {
|
|
return c.closure.Count()
|
|
}
|
|
|
|
func (c CommitClosure) Height() (int, error) {
|
|
return c.closure.Height()
|
|
}
|
|
|
|
func (c CommitClosure) Node() tree.Node {
|
|
return c.closure.Root
|
|
}
|
|
|
|
func (c CommitClosure) HashOf() hash.Hash {
|
|
return c.closure.HashOf()
|
|
}
|
|
|
|
func (c CommitClosure) Format() *types.NomsBinFormat {
|
|
return c.closure.NodeStore.Format()
|
|
}
|
|
|
|
func (c CommitClosure) Editor() CommitClosureEditor {
|
|
return CommitClosureEditor{
|
|
closure: c.closure.Mutate(),
|
|
}
|
|
}
|
|
|
|
func (c CommitClosure) IterAllReverse(ctx context.Context) (CommitClosureIter, error) {
|
|
return c.closure.IterAllReverse(ctx)
|
|
}
|
|
|
|
func DecodeCommitClosureKey(key []byte) (height uint64, addr hash.Hash) {
|
|
height = binary.LittleEndian.Uint64(key)
|
|
addr = hash.New(key[8:])
|
|
return
|
|
}
|
|
|
|
type CommitClosureEditor struct {
|
|
closure tree.MutableMap[CommitClosureKey, CommitClosureValue, commitClosureKeyOrdering]
|
|
}
|
|
|
|
type CommitClosureKey []byte
|
|
|
|
type CommitClosureIter tree.KvIter[CommitClosureKey, CommitClosureValue]
|
|
|
|
func NewCommitClosureKey(p pool.BuffPool, height uint64, addr hash.Hash) CommitClosureKey {
|
|
r := p.Get(8 + 20)
|
|
binary.LittleEndian.PutUint64(r, height)
|
|
copy(r[8:], addr[:])
|
|
return CommitClosureKey(r)
|
|
}
|
|
|
|
func (k CommitClosureKey) Height() uint64 {
|
|
return binary.LittleEndian.Uint64(k)
|
|
}
|
|
|
|
func (k CommitClosureKey) Addr() hash.Hash {
|
|
return hash.New(k[8:])
|
|
}
|
|
|
|
func (k CommitClosureKey) Less(other CommitClosureKey) bool {
|
|
return commitClosureKeyOrdering{}.Compare(k, other) < 0
|
|
}
|
|
|
|
var emptyCommitClosureValue CommitClosureValue = CommitClosureValue(make([]byte, 1))
|
|
|
|
func (wr CommitClosureEditor) Add(ctx context.Context, key CommitClosureKey) error {
|
|
return wr.closure.Put(ctx, key, emptyCommitClosureValue)
|
|
}
|
|
|
|
func (wr CommitClosureEditor) Delete(ctx context.Context, key CommitClosureKey) error {
|
|
return wr.closure.Delete(ctx, key)
|
|
}
|
|
|
|
func (wr CommitClosureEditor) Flush(ctx context.Context) (CommitClosure, error) {
|
|
sm := wr.closure.StaticMap
|
|
serializer := message.NewCommitClosureSerializer(sm.NodeStore.Pool())
|
|
fn := tree.ApplyMutations[CommitClosureKey, commitClosureKeyOrdering, message.CommitClosureSerializer]
|
|
|
|
root, err := fn(ctx, sm.NodeStore, sm.Root, commitClosureKeyOrdering{}, serializer, wr.closure.Mutations())
|
|
if err != nil {
|
|
return CommitClosure{}, err
|
|
}
|
|
|
|
return CommitClosure{
|
|
closure: tree.StaticMap[CommitClosureKey, CommitClosureValue, commitClosureKeyOrdering]{
|
|
Root: root,
|
|
NodeStore: sm.NodeStore,
|
|
Order: sm.Order,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func DiffCommitClosures(ctx context.Context, from, to CommitClosure, cb tree.DiffFn) error {
|
|
return tree.DiffOrderedTrees(ctx, from.closure, to.closure, cb)
|
|
}
|