Skip to content

Commit a86b3df

Browse files
vbabaninrozza
andauthored
Add String cache for BsonArray indexes. (#1664)
JAVA-5836 --------- Co-authored-by: Ross Lawley <[email protected]>
1 parent 3e95e0d commit a86b3df

File tree

2 files changed

+45
-8
lines changed

2 files changed

+45
-8
lines changed

bson/src/main/org/bson/BsonBinaryWriter.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ public class BsonBinaryWriter extends AbstractBsonWriter {
3737

3838
private final BsonOutput bsonOutput;
3939
private final Stack<Integer> maxDocumentSizeStack = new Stack<>();
40+
private static final int ARRAY_INDEXES_CACHE_SIZE = 256;
41+
private static final String[] ARRAY_INDEXES_CACHE = new String[ARRAY_INDEXES_CACHE_SIZE];
4042
private Mark mark;
4143

44+
static {
45+
for (int i = 0; i < ARRAY_INDEXES_CACHE_SIZE; i++) {
46+
ARRAY_INDEXES_CACHE[i] = Integer.toString(i);
47+
}
48+
}
49+
4250
/**
4351
* Construct an instance.
4452
*
@@ -397,7 +405,12 @@ public void reset() {
397405

398406
private void writeCurrentName() {
399407
if (getContext().getContextType() == BsonContextType.ARRAY) {
400-
bsonOutput.writeCString(Integer.toString(getContext().index++));
408+
int index = getContext().index++;
409+
if (index >= ARRAY_INDEXES_CACHE_SIZE) {
410+
bsonOutput.writeCString(Integer.toString(index));
411+
} else {
412+
bsonOutput.writeCString(ARRAY_INDEXES_CACHE[index]);
413+
}
401414
} else {
402415
bsonOutput.writeCString(getName());
403416
}

bson/src/test/unit/org/bson/BsonBinaryWriterTest.java

+31-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.io.ByteArrayOutputStream;
2727
import java.io.IOException;
2828
import java.nio.ByteBuffer;
29+
import java.nio.charset.StandardCharsets;
2930
import java.util.List;
3031

3132
import static java.util.Arrays.asList;
@@ -49,7 +50,7 @@ public class BsonBinaryWriterTest {
4950
@BeforeEach
5051
public void setup() {
5152
buffer = new BasicOutputBuffer();
52-
writer = new BsonBinaryWriter(new BsonWriterSettings(100), new BsonBinaryWriterSettings(1024), buffer);
53+
writer = new BsonBinaryWriter(new BsonWriterSettings(100), new BsonBinaryWriterSettings(12904), buffer);
5354
}
5455

5556
@AfterEach
@@ -61,7 +62,7 @@ public void tearDown() {
6162
public void shouldThrowWhenMaxDocumentSizeIsExceeded() {
6263
try {
6364
writer.writeStartDocument();
64-
writer.writeBinaryData("b", new BsonBinary(new byte[1024]));
65+
writer.writeBinaryData("b", new BsonBinary(new byte[12904]));
6566
writer.writeEndDocument();
6667
fail();
6768
} catch (BsonMaximumSizeExceededException e) {
@@ -197,16 +198,39 @@ public void testWriteArray() {
197198
}
198199

199200
@Test
200-
public void testWriteArrayElements() {
201+
public void testWriteArrayElements() throws IOException {
202+
ByteArrayOutputStream expectedOutput = new ByteArrayOutputStream();
203+
expectedOutput.write(new byte[]{
204+
88, 11, 0, 0, //document length
205+
4, // array type
206+
97, 49, 0, // "a1" name + null terminator
207+
79, 11, 0, 0}); // array length
208+
201209

202210
writer.writeStartDocument();
203211
writer.writeStartArray("a1");
204-
writer.writeBoolean(true);
205-
writer.writeBoolean(false);
212+
int arrayIndex = 0;
213+
while (arrayIndex < 500) {
214+
writer.writeBoolean(true);
215+
216+
expectedOutput.write(BsonType.BOOLEAN.getValue());
217+
expectedOutput.write(Integer.toString(arrayIndex++).getBytes(StandardCharsets.UTF_8));
218+
expectedOutput.write(0); // null terminator
219+
expectedOutput.write(1); // boolean value
220+
221+
writer.writeBoolean(false);
222+
223+
expectedOutput.write(BsonType.BOOLEAN.getValue());
224+
expectedOutput.write(Integer.toString(arrayIndex++).getBytes(StandardCharsets.UTF_8));
225+
expectedOutput.write(0); // null terminator
226+
expectedOutput.write(0); // boolean value
227+
}
206228
writer.writeEndArray();
229+
expectedOutput.write(0); // end of array
207230
writer.writeEndDocument();
208-
byte[] expectedValues = {22, 0, 0, 0, 4, 97, 49, 0, 13, 0, 0, 0, 8, 48, 0, 1, 8, 49, 0, 0, 0, 0};
209-
assertArrayEquals(expectedValues, buffer.toByteArray());
231+
expectedOutput.write(0); // end of a document
232+
233+
assertArrayEquals(expectedOutput.toByteArray(), buffer.toByteArray());
210234
}
211235

212236
@Test

0 commit comments

Comments
 (0)