Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #3 from pcpratts/feature/bson_size

Feature/bson size
  • Loading branch information...
commit 7eae5d15e033f3285ea80ee32c20699245044ee3 2 parents bf6bf03 + a25f6d9
@kohanyirobert authored
View
2  src/main/java/com/github/kohanyirobert/ebson/BsonDocument.java
@@ -196,7 +196,7 @@
*/
@Override
void putAll(Map<? extends String, ? extends Object> map);
-
+
/**
* {@linkplain BsonDocument Document} builder.
* <p>
View
11 src/main/java/com/github/kohanyirobert/ebson/BsonDocuments.java
@@ -37,6 +37,17 @@ public static BsonDocument readFrom(ByteBuffer buffer) {
public static void writeTo(ByteBuffer buffer, BsonDocument document) {
BsonToken.DOCUMENT.writer().writeTo(buffer, document);
}
+
+ /**
+ * Returns the binary size of the document. This is needed to allocate a
+ * ByteBuffer that is exactly the correct size.
+ *
+ * @param document the document to obtain the binary size of
+ * @return the documents binary size
+ */
+ public static int binarySize(BsonDocument document){
+ return BsonToken.DOCUMENT.writer().getSize(document);
+ }
/**
* Returns a new document containing {@code map}'s key-value pairs.
View
2  src/main/java/com/github/kohanyirobert/ebson/BsonObject.java
@@ -195,7 +195,7 @@ private BsonObject(byte terminal, Predicate<Class<?>> predicate,
public byte terminal() {
return terminal;
}
-
+
/**
* Returns this object's associated {@linkplain Predicate predicate}.
*
View
8 src/main/java/com/github/kohanyirobert/ebson/BsonWriter.java
@@ -24,4 +24,12 @@
* little-endian byte ordering
*/
void writeTo(ByteBuffer buffer, @Nullable Object reference);
+
+ /**
+ * Returns the size of the reference object.
+ *
+ * @param reference the object to return the size of
+ * @return the computed size
+ */
+ int getSize(@Nullable Object reference);
}
View
129 src/main/java/com/github/kohanyirobert/ebson/DefaultWriter.java
@@ -5,7 +5,9 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
+import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
+import com.google.common.primitives.Longs;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
@@ -17,8 +19,10 @@
import java.util.SortedSet;
import java.util.regex.Pattern;
-enum DefaultWriter implements BsonWriter {
+import javax.annotation.Nullable;
+enum DefaultWriter implements BsonWriter {
+
DOCUMENT {
@Override
@@ -32,6 +36,17 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.put(BsonBytes.EOO);
buffer.putInt(markedPosition, buffer.position() - markedPosition);
}
+
+ @Override
+ public int getSize(Object reference) {
+ int constSize = BYTES_BYTES + Ints.BYTES;
+ int variableSize = 0;
+ BsonWriter fieldWriter = BsonToken.FIELD.writer();
+ for (Entry<?, ?> entry : ((Map<?, ?>) reference).entrySet()) {
+ variableSize += fieldWriter.getSize(entry);
+ }
+ return constSize + variableSize;
+ }
},
FIELD {
@@ -46,6 +61,19 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
BsonToken.KEY.writer().writeTo(buffer, entry.getKey());
bsonObject.writer().writeTo(buffer, entry.getValue());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ Entry<?, ?> entry = (Entry<?, ?>) reference;
+ BsonObject bsonObject = BsonObject.find(entry.getValue() == null
+ ? null
+ : entry.getValue().getClass());
+
+ int constSize = BYTES_BYTES;
+ int variableSize = BsonToken.KEY.writer().getSize(entry.getKey())
+ + bsonObject.writer().getSize(entry.getValue());
+ return constSize + variableSize;
+ }
},
KEY {
@@ -54,6 +82,13 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.put(((String) reference).getBytes(Charsets.UTF_8)).put(BsonBytes.EOO);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ int constSize = BYTES_BYTES;
+ int variableSize = ((String) reference).getBytes(Charsets.UTF_8).length;
+ return constSize + variableSize;
+ }
},
DOUBLE {
@@ -62,6 +97,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.putDouble(((Double) reference).doubleValue());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return Doubles.BYTES;
+ }
},
STRING {
@@ -71,6 +111,14 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
byte[] bytes = ((String) reference).getBytes(Charsets.UTF_8);
buffer.putInt(bytes.length + 1).put(bytes).put(BsonBytes.EOO);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ int constSize = Ints.BYTES + BYTES_BYTES;
+ byte[] bytes = ((String) reference).getBytes(Charsets.UTF_8);
+ int variableSize = bytes.length;
+ return constSize + variableSize;
+ }
},
ARRAY {
@@ -86,6 +134,18 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
}
BsonToken.DOCUMENT.writer().writeTo(buffer, document);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ Object array = reference instanceof Collection
+ ? ((Collection<?>) reference).toArray()
+ : reference;
+ Map<Object, Object> document = Maps.newLinkedHashMap();
+ for (int i = 0; i < Array.getLength(array); i++) {
+ document.put(String.valueOf(i), Array.get(array, i));
+ }
+ return BsonToken.DOCUMENT.writer().getSize(document);
+ }
},
BINARY {
@@ -99,6 +159,14 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
bsonBinary.writer().writeTo(buffer, reference);
buffer.putInt(markedPosition, buffer.position() - markedPosition - Ints.BYTES - 1);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ BsonBinary bsonBinary = BsonBinary.find(reference.getClass());
+ int constSize = Ints.BYTES + BYTES_BYTES;
+ int variableSize = bsonBinary.writer().getSize(reference);
+ return constSize + variableSize;
+ }
},
GENERIC {
@@ -107,6 +175,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.put((byte[]) reference);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return ((byte[]) reference).length;
+ }
},
OBJECT_ID {
@@ -115,6 +188,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.put(((BsonObjectId) reference).objectId());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return ((BsonObjectId) reference).objectId().capacity();
+ }
},
BOOLEAN {
@@ -125,6 +203,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
? BsonBytes.TRUE
: BsonBytes.FALSE);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return BOOLEANS_BYTES;
+ }
},
UTC_DATE_TIME {
@@ -133,12 +216,22 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.putLong(((Date) reference).getTime());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return Longs.BYTES;
+ }
},
NULL {
@Override
public void checkedWriteTo(ByteBuffer buffer, Object reference) {}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return 0;
+ }
},
REGULAR_EXPRESSION {
@@ -151,6 +244,14 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
keyWriter.writeTo(buffer, flagsToOptions(regularExpression.flags()));
}
+ @Override
+ public int getSize(@Nullable Object reference) {
+ Pattern regularExpression = (Pattern) reference;
+ BsonWriter keyWriter = BsonToken.KEY.writer();
+ return keyWriter.getSize(regularExpression.pattern())
+ + keyWriter.getSize(flagsToOptions(regularExpression.flags()));
+ }
+
// @do-not-check-next-line CyclomaticComplexity
private String flagsToOptions(int flags) {
SortedSet<Character> options = Sets.newTreeSet();
@@ -185,6 +286,14 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
ByteBuffer symbol = ((BsonSymbol) reference).symbol();
buffer.putInt(symbol.capacity() + 1).put(symbol).put(BsonBytes.EOO);
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ ByteBuffer symbol = ((BsonSymbol) reference).symbol();
+ int constSize = Ints.BYTES + BYTES_BYTES;
+ int variableSize = symbol.capacity();
+ return constSize + variableSize;
+ }
},
INT32 {
@@ -193,6 +302,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.putInt(((Integer) reference).intValue());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return Ints.BYTES;
+ }
},
TIMESTAMP {
@@ -201,6 +315,11 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.put(((BsonTimestamp) reference).timestamp());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return ((BsonTimestamp) reference).timestamp().capacity();
+ }
},
INT64 {
@@ -209,7 +328,15 @@ public void checkedWriteTo(ByteBuffer buffer, Object reference) {
public void checkedWriteTo(ByteBuffer buffer, Object reference) {
buffer.putLong(((Long) reference).longValue());
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ return Longs.BYTES;
+ }
};
+
+ private static final int BOOLEANS_BYTES = 1;
+ private static final int BYTES_BYTES = 1;
@Override
public final void writeTo(ByteBuffer buffer, Object reference) {
View
7 src/test/java/com/github/kohanyirobert/ebson/DefaultBinaryReaderWriterTest.java
@@ -79,6 +79,13 @@ public void writeTo(ByteBuffer buffer, Object reference) {
BsonObject.STRING.writer().writeTo(buffer, user.getName());
BsonObject.INT32.writer().writeTo(buffer, Integer.valueOf(user.getAge()));
}
+
+ @Override
+ public int getSize(@Nullable Object reference) {
+ User user = (User) reference;
+ return BsonObject.STRING.writer().getSize(user.getName())
+ + BsonObject.INT32.writer().getSize(Integer.valueOf(user.getAge()));
+ }
}
private static final class User {
Please sign in to comment.
Something went wrong with that request. Please try again.