Skip to content

Commit 7199945

Browse files
committed
Add comments.
1 parent 95ab04b commit 7199945

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

bson/src/main/org/bson/io/ByteBufferBsonInput.java

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ public class ByteBufferBsonInput implements BsonInput {
3535

3636
private static final String[] ONE_BYTE_ASCII_STRINGS = new String[Byte.MAX_VALUE + 1];
3737
private static final boolean UNALIGNED_ACCESS_SUPPORTED = isUnalignedAccessAllowed();
38-
private int scratchBufferSize = 0;
38+
/* A dynamically sized scratch buffer, that is reused across BSON String reads:
39+
* 1. Reduces garbage collection by avoiding new byte array creation.
40+
* 2. Improves cache utilization through temporal locality.
41+
* 3. Avoids JVM allocation and zeroing cost for new memory allocations.
42+
*/
3943
private byte[] scratchBuffer;
4044

4145

@@ -136,8 +140,8 @@ public String readCString() {
136140
return readString(size);
137141
}
138142

139-
private String readString(final int stringSize) {
140-
if (stringSize == 2) {
143+
private String readString(final int bsonStringSize) {
144+
if (bsonStringSize == 2) {
141145
byte asciiByte = buffer.get(); // if only one byte in the string, it must be ascii.
142146
byte nullByte = buffer.get(); // read null terminator
143147
if (nullByte != 0) {
@@ -151,24 +155,24 @@ private String readString(final int stringSize) {
151155
if (buffer.isBackedByArray()) {
152156
int position = buffer.position();
153157
int arrayOffset = buffer.arrayOffset();
154-
int newPosition = position + stringSize;
158+
int newPosition = position + bsonStringSize;
155159
buffer.position(newPosition);
156160

157161
byte[] array = buffer.array();
158162
if (array[arrayOffset + newPosition - 1] != 0) {
159163
throw new BsonSerializationException("Found a BSON string that is not null-terminated");
160164
}
161-
return new String(array, arrayOffset + position, stringSize - 1, StandardCharsets.UTF_8);
162-
} else if (stringSize > scratchBufferSize) {
163-
scratchBufferSize = stringSize + (stringSize >> 1); //1.5 times the size
165+
return new String(array, arrayOffset + position, bsonStringSize - 1, StandardCharsets.UTF_8);
166+
} else if (scratchBuffer == null || bsonStringSize > scratchBuffer.length) {
167+
int scratchBufferSize = bsonStringSize + (bsonStringSize >>> 1); //1.5 times the size
164168
scratchBuffer = new byte[scratchBufferSize];
165169
}
166170

167-
buffer.get(scratchBuffer, 0, stringSize);
168-
if (scratchBuffer[stringSize - 1] != 0) {
171+
buffer.get(scratchBuffer, 0, bsonStringSize);
172+
if (scratchBuffer[bsonStringSize - 1] != 0) {
169173
throw new BsonSerializationException("BSON string not null-terminated");
170174
}
171-
return new String(scratchBuffer, 0, stringSize - 1, StandardCharsets.UTF_8);
175+
return new String(scratchBuffer, 0, bsonStringSize - 1, StandardCharsets.UTF_8);
172176
}
173177
}
174178

@@ -180,6 +184,10 @@ public void skipCString() {
180184
buffer.position(pos + length);
181185
}
182186

187+
/*
188+
This method uses the SWAR (SIMD Within A Register) technique when aligned access is supported.
189+
SWAR finds a null terminator by processing 8 bytes at once.
190+
*/
183191
public int computeCStringLength(final int prevPos) {
184192
ensureOpen();
185193
int pos = buffer.position();

driver-core/src/test/unit/com/mongodb/internal/connection/ByteBufferBsonInputTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ public boolean isBackedByArray() {
7373

7474
@Override
7575
public byte[] array() {
76-
return Assertions.fail("array() is called, when hasArray() returns false");
76+
return Assertions.fail("array() is called, when isBackedByArray() returns false");
7777
}
7878

7979
@Override
8080
public int arrayOffset() {
81-
return Assertions.fail("arrayOffset() is called, when hasArray() returns false");
81+
return Assertions.fail("arrayOffset() is called, when isBackedByArray() returns false");
8282
}
8383
}
8484
);
@@ -558,10 +558,10 @@ public static Stream<Arguments> nonNullTerminatedStringsWithBuffers() {
558558
void shouldThrowIfStringIsNotNullTerminated(final byte[] nonNullTerminatedString, final BufferProvider bufferProvider) {
559559
// given
560560
ByteBuf buffer = allocateAndWriteToBuffer(bufferProvider, nonNullTerminatedString);
561-
try (ByteBufferBsonInput expectedStringeam = new ByteBufferBsonInput(buffer)) {
561+
try (ByteBufferBsonInput expectedString = new ByteBufferBsonInput(buffer)) {
562562

563563
// when & then
564-
assertThrows(BsonSerializationException.class, expectedStringeam::readString);
564+
assertThrows(BsonSerializationException.class, expectedString::readString);
565565
}
566566
}
567567

0 commit comments

Comments
 (0)