Skip to content

Commit 82782ee

Browse files
committed
JAVA-5788 Latin heap array fast path
1 parent 2049481 commit 82782ee

File tree

6 files changed

+65
-2
lines changed

6 files changed

+65
-2
lines changed

bson/src/main/org/bson/ByteBuf.java

+7
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,13 @@ public interface ByteBuf {
125125
*/
126126
ByteBuf flip();
127127

128+
/**
129+
* States whether this buffer is backed by an accessible byte array.
130+
*
131+
* @return {@code true} if, and only if, this buffer is backed by an array and is not read-only
132+
*/
133+
boolean hasArray();
134+
128135
/**
129136
* <p>Returns the byte array that backs this buffer <em>(optional operation)</em>.</p>
130137
*

bson/src/main/org/bson/ByteBufNIO.java

+5
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ public ByteBuf flip() {
103103
return this;
104104
}
105105

106+
@Override
107+
public boolean hasArray() {
108+
return buf.hasArray();
109+
}
110+
106111
@Override
107112
public byte[] array() {
108113
return buf.array();

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

+6-2
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,15 @@ public void writeLong(final long value) {
196196
writeInt64(value);
197197
}
198198

199-
private int writeCharacters(final String str, final boolean checkForNullCharacters) {
199+
protected int writeCharacters(final String str, final boolean checkForNullCharacters) {
200+
return writeCharacters(str, 0, checkForNullCharacters);
201+
}
202+
203+
protected final int writeCharacters(final String str, int start, final boolean checkForNullCharacters) {
200204
int len = str.length();
201205
int total = 0;
202206

203-
for (int i = 0; i < len;) {
207+
for (int i = start; i < len;) {
204208
int c = Character.codePointAt(str, i);
205209

206210
if (checkForNullCharacters && c == 0x0) {

driver-core/src/main/com/mongodb/internal/connection/ByteBufferBsonOutput.java

+38
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.mongodb.internal.connection;
1818

19+
import org.bson.BsonSerializationException;
1920
import org.bson.ByteBuf;
2021
import org.bson.io.OutputBuffer;
2122

@@ -27,6 +28,7 @@
2728

2829
import static com.mongodb.assertions.Assertions.assertTrue;
2930
import static com.mongodb.assertions.Assertions.notNull;
31+
import static java.lang.String.format;
3032

3133
/**
3234
* <p>This class is not part of the public API and may be removed or changed at any time</p>
@@ -273,6 +275,42 @@ public void close() {
273275
}
274276
}
275277

278+
@Override
279+
protected int writeCharacters(final String str, final boolean checkForNullCharacters) {
280+
ensureOpen();
281+
ByteBuf buf = getCurrentByteBuffer();
282+
int i = 0;
283+
if (buf.hasArray() && (buf.remaining() >= str.length() + 1)) {
284+
byte[] array = buf.array();
285+
int pos = buf.position();
286+
int len = str.length();
287+
for (;i < len; i++) {
288+
char c = str.charAt(i);
289+
if (checkForNullCharacters && c == 0x0) {
290+
throw new BsonSerializationException(format("BSON cstring '%s' is not valid because it contains a null character "
291+
+ "at index %d", str, i));
292+
}
293+
if (c > 0x80) {
294+
break;
295+
}
296+
array[pos + i] = (byte) c;
297+
}
298+
if (i == len) {
299+
int total = len + 1;
300+
array[pos + len] = 0;
301+
position += total;
302+
buf.position(pos + total);
303+
return len + 1;
304+
}
305+
// ith character is not ASCII
306+
if (i > 0) {
307+
position += i;
308+
buf.position(pos + i);
309+
}
310+
}
311+
return i + super.writeCharacters(str, i, checkForNullCharacters);
312+
}
313+
276314
private static final class BufferPositionPair {
277315
private final int bufferIndex;
278316
private int position;

driver-core/src/main/com/mongodb/internal/connection/CompositeByteBuf.java

+5
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ private int getShort(final int index) {
208208
return (short) (get(index) & 0xff | (get(index + 1) & 0xff) << 8);
209209
}
210210

211+
@Override
212+
public boolean hasArray() {
213+
return false;
214+
}
215+
211216
@Override
212217
public byte[] array() {
213218
throw new UnsupportedOperationException("Not implemented yet!");

driver-core/src/main/com/mongodb/internal/connection/netty/NettyByteBuf.java

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ public ByteBuf flip() {
9595
return this;
9696
}
9797

98+
public boolean hasArray() {
99+
return proxied.hasArray();
100+
}
101+
98102
@Override
99103
public byte[] array() {
100104
return proxied.array();

0 commit comments

Comments
 (0)