Add key lookup support for tables in Go (#7644)

* Add support for key lookup for tables in Go

* Run clang format

* Run go fmt on tests

* Remove TODO in tests

* Update LookupByKey API

* Update LookupByKey API

* Don't use resolvePointer in expectEq

* Use generated getters instead of reading values directly from buffer

* Fix typo

Co-authored-by: Derek Bailey <derekbailey@google.com>
This commit is contained in:
Michael Le
2022-11-22 14:08:19 -08:00
committed by GitHub
parent 1cba8b2b49
commit 60975d6f7e
10 changed files with 365 additions and 7 deletions

View File

@@ -4,7 +4,6 @@ package Example
import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
MyGame__Example2 "MyGame/Example2"

View File

@@ -4,7 +4,6 @@ package Example
import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
)

View File

@@ -4,7 +4,6 @@ package Example
import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
MyGame__Example2 "MyGame/Example2"

View File

@@ -3,8 +3,8 @@
package Example
import (
"bytes"
"math"
flatbuffers "github.com/google/flatbuffers/go"
MyGame "MyGame"
@@ -568,6 +568,38 @@ func (rcv *Monster) Name() []byte {
return nil
}
func MonsterKeyCompare(o1, o2 flatbuffers.UOffsetT, buf []byte) bool {
obj1 := &Monster{}
obj2 := &Monster{}
obj1.Init(buf, flatbuffers.UOffsetT(len(buf)) - o1)
obj2.Init(buf, flatbuffers.UOffsetT(len(buf)) - o2)
return string(obj1.Name()) < string(obj2.Name())
}
func (rcv *Monster) LookupByKey(key string, vectorLocation flatbuffers.UOffsetT, buf []byte) bool {
span := flatbuffers.GetUOffsetT(buf[vectorLocation - 4:])
start := flatbuffers.UOffsetT(0)
for span != 0 {
middle := span / 2
tableOffset := flatbuffers.GetIndirectOffset(buf, vectorLocation+ 4 * (start + middle))
obj := &Monster{}
obj.Init(buf, tableOffset)
bKey := []byte(key)
comp := bytes.Compare(obj.Name(), bKey)
if comp > 0 {
span = middle
} else if comp < 0 {
middle += 1
start += middle
span -= middle
} else {
rcv.Init(buf, tableOffset)
return true
}
}
return false
}
func (rcv *Monster) Inventory(j int) byte {
o := flatbuffers.UOffsetT(rcv._tab.Offset(14))
if o != 0 {
@@ -685,6 +717,15 @@ func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
return false
}
func (rcv *Monster) TestarrayoftablesByKey(obj *Monster, key string) bool{
o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
if o != 0 {
x := rcv._tab.Vector(o)
return obj.LookupByKey(key, x, rcv._tab.Bytes)
}
return false
}
func (rcv *Monster) TestarrayoftablesLength() int {
o := flatbuffers.UOffsetT(rcv._tab.Offset(26))
if o != 0 {
@@ -1091,6 +1132,15 @@ func (rcv *Monster) VectorOfReferrables(obj *Referrable, j int) bool {
return false
}
func (rcv *Monster) VectorOfReferrablesByKey(obj *Referrable, key uint64) bool{
o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
if o != 0 {
x := rcv._tab.Vector(o)
return obj.LookupByKey(key, x, rcv._tab.Bytes)
}
return false
}
func (rcv *Monster) VectorOfReferrablesLength() int {
o := flatbuffers.UOffsetT(rcv._tab.Offset(74))
if o != 0 {
@@ -1149,6 +1199,15 @@ func (rcv *Monster) VectorOfStrongReferrables(obj *Referrable, j int) bool {
return false
}
func (rcv *Monster) VectorOfStrongReferrablesByKey(obj *Referrable, key uint64) bool{
o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
if o != 0 {
x := rcv._tab.Vector(o)
return obj.LookupByKey(key, x, rcv._tab.Bytes)
}
return false
}
func (rcv *Monster) VectorOfStrongReferrablesLength() int {
o := flatbuffers.UOffsetT(rcv._tab.Offset(80))
if o != 0 {
@@ -1367,6 +1426,15 @@ func (rcv *Monster) ScalarKeySortedTables(obj *Stat, j int) bool {
return false
}
func (rcv *Monster) ScalarKeySortedTablesByKey(obj *Stat, key uint16) bool{
o := flatbuffers.UOffsetT(rcv._tab.Offset(104))
if o != 0 {
x := rcv._tab.Vector(o)
return obj.LookupByKey(key, x, rcv._tab.Bytes)
}
return false
}
func (rcv *Monster) ScalarKeySortedTablesLength() int {
o := flatbuffers.UOffsetT(rcv._tab.Offset(104))
if o != 0 {

View File

@@ -67,6 +67,43 @@ func (rcv *Referrable) MutateId(n uint64) bool {
return rcv._tab.MutateUint64Slot(4, n)
}
func ReferrableKeyCompare(o1, o2 flatbuffers.UOffsetT, buf []byte) bool {
obj1 := &Referrable{}
obj2 := &Referrable{}
obj1.Init(buf, flatbuffers.UOffsetT(len(buf)) - o1)
obj2.Init(buf, flatbuffers.UOffsetT(len(buf)) - o2)
return obj1.Id() < obj2.Id()
}
func (rcv *Referrable) LookupByKey(key uint64, vectorLocation flatbuffers.UOffsetT, buf []byte) bool {
span := flatbuffers.GetUOffsetT(buf[vectorLocation - 4:])
start := flatbuffers.UOffsetT(0)
for span != 0 {
middle := span / 2
tableOffset := flatbuffers.GetIndirectOffset(buf, vectorLocation+ 4 * (start + middle))
obj := &Referrable{}
obj.Init(buf, tableOffset)
val := obj.Id()
comp := 0
if val > key {
comp = 1
} else if val < key {
comp = -1
}
if comp > 0 {
span = middle
} else if comp < 0 {
middle += 1
start += middle
span -= middle
} else {
rcv.Init(buf, tableOffset)
return true
}
}
return false
}
func ReferrableStart(builder *flatbuffers.Builder) {
builder.StartObject(1)
}

View File

@@ -94,6 +94,43 @@ func (rcv *Stat) MutateCount(n uint16) bool {
return rcv._tab.MutateUint16Slot(8, n)
}
func StatKeyCompare(o1, o2 flatbuffers.UOffsetT, buf []byte) bool {
obj1 := &Stat{}
obj2 := &Stat{}
obj1.Init(buf, flatbuffers.UOffsetT(len(buf)) - o1)
obj2.Init(buf, flatbuffers.UOffsetT(len(buf)) - o2)
return obj1.Count() < obj2.Count()
}
func (rcv *Stat) LookupByKey(key uint16, vectorLocation flatbuffers.UOffsetT, buf []byte) bool {
span := flatbuffers.GetUOffsetT(buf[vectorLocation - 4:])
start := flatbuffers.UOffsetT(0)
for span != 0 {
middle := span / 2
tableOffset := flatbuffers.GetIndirectOffset(buf, vectorLocation+ 4 * (start + middle))
obj := &Stat{}
obj.Init(buf, tableOffset)
val := obj.Count()
comp := 0
if val > key {
comp = 1
} else if val < key {
comp = -1
}
if comp > 0 {
span = middle
} else if comp < 0 {
middle += 1
start += middle
span -= middle
} else {
rcv.Init(buf, tableOffset)
return true
}
}
return false
}
func StatStart(builder *flatbuffers.Builder) {
builder.StartObject(3)
}