Skip to content

Commit d998e9d

Browse files
committed
Simplified decode method to use much less memory for small documents. Before it would use a minumum of 4K per document. Not it allocates an array of exactly the right size.
Got rid of unnecessary _buffer field, because ownership of each buffer is handed off to the callback and can't be re-used anyway
1 parent 15f5930 commit d998e9d

2 files changed

Lines changed: 28 additions & 36 deletions

File tree

src/main/org/bson/LazyBSONDecoder.java

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,38 +53,18 @@ public int decode(byte[] b, BSONCallback callback) {
5353
}
5454

5555
public int decode(InputStream in, BSONCallback callback) throws IOException {
56-
byte[] data = null;
57-
if (_buffer == null)
58-
_buffer = new byte[4096];
59-
int read = readBytesFully(in, _buffer, 0, 4);
60-
int objSize = Bits.readInt(_buffer);
61-
if (objSize > _buffer.length) {
62-
// need bigger buffer
63-
data = new byte[objSize];
64-
System.arraycopy(_buffer, 0, data, 0, read);
65-
} else {
66-
data = _buffer;
67-
_buffer = null;
68-
}
56+
byte[] objSizeBuffer = new byte[BYTES_IN_INTEGER];
57+
Bits.readFully(in, objSizeBuffer, 0, BYTES_IN_INTEGER);
58+
int objSize = Bits.readInt(objSizeBuffer);
59+
byte[] data = new byte[objSize];
60+
System.arraycopy(objSizeBuffer, 0, data, 0, BYTES_IN_INTEGER);
6961

70-
if (read < objSize)
71-
readBytesFully(in, data, read, objSize - read);
62+
Bits.readFully(in, data, BYTES_IN_INTEGER, objSize - BYTES_IN_INTEGER);
7263

73-
callback.gotBinary(null, (byte)0, data);
74-
return objSize + 4;
64+
// note that we are handing off ownership of the data byte array to the callback
65+
callback.gotBinary(null, (byte) 0, data);
66+
return objSize;
7567
}
7668

77-
private int readBytesFully(InputStream in, byte[] buffer, int offset, int toread) throws IOException {
78-
int read = 0;
79-
int len = buffer.length;
80-
while (read < toread) {
81-
int n = in.read(buffer, offset, toread - read);
82-
read += n;
83-
offset += n;
84-
}
85-
return read;
86-
}
87-
88-
byte[] _buffer = null;
89-
69+
private static int BYTES_IN_INTEGER = 4;
9070
}

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

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,26 @@ public static void readFully( InputStream in, byte[] b )
2828
readFully( in , b , b.length );
2929
}
3030

31-
public static void readFully( InputStream in, byte[] b , int l )
31+
public static void readFully( InputStream in, byte[] b, int length )
3232
throws IOException {
33-
int x = 0;
34-
while ( x<l ){
35-
int temp = in.read( b , x , l - x );
36-
if ( temp < 0 )
33+
readFully(in, b, 0, length);
34+
}
35+
36+
public static void readFully( InputStream in, byte[] b, int startOffset, int length )
37+
throws IOException {
38+
39+
if (b.length - startOffset > length) {
40+
throw new IllegalArgumentException("Buffer is too small");
41+
}
42+
43+
int offset = startOffset;
44+
int toRead = length;
45+
while ( toRead > 0 ){
46+
int bytesRead = in.read( b, offset , toRead );
47+
if ( bytesRead < 0 )
3748
throw new EOFException();
38-
x += temp;
49+
toRead -= bytesRead;
50+
offset += bytesRead;
3951
}
4052
}
4153

0 commit comments

Comments
 (0)