mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-15 00:50:22 -06:00
Merge pull request #3313 from dolthub/andy/refactor-prolly-message
[no-release-notes] Refactored flatbuffers schema for prolly tree nodes
This commit is contained in:
@@ -22,58 +22,58 @@ import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type TupleFormat byte
|
||||
type ItemType byte
|
||||
|
||||
const (
|
||||
TupleFormatUnknown TupleFormat = 0
|
||||
TupleFormatV1 TupleFormat = 1
|
||||
ItemTypeUnknown ItemType = 0
|
||||
ItemTypeTupleFormatAlpha ItemType = 1
|
||||
)
|
||||
|
||||
var EnumNamesTupleFormat = map[TupleFormat]string{
|
||||
TupleFormatUnknown: "Unknown",
|
||||
TupleFormatV1: "V1",
|
||||
var EnumNamesItemType = map[ItemType]string{
|
||||
ItemTypeUnknown: "Unknown",
|
||||
ItemTypeTupleFormatAlpha: "TupleFormatAlpha",
|
||||
}
|
||||
|
||||
var EnumValuesTupleFormat = map[string]TupleFormat{
|
||||
"Unknown": TupleFormatUnknown,
|
||||
"V1": TupleFormatV1,
|
||||
var EnumValuesItemType = map[string]ItemType{
|
||||
"Unknown": ItemTypeUnknown,
|
||||
"TupleFormatAlpha": ItemTypeTupleFormatAlpha,
|
||||
}
|
||||
|
||||
func (v TupleFormat) String() string {
|
||||
if s, ok := EnumNamesTupleFormat[v]; ok {
|
||||
func (v ItemType) String() string {
|
||||
if s, ok := EnumNamesItemType[v]; ok {
|
||||
return s
|
||||
}
|
||||
return "TupleFormat(" + strconv.FormatInt(int64(v), 10) + ")"
|
||||
return "ItemType(" + strconv.FormatInt(int64(v), 10) + ")"
|
||||
}
|
||||
|
||||
type TupleMap struct {
|
||||
type ProllyTreeNode struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsTupleMap(buf []byte, offset flatbuffers.UOffsetT) *TupleMap {
|
||||
func GetRootAsProllyTreeNode(buf []byte, offset flatbuffers.UOffsetT) *ProllyTreeNode {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &TupleMap{}
|
||||
x := &ProllyTreeNode{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsTupleMap(buf []byte, offset flatbuffers.UOffsetT) *TupleMap {
|
||||
func GetSizePrefixedRootAsProllyTreeNode(buf []byte, offset flatbuffers.UOffsetT) *ProllyTreeNode {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &TupleMap{}
|
||||
x := &ProllyTreeNode{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
func (rcv *ProllyTreeNode) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) Table() flatbuffers.Table {
|
||||
func (rcv *ProllyTreeNode) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyTuples(j int) byte {
|
||||
func (rcv *ProllyTreeNode) KeyItems(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
@@ -82,7 +82,7 @@ func (rcv *TupleMap) KeyTuples(j int) byte {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyTuplesLength() int {
|
||||
func (rcv *ProllyTreeNode) KeyItemsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
@@ -90,7 +90,7 @@ func (rcv *TupleMap) KeyTuplesLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyTuplesBytes() []byte {
|
||||
func (rcv *ProllyTreeNode) KeyItemsBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
@@ -98,7 +98,7 @@ func (rcv *TupleMap) KeyTuplesBytes() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateKeyTuples(j int, n byte) bool {
|
||||
func (rcv *ProllyTreeNode) MutateKeyItems(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
@@ -107,7 +107,7 @@ func (rcv *TupleMap) MutateKeyTuples(j int, n byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyOffsets(j int) uint16 {
|
||||
func (rcv *ProllyTreeNode) KeyOffsets(j int) uint16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
@@ -116,7 +116,7 @@ func (rcv *TupleMap) KeyOffsets(j int) uint16 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyOffsetsLength() int {
|
||||
func (rcv *ProllyTreeNode) KeyOffsetsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
@@ -124,7 +124,7 @@ func (rcv *TupleMap) KeyOffsetsLength() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateKeyOffsets(j int, n uint16) bool {
|
||||
func (rcv *ProllyTreeNode) MutateKeyOffsets(j int, n uint16) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
@@ -133,8 +133,20 @@ func (rcv *TupleMap) MutateKeyOffsets(j int, n uint16) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueTuples(j int) byte {
|
||||
func (rcv *ProllyTreeNode) KeyType() ItemType {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
if o != 0 {
|
||||
return ItemType(rcv._tab.GetByte(o + rcv._tab.Pos))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) MutateKeyType(n ItemType) bool {
|
||||
return rcv._tab.MutateByteSlot(8, byte(n))
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) ValueItems(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
@@ -142,24 +154,24 @@ func (rcv *TupleMap) ValueTuples(j int) byte {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueTuplesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
func (rcv *ProllyTreeNode) ValueItemsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueTuplesBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
func (rcv *ProllyTreeNode) ValueItemsBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateValueTuples(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(8))
|
||||
func (rcv *ProllyTreeNode) MutateValueItems(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
@@ -167,8 +179,8 @@ func (rcv *TupleMap) MutateValueTuples(j int, n byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueOffsets(j int) uint16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
func (rcv *ProllyTreeNode) ValueOffsets(j int) uint16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetUint16(a + flatbuffers.UOffsetT(j*2))
|
||||
@@ -176,16 +188,16 @@ func (rcv *TupleMap) ValueOffsets(j int) uint16 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueOffsetsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
func (rcv *ProllyTreeNode) ValueOffsetsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateValueOffsets(j int, n uint16) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
|
||||
func (rcv *ProllyTreeNode) MutateValueOffsets(j int, n uint16) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateUint16(a+flatbuffers.UOffsetT(j*2), n)
|
||||
@@ -193,174 +205,194 @@ func (rcv *TupleMap) MutateValueOffsets(j int, n uint16) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefArray(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
func (rcv *ProllyTreeNode) ValueType() ItemType {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
return ItemType(rcv._tab.GetByte(o + rcv._tab.Pos))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefArrayLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
func (rcv *ProllyTreeNode) MutateValueType(n ItemType) bool {
|
||||
return rcv._tab.MutateByteSlot(14, byte(n))
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefArrayBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateRefArray(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(12))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefCardinalities(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefCardinalitiesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) RefCardinalitiesBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateRefCardinalities(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) KeyFormat() TupleFormat {
|
||||
func (rcv *ProllyTreeNode) ValueAddressOffsets(j int) uint16 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
return TupleFormat(rcv._tab.GetByte(o + rcv._tab.Pos))
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetUint16(a + flatbuffers.UOffsetT(j*2))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateKeyFormat(n TupleFormat) bool {
|
||||
return rcv._tab.MutateByteSlot(16, byte(n))
|
||||
func (rcv *ProllyTreeNode) ValueAddressOffsetsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) ValueFormat() TupleFormat {
|
||||
func (rcv *ProllyTreeNode) MutateValueAddressOffsets(j int, n uint16) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateUint16(a+flatbuffers.UOffsetT(j*2), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) AddressArray(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return TupleFormat(rcv._tab.GetByte(o + rcv._tab.Pos))
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateValueFormat(n TupleFormat) bool {
|
||||
return rcv._tab.MutateByteSlot(18, byte(n))
|
||||
func (rcv *ProllyTreeNode) AddressArrayLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) TreeCount() uint64 {
|
||||
func (rcv *ProllyTreeNode) AddressArrayBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) MutateAddressArray(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) SubtreeCounts(j int) byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1))
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) SubtreeCountsLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) SubtreeCountsBytes() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
return rcv._tab.ByteVector(o + rcv._tab.Pos)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) MutateSubtreeCounts(j int, n byte) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(20))
|
||||
if o != 0 {
|
||||
a := rcv._tab.Vector(o)
|
||||
return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *ProllyTreeNode) TreeCount() uint64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetUint64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateTreeCount(n uint64) bool {
|
||||
return rcv._tab.MutateUint64Slot(20, n)
|
||||
func (rcv *ProllyTreeNode) MutateTreeCount(n uint64) bool {
|
||||
return rcv._tab.MutateUint64Slot(22, n)
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) TreeLevel() byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(22))
|
||||
func (rcv *ProllyTreeNode) TreeLevel() byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(24))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetByte(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *TupleMap) MutateTreeLevel(n byte) bool {
|
||||
return rcv._tab.MutateByteSlot(22, n)
|
||||
func (rcv *ProllyTreeNode) MutateTreeLevel(n byte) bool {
|
||||
return rcv._tab.MutateByteSlot(24, n)
|
||||
}
|
||||
|
||||
func TupleMapStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(10)
|
||||
func ProllyTreeNodeStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(11)
|
||||
}
|
||||
func TupleMapAddKeyTuples(builder *flatbuffers.Builder, keyTuples flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(keyTuples), 0)
|
||||
func ProllyTreeNodeAddKeyItems(builder *flatbuffers.Builder, keyItems flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(keyItems), 0)
|
||||
}
|
||||
func TupleMapStartKeyTuplesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeStartKeyItemsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func TupleMapAddKeyOffsets(builder *flatbuffers.Builder, keyOffsets flatbuffers.UOffsetT) {
|
||||
func ProllyTreeNodeAddKeyOffsets(builder *flatbuffers.Builder, keyOffsets flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(keyOffsets), 0)
|
||||
}
|
||||
func TupleMapStartKeyOffsetsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeStartKeyOffsetsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(2, numElems, 2)
|
||||
}
|
||||
func TupleMapAddValueTuples(builder *flatbuffers.Builder, valueTuples flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(valueTuples), 0)
|
||||
func ProllyTreeNodeAddKeyType(builder *flatbuffers.Builder, keyType ItemType) {
|
||||
builder.PrependByteSlot(2, byte(keyType), 0)
|
||||
}
|
||||
func TupleMapStartValueTuplesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeAddValueItems(builder *flatbuffers.Builder, valueItems flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(valueItems), 0)
|
||||
}
|
||||
func ProllyTreeNodeStartValueItemsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func TupleMapAddValueOffsets(builder *flatbuffers.Builder, valueOffsets flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(valueOffsets), 0)
|
||||
func ProllyTreeNodeAddValueOffsets(builder *flatbuffers.Builder, valueOffsets flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(valueOffsets), 0)
|
||||
}
|
||||
func TupleMapStartValueOffsetsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeStartValueOffsetsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(2, numElems, 2)
|
||||
}
|
||||
func TupleMapAddRefArray(builder *flatbuffers.Builder, refArray flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(4, flatbuffers.UOffsetT(refArray), 0)
|
||||
func ProllyTreeNodeAddValueType(builder *flatbuffers.Builder, valueType ItemType) {
|
||||
builder.PrependByteSlot(5, byte(valueType), 0)
|
||||
}
|
||||
func TupleMapStartRefArrayVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeAddValueAddressOffsets(builder *flatbuffers.Builder, valueAddressOffsets flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(6, flatbuffers.UOffsetT(valueAddressOffsets), 0)
|
||||
}
|
||||
func ProllyTreeNodeStartValueAddressOffsetsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(2, numElems, 2)
|
||||
}
|
||||
func ProllyTreeNodeAddAddressArray(builder *flatbuffers.Builder, addressArray flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(7, flatbuffers.UOffsetT(addressArray), 0)
|
||||
}
|
||||
func ProllyTreeNodeStartAddressArrayVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func TupleMapAddRefCardinalities(builder *flatbuffers.Builder, refCardinalities flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(refCardinalities), 0)
|
||||
func ProllyTreeNodeAddSubtreeCounts(builder *flatbuffers.Builder, subtreeCounts flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(subtreeCounts), 0)
|
||||
}
|
||||
func TupleMapStartRefCardinalitiesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeStartSubtreeCountsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(1, numElems, 1)
|
||||
}
|
||||
func TupleMapAddKeyFormat(builder *flatbuffers.Builder, keyFormat TupleFormat) {
|
||||
builder.PrependByteSlot(6, byte(keyFormat), 0)
|
||||
func ProllyTreeNodeAddTreeCount(builder *flatbuffers.Builder, treeCount uint64) {
|
||||
builder.PrependUint64Slot(9, treeCount, 0)
|
||||
}
|
||||
func TupleMapAddValueFormat(builder *flatbuffers.Builder, valueFormat TupleFormat) {
|
||||
builder.PrependByteSlot(7, byte(valueFormat), 0)
|
||||
func ProllyTreeNodeAddTreeLevel(builder *flatbuffers.Builder, treeLevel byte) {
|
||||
builder.PrependByteSlot(10, treeLevel, 0)
|
||||
}
|
||||
func TupleMapAddTreeCount(builder *flatbuffers.Builder, treeCount uint64) {
|
||||
builder.PrependUint64Slot(8, treeCount, 0)
|
||||
}
|
||||
func TupleMapAddTreeLevel(builder *flatbuffers.Builder, treeLevel byte) {
|
||||
builder.PrependByteSlot(9, treeLevel, 0)
|
||||
}
|
||||
func TupleMapEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
func ProllyTreeNodeEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,282 +0,0 @@
|
||||
// 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 serialbench
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
fb "github.com/google/flatbuffers/go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dolthub/dolt/go/gen/fb/serial"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
)
|
||||
|
||||
var (
|
||||
SmallLeafNodeHash = hash.Hash{
|
||||
0x5, 0xc3, 0x46, 0x4, 0x69,
|
||||
0xcd, 0x2b, 0xdf, 0xb5, 0xea,
|
||||
0x22, 0xb4, 0x86, 0xc2, 0x74,
|
||||
0x9b, 0x7a, 0x36, 0x2a, 0xd9,
|
||||
}
|
||||
LargeLeafNodeHash = hash.Hash{
|
||||
0xbb, 0x8e, 0x34, 0x44, 0x5f,
|
||||
0xdd, 0x63, 0x3c, 0x8c, 0x9,
|
||||
0xc9, 0x62, 0x54, 0x19, 0xb9,
|
||||
0x9d, 0x4c, 0xdf, 0x10, 0x76,
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
SmallLeafNodeSz = 232
|
||||
SmallKeyTuplesSz = 40
|
||||
SmallValueTuplesSz = 70
|
||||
SmallKeyOffsetsSz = 18
|
||||
SmallValueOffsetsSz = 18
|
||||
|
||||
LargeLeafNodeSz = 4080
|
||||
LargeLeafNodeCount = 200
|
||||
LargeKeyTuplesSz = 800
|
||||
LargeValueTuplesSz = 2400
|
||||
LargeKeyOffsetsSz = 398
|
||||
LargeValueOffsetsSz = 398
|
||||
)
|
||||
|
||||
func TestSerialFormat(t *testing.T) {
|
||||
t.Run("small leaf node", func(t *testing.T) {
|
||||
keys, values := smallTestTuples()
|
||||
buf := makeLeafNode(t, keys, values)
|
||||
assert.Equal(t, SmallLeafNodeSz, len(buf))
|
||||
assert.Equal(t, SmallLeafNodeHash, hash.Of(buf))
|
||||
|
||||
m := serial.GetRootAsTupleMap(buf, 0)
|
||||
validateLeafNode(t, m, keys, values)
|
||||
assert.Equal(t, SmallKeyTuplesSz, len(m.KeyTuplesBytes()))
|
||||
assert.Equal(t, SmallValueTuplesSz, len(m.ValueTuplesBytes()))
|
||||
assert.Equal(t, SmallKeyOffsetsSz, m.KeyOffsetsLength()*2)
|
||||
assert.Equal(t, SmallValueOffsetsSz, m.ValueOffsetsLength()*2)
|
||||
})
|
||||
t.Run("large leaf node", func(t *testing.T) {
|
||||
keys, values := largeTestTuples()
|
||||
buf := makeLeafNode(t, keys, values)
|
||||
assert.Equal(t, LargeLeafNodeSz, len(buf))
|
||||
assert.Equal(t, LargeLeafNodeHash, hash.Of(buf))
|
||||
|
||||
m := serial.GetRootAsTupleMap(buf, 0)
|
||||
validateLeafNode(t, m, keys, values)
|
||||
assert.Equal(t, LargeKeyTuplesSz, len(m.KeyTuplesBytes()))
|
||||
assert.Equal(t, LargeValueTuplesSz, len(m.ValueTuplesBytes()))
|
||||
assert.Equal(t, LargeKeyOffsetsSz, m.KeyOffsetsLength()*2)
|
||||
assert.Equal(t, LargeValueOffsetsSz, m.ValueOffsetsLength()*2)
|
||||
})
|
||||
t.Run("test data sanity check", func(t *testing.T) {
|
||||
keys, values := smallTestTuples()
|
||||
require.Equal(t, SmallKeyTuplesSz, byteSize(keys))
|
||||
require.Equal(t, SmallValueTuplesSz, byteSize(values))
|
||||
require.Equal(t, 10, len(keys))
|
||||
require.Equal(t, 10, len(values))
|
||||
|
||||
keys, values = largeTestTuples()
|
||||
require.Equal(t, LargeKeyTuplesSz, byteSize(keys))
|
||||
require.Equal(t, LargeValueTuplesSz, byteSize(values))
|
||||
require.Equal(t, LargeLeafNodeCount, len(keys))
|
||||
require.Equal(t, LargeLeafNodeCount, len(values))
|
||||
})
|
||||
}
|
||||
|
||||
func makeLeafNode(t *testing.T, keys, values [][]byte) []byte {
|
||||
b := fb.NewBuilder((byteSize(keys) + byteSize(values)) * 2)
|
||||
start := int(b.Offset())
|
||||
assert.Equal(t, 0, start)
|
||||
|
||||
keySz := byteSize(keys)
|
||||
serial.TupleMapStartKeyTuplesVector(b, keySz)
|
||||
start = int(b.Offset())
|
||||
keyTuples := serializeTuples(t, b, keys)
|
||||
assert.Equal(t, keyTuples, b.Offset())
|
||||
assert.Equal(t, start+keySz+4, int(b.Offset()))
|
||||
|
||||
start = int(b.Offset())
|
||||
// zeroth offset ommitted
|
||||
ol := len(keys) - 1
|
||||
serial.TupleMapStartKeyOffsetsVector(b, ol)
|
||||
keyOffsets := serializeOffsets(t, b, keys)
|
||||
assert.Equal(t, keyOffsets, b.Offset())
|
||||
offsetsSz := (2 * (len(keys) - 1)) + 4
|
||||
assert.Equal(t, padToMultiple(start+offsetsSz, 4), int(b.Offset()))
|
||||
|
||||
valSz := byteSize(values)
|
||||
serial.TupleMapStartValueOffsetsVector(b, valSz)
|
||||
start = int(b.Offset())
|
||||
valTuples := serializeTuples(t, b, values)
|
||||
assert.Equal(t, valTuples, b.Offset())
|
||||
assert.Equal(t, start+valSz+4, int(b.Offset()))
|
||||
|
||||
// zeroth offset ommitted
|
||||
serial.TupleMapStartValueOffsetsVector(b, len(values)-1)
|
||||
start = int(b.Offset())
|
||||
valOffsets := serializeOffsets(t, b, values)
|
||||
assert.Equal(t, valOffsets, b.Offset())
|
||||
offsetsSz = (2 * (len(values) - 1)) + 4
|
||||
assert.Equal(t, padToMultiple(start+offsetsSz, 4), int(b.Offset()))
|
||||
|
||||
start = int(b.Offset())
|
||||
serial.TupleMapStart(b)
|
||||
assert.Equal(t, start, int(b.Offset()))
|
||||
|
||||
serial.TupleMapAddTreeCount(b, uint64(len(keys)))
|
||||
// write map elements in descending order by size
|
||||
start = padToMultiple(start, 8)
|
||||
assert.Equal(t, start+8, int(b.Offset()))
|
||||
|
||||
// each vector reference is a uint32
|
||||
serial.TupleMapAddKeyTuples(b, keyTuples)
|
||||
assert.Equal(t, start+12, int(b.Offset()))
|
||||
serial.TupleMapAddKeyOffsets(b, keyOffsets)
|
||||
assert.Equal(t, start+16, int(b.Offset()))
|
||||
serial.TupleMapAddValueTuples(b, valTuples)
|
||||
assert.Equal(t, start+20, int(b.Offset()))
|
||||
serial.TupleMapAddValueOffsets(b, valOffsets)
|
||||
assert.Equal(t, start+24, int(b.Offset()))
|
||||
|
||||
serial.TupleMapAddKeyFormat(b, serial.TupleFormatV1)
|
||||
assert.Equal(t, start+25, int(b.Offset()))
|
||||
serial.TupleMapAddValueFormat(b, serial.TupleFormatV1)
|
||||
assert.Equal(t, start+26, int(b.Offset()))
|
||||
|
||||
// default value of 0 ommitted
|
||||
serial.TupleMapAddTreeLevel(b, 0)
|
||||
assert.Equal(t, start+26, int(b.Offset()))
|
||||
|
||||
mapEnd := serial.TupleMapEnd(b)
|
||||
assert.Equal(t, start+54, int(b.Offset()))
|
||||
b.Finish(mapEnd)
|
||||
assert.Equal(t, start+64, int(b.Offset()))
|
||||
|
||||
return b.FinishedBytes()
|
||||
}
|
||||
|
||||
func validateLeafNode(t *testing.T, m *serial.TupleMap, keys, values [][]byte) {
|
||||
require.Equal(t, len(keys), len(values))
|
||||
|
||||
assert.Equal(t, len(keys)-1, m.KeyOffsetsLength())
|
||||
kb := make([]uint16, m.KeyOffsetsLength()+2)
|
||||
vb := make([]uint16, m.ValueOffsetsLength()+2)
|
||||
ktb := m.KeyTuplesBytes()
|
||||
vtb := m.ValueTuplesBytes()
|
||||
|
||||
kb[0], vb[0] = 0, 0
|
||||
kb[len(kb)-1], vb[len(vb)-1] = uint16(len(ktb)), uint16(len(vtb))
|
||||
for i := 0; i < m.KeyOffsetsLength(); i++ {
|
||||
kb[i+1] = m.KeyOffsets(i)
|
||||
vb[i+1] = m.ValueOffsets(i)
|
||||
}
|
||||
|
||||
validateTuples(t, ktb, kb, keys)
|
||||
validateTuples(t, vtb, vb, values)
|
||||
|
||||
assert.Equal(t, serial.TupleFormatV1, m.KeyFormat())
|
||||
assert.Equal(t, serial.TupleFormatV1, m.ValueFormat())
|
||||
assert.Equal(t, len(keys), int(m.TreeCount()))
|
||||
assert.Equal(t, 0, int(m.TreeLevel()))
|
||||
}
|
||||
|
||||
func validateTuples(t *testing.T, buf []byte, bounds []uint16, tups [][]byte) {
|
||||
for i, exp := range tups {
|
||||
start, stop := bounds[i], bounds[i+1]
|
||||
act := buf[start:stop]
|
||||
assert.Equal(t, act, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func serializeTuples(t *testing.T, b *fb.Builder, tt [][]byte) fb.UOffsetT {
|
||||
for i := len(tt) - 1; i >= 0; i-- {
|
||||
for j := len(tt[i]) - 1; j >= 0; j-- {
|
||||
b.PrependByte(tt[i][j])
|
||||
}
|
||||
}
|
||||
return b.EndVector(byteSize(tt))
|
||||
}
|
||||
|
||||
func serializeOffsets(t *testing.T, b *fb.Builder, tt [][]byte) fb.UOffsetT {
|
||||
off := byteSize(tt)
|
||||
for i := len(tt) - 1; i > 0; i-- {
|
||||
off -= len(tt[i])
|
||||
b.PrependUint16(uint16(off))
|
||||
}
|
||||
// zeroth offset ommitted
|
||||
require.Equal(t, len(tt[0]), off)
|
||||
return b.EndVector(len(tt) - 1)
|
||||
}
|
||||
|
||||
func byteSize(tt [][]byte) (sz int) {
|
||||
for i := range tt {
|
||||
sz += len(tt[i])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func smallTestTuples() (keys, values [][]byte) {
|
||||
keys = [][]byte{
|
||||
[]byte("zero"),
|
||||
[]byte("one"),
|
||||
[]byte("two"),
|
||||
[]byte("three"),
|
||||
[]byte("four"),
|
||||
[]byte("five"),
|
||||
[]byte("six"),
|
||||
[]byte("seven"),
|
||||
[]byte("eight"),
|
||||
[]byte("nine"),
|
||||
}
|
||||
values = [][]byte{
|
||||
[]byte("ten"),
|
||||
[]byte("eleven"),
|
||||
[]byte("twelve"),
|
||||
[]byte("thirteen"),
|
||||
[]byte("fourteen"),
|
||||
[]byte("fifteen"),
|
||||
[]byte("sixteen"),
|
||||
[]byte("seventeen"),
|
||||
[]byte("eighteen"),
|
||||
[]byte("nineteen"),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func largeTestTuples() (keys, values [][]byte) {
|
||||
keys = make([][]byte, LargeLeafNodeCount)
|
||||
values = make([][]byte, LargeLeafNodeCount)
|
||||
for i := range keys {
|
||||
keys[i] = make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(keys[i], uint32(i))
|
||||
values[i] = make([]byte, 12)
|
||||
binary.LittleEndian.PutUint32(values[i][0:4], uint32(i))
|
||||
binary.LittleEndian.PutUint32(values[i][4:8], uint32(i*2))
|
||||
binary.LittleEndian.PutUint32(values[i][8:12], uint32(i*3))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func padToMultiple(i, k int) int {
|
||||
for {
|
||||
if i%k == 0 {
|
||||
return i
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
@@ -14,42 +14,41 @@
|
||||
|
||||
namespace serial;
|
||||
|
||||
enum TupleFormat : uint8 {
|
||||
enum ItemType : uint8 {
|
||||
Unknown,
|
||||
V1 = 1,
|
||||
TupleFormatAlpha = 1,
|
||||
}
|
||||
|
||||
table TupleMap {
|
||||
// array of map key tuples, ordered lexigraphically
|
||||
key_tuples:[ubyte] (required);
|
||||
// array of offets into |key_tuples|, zeroth offset omitted
|
||||
table ProllyTreeNode {
|
||||
// sorted array of key items
|
||||
key_items:[ubyte] (required);
|
||||
// items offets for |key_items|, zeroth offset omitted
|
||||
key_offsets:[uint16] (required);
|
||||
// item type for |key_items|
|
||||
key_type:ItemType;
|
||||
|
||||
// array of map values tuples, ordered by paired key
|
||||
// |value_tuples| is only present in leaf nodes
|
||||
value_tuples:[ubyte];
|
||||
// array of offets into |value_tuples|, zeroth offset omitted
|
||||
// |value_offsets| is only present in leaf nodes
|
||||
// array of values items, ordered by paired key
|
||||
value_items:[ubyte];
|
||||
// item offsets for |value_items|, zeroth offset omitted
|
||||
value_offsets:[uint16];
|
||||
// item type for |value_items|
|
||||
value_type:ItemType;
|
||||
// offsets for each address (if any) in |value_items|
|
||||
// (eg value tuples containing out-of-line BLOB addresses)
|
||||
value_address_offsets:[uint16];
|
||||
|
||||
|
||||
// array of chunk addresses
|
||||
// - subtree addresses for internal prolly tree nodes
|
||||
// - value addresses for AddressMap leaf nodes
|
||||
address_array:[ubyte];
|
||||
|
||||
|
||||
// array of ref hashes
|
||||
// - internal nodes: contains refs for
|
||||
// Prolly tree children
|
||||
// - leaf nodes: contains refs for heap values
|
||||
// iff table has ref'd types (eg TEXT)
|
||||
ref_array:[ubyte];
|
||||
// array of uvarint encoded subtree counts
|
||||
ref_cardinalities:[ubyte];
|
||||
|
||||
// tuple format for |key_tuples|
|
||||
key_format:TupleFormat;
|
||||
// tuple format for |value_tuples|
|
||||
value_format:TupleFormat;
|
||||
|
||||
// subtree member count
|
||||
subtree_counts:[ubyte];
|
||||
// total count of prolly tree
|
||||
tree_count:uint64;
|
||||
|
||||
// node tree level, 0 for leaf nodes
|
||||
// prolly tree level, 0 for leaf nodes
|
||||
tree_level:uint8;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/pool"
|
||||
"github.com/dolthub/dolt/go/store/prolly/tree"
|
||||
"github.com/dolthub/dolt/go/store/val"
|
||||
@@ -65,9 +66,25 @@ func TestMap(t *testing.T) {
|
||||
})
|
||||
|
||||
pm := prollyMap.(Map)
|
||||
t.Run("item exists in map", func(t *testing.T) {
|
||||
t.Run("tuple exists in map", func(t *testing.T) {
|
||||
testHas(t, pm, tuples)
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
t.Run("walk addresses smoke test", func(t *testing.T) {
|
||||
err := pm.WalkAddresses(ctx, func(_ context.Context, addr hash.Hash) error {
|
||||
assert.True(t, addr != hash.Hash{})
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
t.Run("walk nodes smoke test", func(t *testing.T) {
|
||||
err := pm.WalkNodes(ctx, func(_ context.Context, nd tree.Node) error {
|
||||
assert.True(t, nd.Count() > 1)
|
||||
return nil
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ func (tc *chunker) Done(ctx context.Context) (Node, error) {
|
||||
return child, nil
|
||||
}
|
||||
|
||||
mt = child.getRef(0)
|
||||
mt = child.getChildAddress(0)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,10 @@ import (
|
||||
)
|
||||
|
||||
var goldenHash = hash.Hash{
|
||||
0x14, 0xc8, 0x30, 0xe0, 0xc7,
|
||||
0x84, 0xe8, 0xc8, 0x78, 0x45,
|
||||
0xa5, 0x4f, 0x94, 0xe7, 0x52,
|
||||
0x7b, 0x17, 0x21, 0x3f, 0x59,
|
||||
0x9c, 0xf1, 0x55, 0xce, 0x1c,
|
||||
0xfc, 0x6e, 0xd5, 0x4b, 0xa9,
|
||||
0xcc, 0x7e, 0x15, 0x93, 0xa8,
|
||||
0x29, 0x47, 0x16, 0xa8, 0x89,
|
||||
}
|
||||
|
||||
func TestContentAddress(t *testing.T) {
|
||||
|
||||
@@ -30,34 +30,29 @@ import (
|
||||
|
||||
const (
|
||||
maxVectorOffset = uint64(math.MaxUint16)
|
||||
refSize = hash.ByteLen
|
||||
addrSz = hash.ByteLen
|
||||
|
||||
// These constants are mirrored from serial.TupleMap.KeyOffsetsLength()
|
||||
// and serial.TupleMap.ValueOffsetsLength() respectively.
|
||||
// These constants are mirrored from serial.ProllyTreeNode.KeyOffsetsLength()
|
||||
// and serial.ProllyTreeNode.ValueOffsetsLength() respectively.
|
||||
// They are only as stable as the flatbuffers schemas that define them.
|
||||
keyOffsetsVOffset = 6
|
||||
valueOffsetsVOffset = 10
|
||||
valueOffsetsVOffset = 12
|
||||
)
|
||||
|
||||
type Item []byte
|
||||
|
||||
type Node struct {
|
||||
// keys and values contain sub-slices of |msg|,
|
||||
// allowing faster lookups by avoiding the vtable
|
||||
keys, values val.SlicedBuffer
|
||||
buf serial.TupleMap
|
||||
msg serial.ProllyTreeNode
|
||||
count uint16
|
||||
}
|
||||
|
||||
type AddressCb func(ctx context.Context, addr hash.Hash) error
|
||||
|
||||
func WalkAddresses(ctx context.Context, nd Node, ns NodeStore, cb AddressCb) error {
|
||||
if nd.IsLeaf() {
|
||||
// todo(andy): ref'd values
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < int(nd.count); i++ {
|
||||
addr := nd.getRef(i)
|
||||
|
||||
return walkAddresses(ctx, nd, func(ctx context.Context, addr hash.Hash) error {
|
||||
if err := cb(ctx, addr); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -67,11 +62,8 @@ func WalkAddresses(ctx context.Context, nd Node, ns NodeStore, cb AddressCb) err
|
||||
return err
|
||||
}
|
||||
|
||||
if err := WalkAddresses(ctx, child, ns, cb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return WalkAddresses(ctx, child, ns, cb)
|
||||
})
|
||||
}
|
||||
|
||||
type NodeCb func(ctx context.Context, nd Node) error
|
||||
@@ -80,39 +72,32 @@ func WalkNodes(ctx context.Context, nd Node, ns NodeStore, cb NodeCb) error {
|
||||
if err := cb(ctx, nd); err != nil {
|
||||
return err
|
||||
}
|
||||
if nd.IsLeaf() {
|
||||
// todo(andy): walk ref'd values?
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < int(nd.count); i++ {
|
||||
child, err := ns.Read(ctx, nd.getRef(i))
|
||||
return walkAddresses(ctx, nd, func(ctx context.Context, addr hash.Hash) error {
|
||||
child, err := ns.Read(ctx, addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := WalkNodes(ctx, child, ns, cb); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return WalkNodes(ctx, child, ns, cb)
|
||||
})
|
||||
}
|
||||
|
||||
func MapNodeFromBytes(bb []byte) Node {
|
||||
buf := serial.GetRootAsTupleMap(bb, 0)
|
||||
return mapNodeFromFlatbuffer(*buf)
|
||||
func MapNodeFromBytes(buf []byte) Node {
|
||||
msg := serial.GetRootAsProllyTreeNode(buf, 0)
|
||||
return mapNodeFromFlatbuffer(*msg)
|
||||
}
|
||||
|
||||
func mapNodeFromFlatbuffer(buf serial.TupleMap) Node {
|
||||
func mapNodeFromFlatbuffer(msg serial.ProllyTreeNode) Node {
|
||||
keys := val.SlicedBuffer{
|
||||
Buf: buf.KeyTuplesBytes(),
|
||||
Offs: getKeyOffsetsVector(buf),
|
||||
Buf: msg.KeyItemsBytes(),
|
||||
Offs: getKeyOffsetsVector(msg),
|
||||
}
|
||||
values := val.SlicedBuffer{
|
||||
Buf: buf.ValueTuplesBytes(),
|
||||
Offs: getValueOffsetsVector(buf),
|
||||
Buf: msg.ValueItemsBytes(),
|
||||
Offs: getValueOffsetsVector(msg),
|
||||
}
|
||||
|
||||
count := buf.KeyOffsetsLength() + 1
|
||||
count := msg.KeyOffsetsLength() + 1
|
||||
if len(keys.Buf) == 0 {
|
||||
count = 0
|
||||
}
|
||||
@@ -121,7 +106,7 @@ func mapNodeFromFlatbuffer(buf serial.TupleMap) Node {
|
||||
keys: keys,
|
||||
values: values,
|
||||
count: uint16(count),
|
||||
buf: buf,
|
||||
msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +119,7 @@ func (nd Node) Count() int {
|
||||
}
|
||||
|
||||
func (nd Node) TreeCount() int {
|
||||
return int(nd.buf.TreeCount())
|
||||
return int(nd.msg.TreeCount())
|
||||
}
|
||||
|
||||
func (nd Node) Size() int {
|
||||
@@ -143,12 +128,12 @@ func (nd Node) Size() int {
|
||||
|
||||
// Level returns the tree Level for this node
|
||||
func (nd Node) Level() int {
|
||||
return int(nd.buf.TreeLevel())
|
||||
return int(nd.msg.TreeLevel())
|
||||
}
|
||||
|
||||
// IsLeaf returns whether this node is a leaf
|
||||
func (nd Node) IsLeaf() bool {
|
||||
return int(nd.buf.TreeLevel()) == 0
|
||||
return int(nd.msg.TreeLevel()) == 0
|
||||
}
|
||||
|
||||
// GetKey returns the |ith| key of this node
|
||||
@@ -161,21 +146,27 @@ func (nd Node) getValue(i int) Item {
|
||||
if nd.IsLeaf() {
|
||||
return nd.values.GetSlice(i)
|
||||
} else {
|
||||
r := nd.getRef(i)
|
||||
r := nd.getChildAddress(i)
|
||||
return r[:]
|
||||
}
|
||||
}
|
||||
|
||||
// getRef returns the |ith| ref in this node. Only Valid for internal nodes.
|
||||
func (nd Node) getRef(i int) hash.Hash {
|
||||
refs := nd.buf.RefArrayBytes()
|
||||
start, stop := i*refSize, (i+1)*refSize
|
||||
// getChildAddress returns the |ith| address in this node
|
||||
func (nd Node) getChildAddress(i int) hash.Hash {
|
||||
refs := nd.msg.AddressArrayBytes()
|
||||
start, stop := i*addrSz, (i+1)*addrSz
|
||||
return hash.New(refs[start:stop])
|
||||
}
|
||||
|
||||
// getValueAddress returns the |ith| value address in this node
|
||||
func (nd Node) getValueAddress(i int) hash.Hash {
|
||||
o := nd.msg.ValueAddressOffsets(i)
|
||||
return hash.New(nd.values.Buf[o : o+addrSz])
|
||||
}
|
||||
|
||||
func (nd Node) getSubtreeCounts() subtreeCounts {
|
||||
buf := nd.buf.RefCardinalitiesBytes()
|
||||
return readSubtreeCounts(int(nd.count), buf)
|
||||
arr := nd.msg.SubtreeCountsBytes()
|
||||
return readSubtreeCounts(int(nd.count), arr)
|
||||
}
|
||||
|
||||
func (nd Node) empty() bool {
|
||||
@@ -183,12 +174,32 @@ func (nd Node) empty() bool {
|
||||
}
|
||||
|
||||
func (nd Node) bytes() []byte {
|
||||
return nd.buf.Table().Bytes
|
||||
return nd.msg.Table().Bytes
|
||||
}
|
||||
|
||||
func getKeyOffsetsVector(buf serial.TupleMap) []byte {
|
||||
sz := buf.KeyOffsetsLength() * 2
|
||||
tab := buf.Table()
|
||||
func walkAddresses(ctx context.Context, nd Node, cb AddressCb) (err error) {
|
||||
arr := nd.msg.AddressArrayBytes()
|
||||
cnt := len(arr) / addrSz
|
||||
for i := 0; i < cnt; i++ {
|
||||
if err = cb(ctx, nd.getChildAddress(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
cnt2 := nd.msg.ValueAddressOffsetsLength()
|
||||
for i := 0; i < cnt2; i++ {
|
||||
if err = cb(ctx, nd.getValueAddress(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
assertFalse((cnt > 0) && (cnt2 > 0))
|
||||
return
|
||||
}
|
||||
|
||||
func getKeyOffsetsVector(msg serial.ProllyTreeNode) []byte {
|
||||
sz := msg.KeyOffsetsLength() * 2
|
||||
tab := msg.Table()
|
||||
vec := tab.Offset(keyOffsetsVOffset)
|
||||
start := int(tab.Vector(fb.UOffsetT(vec)))
|
||||
stop := start + sz
|
||||
@@ -196,9 +207,9 @@ func getKeyOffsetsVector(buf serial.TupleMap) []byte {
|
||||
return tab.Bytes[start:stop]
|
||||
}
|
||||
|
||||
func getValueOffsetsVector(buf serial.TupleMap) []byte {
|
||||
sz := buf.ValueOffsetsLength() * 2
|
||||
tab := buf.Table()
|
||||
func getValueOffsetsVector(msg serial.ProllyTreeNode) []byte {
|
||||
sz := msg.ValueOffsetsLength() * 2
|
||||
tab := msg.Table()
|
||||
vec := tab.Offset(valueOffsetsVOffset)
|
||||
start := int(tab.Vector(fb.UOffsetT(vec)))
|
||||
stop := start + sz
|
||||
@@ -238,7 +249,7 @@ func OutputProllyNode(w io.Writer, node Node) error {
|
||||
|
||||
w.Write([]byte(" }"))
|
||||
} else {
|
||||
ref := node.getRef(i)
|
||||
ref := node.getChildAddress(i)
|
||||
|
||||
w.Write([]byte(" ref: #"))
|
||||
w.Write([]byte(ref.String()))
|
||||
|
||||
@@ -110,13 +110,13 @@ func (nb *nodeBuilder) build(pool pool.BuffPool) (node Node) {
|
||||
|
||||
// serialize keys and offsets
|
||||
keyTups = writeItemBytes(b, nb.keys, keySz)
|
||||
serial.TupleMapStartKeyOffsetsVector(b, len(nb.keys)-1)
|
||||
serial.ProllyTreeNodeStartKeyOffsetsVector(b, len(nb.keys)-1)
|
||||
keyOffs = b.EndVector(writeItemOffsets(b, nb.keys, keySz))
|
||||
|
||||
if nb.level == 0 {
|
||||
// serialize value tuples for leaf nodes
|
||||
valTups = writeItemBytes(b, nb.values, valSz)
|
||||
serial.TupleMapStartValueOffsetsVector(b, len(nb.values)-1)
|
||||
serial.ProllyTreeNodeStartValueOffsetsVector(b, len(nb.values)-1)
|
||||
valOffs = b.EndVector(writeItemOffsets(b, nb.values, valSz))
|
||||
} else {
|
||||
// serialize child refs and subtree counts for internal nodes
|
||||
@@ -125,22 +125,22 @@ func (nb *nodeBuilder) build(pool pool.BuffPool) (node Node) {
|
||||
}
|
||||
|
||||
// populate the node's vtable
|
||||
serial.TupleMapStart(b)
|
||||
serial.TupleMapAddKeyTuples(b, keyTups)
|
||||
serial.TupleMapAddKeyOffsets(b, keyOffs)
|
||||
serial.ProllyTreeNodeStart(b)
|
||||
serial.ProllyTreeNodeAddKeyItems(b, keyTups)
|
||||
serial.ProllyTreeNodeAddKeyOffsets(b, keyOffs)
|
||||
if nb.level == 0 {
|
||||
serial.TupleMapAddValueTuples(b, valTups)
|
||||
serial.TupleMapAddValueOffsets(b, valOffs)
|
||||
serial.TupleMapAddTreeCount(b, uint64(len(nb.keys)))
|
||||
serial.ProllyTreeNodeAddValueItems(b, valTups)
|
||||
serial.ProllyTreeNodeAddValueOffsets(b, valOffs)
|
||||
serial.ProllyTreeNodeAddTreeCount(b, uint64(len(nb.keys)))
|
||||
} else {
|
||||
serial.TupleMapAddRefArray(b, refArr)
|
||||
serial.TupleMapAddRefCardinalities(b, cardArr)
|
||||
serial.TupleMapAddTreeCount(b, nb.subtrees.sum())
|
||||
serial.ProllyTreeNodeAddAddressArray(b, refArr)
|
||||
serial.ProllyTreeNodeAddSubtreeCounts(b, cardArr)
|
||||
serial.ProllyTreeNodeAddTreeCount(b, nb.subtrees.sum())
|
||||
}
|
||||
serial.TupleMapAddKeyFormat(b, serial.TupleFormatV1)
|
||||
serial.TupleMapAddValueFormat(b, serial.TupleFormatV1)
|
||||
serial.TupleMapAddTreeLevel(b, uint8(nb.level))
|
||||
b.Finish(serial.TupleMapEnd(b))
|
||||
serial.ProllyTreeNodeAddKeyType(b, serial.ItemTypeTupleFormatAlpha)
|
||||
serial.ProllyTreeNodeAddValueType(b, serial.ItemTypeTupleFormatAlpha)
|
||||
serial.ProllyTreeNodeAddTreeLevel(b, uint8(nb.level))
|
||||
b.Finish(serial.ProllyTreeNodeEnd(b))
|
||||
|
||||
buf := b.FinishedBytes()
|
||||
return MapNodeFromBytes(buf)
|
||||
|
||||
@@ -216,7 +216,7 @@ func (cur *Cursor) CurrentValue() Item {
|
||||
}
|
||||
|
||||
func (cur *Cursor) CurrentRef() hash.Hash {
|
||||
return cur.nd.getRef(cur.idx)
|
||||
return cur.nd.getChildAddress(cur.idx)
|
||||
}
|
||||
|
||||
func (cur *Cursor) currentSubtreeSize() uint64 {
|
||||
@@ -486,3 +486,9 @@ func assertTrue(b bool) {
|
||||
panic("assertion failed")
|
||||
}
|
||||
}
|
||||
|
||||
func assertFalse(b bool) {
|
||||
if b {
|
||||
panic("assertion failed")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func TestGetKeyValueOffsetsVectors(t *testing.T) {
|
||||
nd := newLeafNode(keys, values)
|
||||
|
||||
ko1, vo1 := offsetsFromSlicedBuffers(nd.keys, nd.values)
|
||||
ko2, vo2 := offsetsFromFlatbuffer(nd.buf)
|
||||
ko2, vo2 := offsetsFromFlatbuffer(nd.msg)
|
||||
|
||||
assert.Equal(t, len(ko1), len(ko2))
|
||||
assert.Equal(t, len(ko1), len(keys)-1)
|
||||
@@ -139,7 +139,7 @@ func sumTupleSize(items []val.Tuple) (sz uint64) {
|
||||
return
|
||||
}
|
||||
|
||||
func offsetsFromFlatbuffer(buf serial.TupleMap) (ko, vo []uint16) {
|
||||
func offsetsFromFlatbuffer(buf serial.ProllyTreeNode) (ko, vo []uint16) {
|
||||
ko = make([]uint16, buf.KeyOffsetsLength())
|
||||
for i := range ko {
|
||||
ko[i] = buf.KeyOffsets(i)
|
||||
|
||||
Reference in New Issue
Block a user