Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
flatbuffers
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
flatbuffers
Commits
8468ea1a
Commit
8468ea1a
authored
May 09, 2017
by
Wouter van Oortmerssen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed LookupByKey for Java & C#
Change-Id: I05c02223675dee241d1ae8cb466e5186444058c8 Tested: on Linux.
parent
0920d663
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
49 additions
and
33 deletions
+49
-33
JavaCsharpUsage.md
docs/source/JavaCsharpUsage.md
+9
-8
idl_gen_general.cpp
src/idl_gen_general.cpp
+26
-9
FlatBuffersExampleTests.cs
tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
+4
-4
JavaTest.java
tests/JavaTest.java
+3
-3
Monster.cs
tests/MyGame/Example/Monster.cs
+4
-5
Monster.java
tests/MyGame/Example/Monster.java
+3
-4
No files found.
docs/source/JavaCsharpUsage.md
View file @
8468ea1a
...
@@ -147,19 +147,20 @@ To use it:
...
@@ -147,19 +147,20 @@ To use it:
array.
array.
-
Instead of calling standard generated method,
-
Instead of calling standard generated method,
e.g.:
`Monster.createTestarrayoftablesVector`
,
e.g.:
`Monster.createTestarrayoftablesVector`
,
call
`Create
MySortedVectorOfTables
`
in C# or
call
`Create
SortedVectorOfMonster
`
in C# or
`createSortedVectorOfTables`
(from the
`FlatBufferBuilder`
object) in Java,
`createSortedVectorOfTables`
(from the
`FlatBufferBuilder`
object) in Java,
which will first sort all offsets such that the tables they refer to
which will first sort all offsets such that the tables they refer to
are sorted by the key field, then serialize it.
are sorted by the key field, then serialize it.
-
Now when you're accessing the FlatBuffer, you can use
`LookupByKey`
-
Now when you're accessing the FlatBuffer, you can use
to access elements of the vector, e.g.:
the
`ByKey`
accessor to access elements of the vector, e.g.:
`Monster.lookupByKey(tablesVectorOffset, "Frodo", dataBuffer)`
,
`monster.testarrayoftablesByKey("Frodo")`
in Java or
`monster.TestarrayoftablesByKey("Frodo")`
in C#,
which returns an object of the corresponding table type,
which returns an object of the corresponding table type,
or
`null`
if not found.
or
`null`
if not found.
`
LookupByKey`
performs a binary search, so should have a similar speed to
`
ByKey`
performs a binary search, so should have a similar
`Dictionary`
, though may be faster because of better caching.
`LookupByKey`
speed to
`Dictionary`
, though may be faster because of better caching.
only works if the vector has been sorted, it will likely not find elements
`ByKey`
only works if the vector has been sorted, it will
if it hasn't been sorted.
likely not find elements
if it hasn't been sorted.
## Text parsing
## Text parsing
...
...
src/idl_gen_general.cpp
View file @
8468ea1a
...
@@ -1005,6 +1005,26 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
...
@@ -1005,6 +1005,26 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
code
+=
lang_
.
accessor_prefix
+
"__vector_len(o) : 0; "
;
code
+=
lang_
.
accessor_prefix
+
"__vector_len(o) : 0; "
;
code
+=
lang_
.
getter_suffix
;
code
+=
lang_
.
getter_suffix
;
code
+=
"}
\n
"
;
code
+=
"}
\n
"
;
// See if we should generate a by-key accessor.
if
(
field
.
value
.
type
.
element
==
BASE_TYPE_STRUCT
&&
!
field
.
value
.
type
.
struct_def
->
fixed
)
{
auto
&
sd
=
*
field
.
value
.
type
.
struct_def
;
auto
&
fields
=
sd
.
fields
.
vec
;
for
(
auto
kit
=
fields
.
begin
();
kit
!=
fields
.
end
();
++
kit
)
{
auto
&
key_field
=
**
kit
;
if
(
key_field
.
key
)
{
code
+=
" public "
+
sd
.
name
+
lang_
.
optional_suffix
+
" "
;
code
+=
MakeCamel
(
field
.
name
,
lang_
.
first_camel_upper
)
+
"ByKey("
;
code
+=
GenTypeNameDest
(
key_field
.
value
.
type
)
+
" key)"
;
code
+=
offset_prefix
;
code
+=
sd
.
name
+
".__lookup_by_key("
;
code
+=
lang_
.
accessor_prefix
+
"__vector(o), key, "
;
code
+=
lang_
.
accessor_prefix
+
"bb) : null; "
;
code
+=
"}
\n
"
;
break
;
}
}
}
}
}
// Generate a ByteBuffer accessor for strings & vectors of scalars.
// Generate a ByteBuffer accessor for strings & vectors of scalars.
if
((
field
.
value
.
type
.
base_type
==
BASE_TYPE_VECTOR
&&
if
((
field
.
value
.
type
.
base_type
==
BASE_TYPE_VECTOR
&&
...
@@ -1302,7 +1322,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
...
@@ -1302,7 +1322,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
}
}
else
{
else
{
code
+=
"
\n
public static VectorOffset "
;
code
+=
"
\n
public static VectorOffset "
;
code
+=
"CreateMySortedVectorOfTables(FlatBufferBuilder builder, "
;
code
+=
"CreateSortedVectorOf"
+
struct_def
.
name
;
code
+=
"(FlatBufferBuilder builder, "
;
code
+=
"Offset<"
+
struct_def
.
name
+
">"
;
code
+=
"Offset<"
+
struct_def
.
name
+
">"
;
code
+=
"[] offsets) {
\n
"
;
code
+=
"[] offsets) {
\n
"
;
code
+=
" Array.Sort(offsets, (Offset<"
+
struct_def
.
name
+
code
+=
" Array.Sort(offsets, (Offset<"
+
struct_def
.
name
+
...
@@ -1312,8 +1333,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
...
@@ -1312,8 +1333,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
}
}
code
+=
"
\n
public static "
+
struct_def
.
name
+
lang_
.
optional_suffix
;
code
+=
"
\n
public static "
+
struct_def
.
name
+
lang_
.
optional_suffix
;
code
+=
"
"
+
FunctionStart
(
'L'
)
+
"ookupByKey("
+
GenVectorOffsetType
()
;
code
+=
"
__lookup_by_key(int vectorLocation, "
;
code
+=
" vectorOffset, "
+
GenTypeNameDest
(
key_field
->
value
.
type
);
code
+=
GenTypeNameDest
(
key_field
->
value
.
type
);
code
+=
" key, ByteBuffer bb) {
\n
"
;
code
+=
" key, ByteBuffer bb) {
\n
"
;
if
(
key_field
->
value
.
type
.
base_type
==
BASE_TYPE_STRING
)
{
if
(
key_field
->
value
.
type
.
base_type
==
BASE_TYPE_STRING
)
{
code
+=
" byte[] byteKey = "
;
code
+=
" byte[] byteKey = "
;
...
@@ -1322,13 +1343,9 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
...
@@ -1322,13 +1343,9 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
else
else
code
+=
"System.Text.Encoding.UTF8.GetBytes(key);
\n
"
;
code
+=
"System.Text.Encoding.UTF8.GetBytes(key);
\n
"
;
}
}
code
+=
" int vectorLocation = "
+
GenByteBufferLength
(
"bb"
);
code
+=
" int span = "
;
code
+=
" - vectorOffset"
;
code
+=
"bb."
+
FunctionStart
(
'G'
)
+
"etInt(vectorLocation - 4);
\n
"
;
if
(
lang_
.
language
==
IDLOptions
::
kCSharp
)
code
+=
".Value"
;
code
+=
";
\n
int span = "
;
code
+=
"bb."
+
FunctionStart
(
'G'
)
+
"etInt(vectorLocation);
\n
"
;
code
+=
" int start = 0;
\n
"
;
code
+=
" int start = 0;
\n
"
;
code
+=
" vectorLocation += 4;
\n
"
;
code
+=
" while (span != 0) {
\n
"
;
code
+=
" while (span != 0) {
\n
"
;
code
+=
" int middle = span / 2;
\n
"
;
code
+=
" int middle = span / 2;
\n
"
;
code
+=
GenLookupKeyGetter
(
key_field
);
code
+=
GenLookupKeyGetter
(
key_field
);
...
...
tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
View file @
8468ea1a
...
@@ -50,7 +50,7 @@ namespace FlatBuffers.Test
...
@@ -50,7 +50,7 @@ namespace FlatBuffers.Test
Monster
.
StartMonster
(
fbb
);
Monster
.
StartMonster
(
fbb
);
Monster
.
AddName
(
fbb
,
names
[
2
]);
Monster
.
AddName
(
fbb
,
names
[
2
]);
off
[
2
]
=
Monster
.
EndMonster
(
fbb
);
off
[
2
]
=
Monster
.
EndMonster
(
fbb
);
var
sortMons
=
Monster
.
Create
MySortedVectorOfTables
(
fbb
,
off
);
var
sortMons
=
Monster
.
Create
SortedVectorOfMonster
(
fbb
,
off
);
// We set up the same values as monsterdata.json:
// We set up the same values as monsterdata.json:
...
@@ -123,9 +123,9 @@ namespace FlatBuffers.Test
...
@@ -123,9 +123,9 @@ namespace FlatBuffers.Test
Assert
.
AreEqual
(
monster
.
Testarrayoftables
(
2
).
Value
.
Name
,
"Wilma"
);
Assert
.
AreEqual
(
monster
.
Testarrayoftables
(
2
).
Value
.
Name
,
"Wilma"
);
// Example of searching for a table by the key
// Example of searching for a table by the key
Assert
.
IsTrue
(
Monster
.
LookupByKey
(
sortMons
,
"Frodo"
,
fbb
.
DataBuffer
)
!=
null
);
Assert
.
IsTrue
(
monster
.
TestarrayoftablesByKey
(
"Frodo"
)
!=
null
);
Assert
.
IsTrue
(
Monster
.
LookupByKey
(
sortMons
,
"Barney"
,
fbb
.
DataBuffer
)
!=
null
);
Assert
.
IsTrue
(
monster
.
TestarrayoftablesByKey
(
"Barney"
)
!=
null
);
Assert
.
IsTrue
(
Monster
.
LookupByKey
(
sortMons
,
"Wilma"
,
fbb
.
DataBuffer
)
!=
null
);
Assert
.
IsTrue
(
monster
.
TestarrayoftablesByKey
(
"Wilma"
)
!=
null
);
// testType is an existing field and mutating it should succeed
// testType is an existing field and mutating it should succeed
Assert
.
AreEqual
(
monster
.
TestType
,
Any
.
Monster
);
Assert
.
AreEqual
(
monster
.
TestType
,
Any
.
Monster
);
...
...
tests/JavaTest.java
View file @
8468ea1a
...
@@ -142,9 +142,9 @@ class JavaTest {
...
@@ -142,9 +142,9 @@ class JavaTest {
TestEq
(
monster
.
testarrayoftables
(
2
).
name
(),
"Wilma"
);
TestEq
(
monster
.
testarrayoftables
(
2
).
name
(),
"Wilma"
);
// Example of searching for a table by the key
// Example of searching for a table by the key
TestEq
(
Monster
.
lookupByKey
(
sortMons
,
"Frodo"
,
fbb
.
dataBuffer
()
).
name
(),
"Frodo"
);
TestEq
(
monster
.
testarrayoftablesByKey
(
"Frodo"
).
name
(),
"Frodo"
);
TestEq
(
Monster
.
lookupByKey
(
sortMons
,
"Barney"
,
fbb
.
dataBuffer
()
).
name
(),
"Barney"
);
TestEq
(
monster
.
testarrayoftablesByKey
(
"Barney"
).
name
(),
"Barney"
);
TestEq
(
Monster
.
lookupByKey
(
sortMons
,
"Wilma"
,
fbb
.
dataBuffer
()
).
name
(),
"Wilma"
);
TestEq
(
monster
.
testarrayoftablesByKey
(
"Wilma"
).
name
(),
"Wilma"
);
// testType is an existing field and mutating it should succeed
// testType is an existing field and mutating it should succeed
TestEq
(
monster
.
testType
(),
(
byte
)
Any
.
Monster
);
TestEq
(
monster
.
testType
(),
(
byte
)
Any
.
Monster
);
...
...
tests/MyGame/Example/Monster.cs
View file @
8468ea1a
...
@@ -41,6 +41,7 @@ public struct Monster : IFlatbufferObject
...
@@ -41,6 +41,7 @@ public struct Monster : IFlatbufferObject
/// multiline too
/// multiline too
public
Monster
?
Testarrayoftables
(
int
j
)
{
int
o
=
__p
.
__offset
(
26
);
return
o
!=
0
?
(
Monster
?)(
new
Monster
()).
__assign
(
__p
.
__indirect
(
__p
.
__vector
(
o
)
+
j
*
4
),
__p
.
bb
)
:
null
;
}
public
Monster
?
Testarrayoftables
(
int
j
)
{
int
o
=
__p
.
__offset
(
26
);
return
o
!=
0
?
(
Monster
?)(
new
Monster
()).
__assign
(
__p
.
__indirect
(
__p
.
__vector
(
o
)
+
j
*
4
),
__p
.
bb
)
:
null
;
}
public
int
TestarrayoftablesLength
{
get
{
int
o
=
__p
.
__offset
(
26
);
return
o
!=
0
?
__p
.
__vector_len
(
o
)
:
0
;
}
}
public
int
TestarrayoftablesLength
{
get
{
int
o
=
__p
.
__offset
(
26
);
return
o
!=
0
?
__p
.
__vector_len
(
o
)
:
0
;
}
}
public
Monster
?
TestarrayoftablesByKey
(
string
key
)
{
int
o
=
__p
.
__offset
(
26
);
return
o
!=
0
?
Monster
.
__lookup_by_key
(
__p
.
__vector
(
o
),
key
,
__p
.
bb
)
:
null
;
}
public
Monster
?
Enemy
{
get
{
int
o
=
__p
.
__offset
(
28
);
return
o
!=
0
?
(
Monster
?)(
new
Monster
()).
__assign
(
__p
.
__indirect
(
o
+
__p
.
bb_pos
),
__p
.
bb
)
:
null
;
}
}
public
Monster
?
Enemy
{
get
{
int
o
=
__p
.
__offset
(
28
);
return
o
!=
0
?
(
Monster
?)(
new
Monster
()).
__assign
(
__p
.
__indirect
(
o
+
__p
.
bb_pos
),
__p
.
bb
)
:
null
;
}
}
public
byte
Testnestedflatbuffer
(
int
j
)
{
int
o
=
__p
.
__offset
(
30
);
return
o
!=
0
?
__p
.
bb
.
Get
(
__p
.
__vector
(
o
)
+
j
*
1
)
:
(
byte
)
0
;
}
public
byte
Testnestedflatbuffer
(
int
j
)
{
int
o
=
__p
.
__offset
(
30
);
return
o
!=
0
?
__p
.
bb
.
Get
(
__p
.
__vector
(
o
)
+
j
*
1
)
:
(
byte
)
0
;
}
public
int
TestnestedflatbufferLength
{
get
{
int
o
=
__p
.
__offset
(
30
);
return
o
!=
0
?
__p
.
__vector_len
(
o
)
:
0
;
}
}
public
int
TestnestedflatbufferLength
{
get
{
int
o
=
__p
.
__offset
(
30
);
return
o
!=
0
?
__p
.
__vector_len
(
o
)
:
0
;
}
}
...
@@ -132,17 +133,15 @@ public struct Monster : IFlatbufferObject
...
@@ -132,17 +133,15 @@ public struct Monster : IFlatbufferObject
}
}
public
static
void
FinishMonsterBuffer
(
FlatBufferBuilder
builder
,
Offset
<
Monster
>
offset
)
{
builder
.
Finish
(
offset
.
Value
,
"MONS"
);
}
public
static
void
FinishMonsterBuffer
(
FlatBufferBuilder
builder
,
Offset
<
Monster
>
offset
)
{
builder
.
Finish
(
offset
.
Value
,
"MONS"
);
}
public
static
VectorOffset
Create
MySortedVectorOfTables
(
FlatBufferBuilder
builder
,
Offset
<
Monster
>[]
offsets
)
{
public
static
VectorOffset
Create
SortedVectorOfMonster
(
FlatBufferBuilder
builder
,
Offset
<
Monster
>[]
offsets
)
{
Array
.
Sort
(
offsets
,
(
Offset
<
Monster
>
o1
,
Offset
<
Monster
>
o2
)
=>
Table
.
CompareStrings
(
Table
.
__offset
(
10
,
o1
.
Value
,
builder
.
DataBuffer
),
Table
.
__offset
(
10
,
o2
.
Value
,
builder
.
DataBuffer
),
builder
.
DataBuffer
));
Array
.
Sort
(
offsets
,
(
Offset
<
Monster
>
o1
,
Offset
<
Monster
>
o2
)
=>
Table
.
CompareStrings
(
Table
.
__offset
(
10
,
o1
.
Value
,
builder
.
DataBuffer
),
Table
.
__offset
(
10
,
o2
.
Value
,
builder
.
DataBuffer
),
builder
.
DataBuffer
));
return
builder
.
CreateVectorOfTables
(
offsets
);
return
builder
.
CreateVectorOfTables
(
offsets
);
}
}
public
static
Monster
?
LookupByKey
(
VectorOffset
vectorOffset
,
string
key
,
ByteBuffer
bb
)
{
public
static
Monster
?
__lookup_by_key
(
int
vectorLocation
,
string
key
,
ByteBuffer
bb
)
{
byte
[]
byteKey
=
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
key
);
byte
[]
byteKey
=
System
.
Text
.
Encoding
.
UTF8
.
GetBytes
(
key
);
int
vectorLocation
=
bb
.
Length
-
vectorOffset
.
Value
;
int
span
=
bb
.
GetInt
(
vectorLocation
-
4
);
int
span
=
bb
.
GetInt
(
vectorLocation
);
int
start
=
0
;
int
start
=
0
;
vectorLocation
+=
4
;
while
(
span
!=
0
)
{
while
(
span
!=
0
)
{
int
middle
=
span
/
2
;
int
middle
=
span
/
2
;
int
tableOffset
=
Table
.
__indirect
(
vectorLocation
+
4
*
(
start
+
middle
),
bb
);
int
tableOffset
=
Table
.
__indirect
(
vectorLocation
+
4
*
(
start
+
middle
),
bb
);
...
...
tests/MyGame/Example/Monster.java
View file @
8468ea1a
...
@@ -47,6 +47,7 @@ public final class Monster extends Table {
...
@@ -47,6 +47,7 @@ public final class Monster extends Table {
public
Monster
testarrayoftables
(
int
j
)
{
return
testarrayoftables
(
new
Monster
(),
j
);
}
public
Monster
testarrayoftables
(
int
j
)
{
return
testarrayoftables
(
new
Monster
(),
j
);
}
public
Monster
testarrayoftables
(
Monster
obj
,
int
j
)
{
int
o
=
__offset
(
26
);
return
o
!=
0
?
obj
.
__assign
(
__indirect
(
__vector
(
o
)
+
j
*
4
),
bb
)
:
null
;
}
public
Monster
testarrayoftables
(
Monster
obj
,
int
j
)
{
int
o
=
__offset
(
26
);
return
o
!=
0
?
obj
.
__assign
(
__indirect
(
__vector
(
o
)
+
j
*
4
),
bb
)
:
null
;
}
public
int
testarrayoftablesLength
()
{
int
o
=
__offset
(
26
);
return
o
!=
0
?
__vector_len
(
o
)
:
0
;
}
public
int
testarrayoftablesLength
()
{
int
o
=
__offset
(
26
);
return
o
!=
0
?
__vector_len
(
o
)
:
0
;
}
public
Monster
testarrayoftablesByKey
(
String
key
)
{
int
o
=
__offset
(
26
);
return
o
!=
0
?
Monster
.
__lookup_by_key
(
__vector
(
o
),
key
,
bb
)
:
null
;
}
public
Monster
enemy
()
{
return
enemy
(
new
Monster
());
}
public
Monster
enemy
()
{
return
enemy
(
new
Monster
());
}
public
Monster
enemy
(
Monster
obj
)
{
int
o
=
__offset
(
28
);
return
o
!=
0
?
obj
.
__assign
(
__indirect
(
o
+
bb_pos
),
bb
)
:
null
;
}
public
Monster
enemy
(
Monster
obj
)
{
int
o
=
__offset
(
28
);
return
o
!=
0
?
obj
.
__assign
(
__indirect
(
o
+
bb_pos
),
bb
)
:
null
;
}
public
int
testnestedflatbuffer
(
int
j
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
bb
.
get
(
__vector
(
o
)
+
j
*
1
)
&
0xFF
:
0
;
}
public
int
testnestedflatbuffer
(
int
j
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
bb
.
get
(
__vector
(
o
)
+
j
*
1
)
&
0xFF
:
0
;
}
...
@@ -145,12 +146,10 @@ public final class Monster extends Table {
...
@@ -145,12 +146,10 @@ public final class Monster extends Table {
@Override
@Override
protected
int
keysCompare
(
Integer
o1
,
Integer
o2
,
ByteBuffer
_bb
)
{
return
compareStrings
(
__offset
(
10
,
o1
,
_bb
),
__offset
(
10
,
o2
,
_bb
),
_bb
);
}
protected
int
keysCompare
(
Integer
o1
,
Integer
o2
,
ByteBuffer
_bb
)
{
return
compareStrings
(
__offset
(
10
,
o1
,
_bb
),
__offset
(
10
,
o2
,
_bb
),
_bb
);
}
public
static
Monster
lookupByKey
(
int
vectorOffset
,
String
key
,
ByteBuffer
bb
)
{
public
static
Monster
__lookup_by_key
(
int
vectorLocation
,
String
key
,
ByteBuffer
bb
)
{
byte
[]
byteKey
=
key
.
getBytes
(
Table
.
UTF8_CHARSET
.
get
());
byte
[]
byteKey
=
key
.
getBytes
(
Table
.
UTF8_CHARSET
.
get
());
int
vectorLocation
=
bb
.
array
().
length
-
vectorOffset
;
int
span
=
bb
.
getInt
(
vectorLocation
-
4
);
int
span
=
bb
.
getInt
(
vectorLocation
);
int
start
=
0
;
int
start
=
0
;
vectorLocation
+=
4
;
while
(
span
!=
0
)
{
while
(
span
!=
0
)
{
int
middle
=
span
/
2
;
int
middle
=
span
/
2
;
int
tableOffset
=
__indirect
(
vectorLocation
+
4
*
(
start
+
middle
),
bb
);
int
tableOffset
=
__indirect
(
vectorLocation
+
4
*
(
start
+
middle
),
bb
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment