mirror of
https://github.com/google/flatbuffers.git
synced 2026-07-05 06:17:04 +00:00
[Java] Add support for shared strings on FlatBufferBuilder. (#6012)
Added a method FlatBufferBuilder::createSharedString that enable string sharing for building messages on java. The shared pool will only contains strings inserted by this methods.
This commit is contained in:
@@ -22,6 +22,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.*;
|
import java.nio.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
/// @addtogroup flatbuffers_java_api
|
/// @addtogroup flatbuffers_java_api
|
||||||
@@ -47,6 +50,7 @@ public class FlatBufferBuilder {
|
|||||||
boolean force_defaults = false; // False omits default values from the serialized data.
|
boolean force_defaults = false; // False omits default values from the serialized data.
|
||||||
ByteBufferFactory bb_factory; // Factory for allocating the internal buffer
|
ByteBufferFactory bb_factory; // Factory for allocating the internal buffer
|
||||||
final Utf8 utf8; // UTF-8 encoder to use
|
final Utf8 utf8; // UTF-8 encoder to use
|
||||||
|
Map<String, Integer> string_pool; // map used to cache shared strings.
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,6 +151,9 @@ public class FlatBufferBuilder {
|
|||||||
object_start = 0;
|
object_start = 0;
|
||||||
num_vtables = 0;
|
num_vtables = 0;
|
||||||
vector_num_elems = 0;
|
vector_num_elems = 0;
|
||||||
|
if (string_pool != null) {
|
||||||
|
string_pool.clear();
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,6 +231,9 @@ public class FlatBufferBuilder {
|
|||||||
object_start = 0;
|
object_start = 0;
|
||||||
num_vtables = 0;
|
num_vtables = 0;
|
||||||
vector_num_elems = 0;
|
vector_num_elems = 0;
|
||||||
|
if (string_pool != null) {
|
||||||
|
string_pool.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -527,6 +537,37 @@ public class FlatBufferBuilder {
|
|||||||
return createVectorOfTables(offsets);
|
return createVectorOfTables(offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode the String `s` in the buffer using UTF-8. If a String with
|
||||||
|
* this exact contents has already been serialized using this method,
|
||||||
|
* instead simply returns the offset of the existing String.
|
||||||
|
*
|
||||||
|
* Usage of the method will incur into additional allocations,
|
||||||
|
* so it is advisable to use it only when it is known upfront that
|
||||||
|
* your message will have several repeated strings.
|
||||||
|
*
|
||||||
|
* @param s The String to encode.
|
||||||
|
* @return The offset in the buffer where the encoded String starts.
|
||||||
|
*/
|
||||||
|
public int createSharedString(String s) {
|
||||||
|
|
||||||
|
if (string_pool == null) {
|
||||||
|
string_pool = new HashMap<>();
|
||||||
|
int offset = createString(s);
|
||||||
|
string_pool.put(s, offset);
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer offset = string_pool.get(s);
|
||||||
|
|
||||||
|
if(offset == null) {
|
||||||
|
offset = createString(s);
|
||||||
|
string_pool.put(s, offset);
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
||||||
* already a {@link CharBuffer}, this method is allocation free.
|
* already a {@link CharBuffer}, this method is allocation free.
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ import java.io.*;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -101,6 +103,8 @@ class JavaTest {
|
|||||||
|
|
||||||
TestVectorOfBytes();
|
TestVectorOfBytes();
|
||||||
|
|
||||||
|
TestSharedStringPool();
|
||||||
|
|
||||||
System.out.println("FlatBuffers test: completed successfully");
|
System.out.println("FlatBuffers test: completed successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,6 +1220,15 @@ class JavaTest {
|
|||||||
TestEq(monsterObject8.inventoryLength(), 2048);
|
TestEq(monsterObject8.inventoryLength(), 2048);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TestSharedStringPool() {
|
||||||
|
FlatBufferBuilder fb = new FlatBufferBuilder(1);
|
||||||
|
String testString = "My string";
|
||||||
|
int offset = fb.createSharedString(testString);
|
||||||
|
for (int i=0; i< 10; i++) {
|
||||||
|
TestEq(offset, fb.createSharedString(testString));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static <T> void TestEq(T a, T b) {
|
static <T> void TestEq(T a, T b) {
|
||||||
if (!a.equals(b)) {
|
if (!a.equals(b)) {
|
||||||
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ class KotlinTest {
|
|||||||
|
|
||||||
TestVectorOfUnions()
|
TestVectorOfUnions()
|
||||||
|
|
||||||
|
TestSharedStringPool()
|
||||||
|
|
||||||
println("FlatBuffers test: completed successfully")
|
println("FlatBuffers test: completed successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,5 +458,14 @@ class KotlinTest {
|
|||||||
|
|
||||||
assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
|
assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TestSharedStringPool() {
|
||||||
|
val fb = FlatBufferBuilder(1);
|
||||||
|
val testString = "My string";
|
||||||
|
val offset = fb.createSharedString(testString);
|
||||||
|
for (i in 0..10) {
|
||||||
|
assert(offset == fb.createSharedString(testString));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user