Optimized callback class to return Java objects
This commit is contained in:
parent
2daf86bb7b
commit
315e608cd4
|
@ -70,7 +70,7 @@ def profile(str)
|
|||
end
|
||||
end
|
||||
|
||||
def benchmark(str, n, coll_name, data, create_index=false)
|
||||
def benchmark(str, n, coll_name, data, create_index=false, verbosity=true)
|
||||
coll = @db.collection(coll_name)
|
||||
coll.create_index('x') if create_index
|
||||
profile(str) do
|
||||
|
@ -79,7 +79,7 @@ def benchmark(str, n, coll_name, data, create_index=false)
|
|||
td = tm.add do
|
||||
n.times { |i| yield(coll, i) }
|
||||
end
|
||||
report(str, td.real, td.utime)
|
||||
report(str, td.real, td.utime) if verbosity
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -90,8 +90,8 @@ connection = Connection.new(host, port)
|
|||
connection.drop_database("benchmark")
|
||||
@db = connection.db('benchmark')
|
||||
|
||||
def benchmark_insert(desc, coll_name, data)
|
||||
benchmark(desc, PER_TRIAL, coll_name, data) do |coll, i|
|
||||
def benchmark_insert(desc, coll_name, data, verbosity=true)
|
||||
benchmark(desc, PER_TRIAL, coll_name, data, verbosity) do |coll, i|
|
||||
data['x'] = i
|
||||
coll.insert(data)
|
||||
data.delete(:_id)
|
||||
|
@ -109,10 +109,18 @@ end
|
|||
|
||||
print_headings
|
||||
|
||||
if RUBY_PLATFORM =~ /java/
|
||||
puts "***WARMUP***"
|
||||
benchmark_insert('insert (small, no index)', 'small_none', SMALL, false)
|
||||
benchmark_insert('insert (medium, no index)', 'medium_none', MEDIUM, false)
|
||||
benchmark_insert('insert (large, no index)', 'large_none', LARGE, false)
|
||||
puts "***WARMUP***"
|
||||
end
|
||||
benchmark_insert('insert (small, no index)', 'small_none', SMALL)
|
||||
benchmark_insert('insert (medium, no index)', 'medium_none', MEDIUM)
|
||||
benchmark_insert('insert (large, no index)', 'large_none', LARGE)
|
||||
|
||||
|
||||
benchmark_insert_index('insert (small, index)', 'small_indexed', SMALL)
|
||||
benchmark_insert_index('insert (medium, index)', 'medium_indexed', MEDIUM)
|
||||
benchmark_insert_index('insert (large, index)', 'large_indexed', LARGE)
|
||||
|
@ -138,6 +146,11 @@ end
|
|||
benchmark_find_one('find_one (small, no index)', 'small_none', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (medium, no index)', 'medium_none', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (large, no index)', 'large_none', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (small, no index)', 'small_none', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (medium, no index)', 'medium_none', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (large, no index)', 'large_none', PER_TRIAL / 2)
|
||||
|
||||
|
||||
|
||||
benchmark_find_one('find_one (small, indexed)', 'small_indexed', PER_TRIAL / 2)
|
||||
benchmark_find_one('find_one (medium, indexed)', 'medium_indexed', PER_TRIAL / 2)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -60,6 +60,7 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
_nameStack.clear();
|
||||
}
|
||||
|
||||
// Note: this actually creates an OrderedHash.
|
||||
public RubyHash createHash() {
|
||||
RubyHash h = (RubyHash)JavaEmbedUtils.invokeMethod(_runtime, _rbclsOrderedHash, "new",
|
||||
new Object[] { }, Object.class);
|
||||
|
@ -108,6 +109,8 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
_stack.addLast( (RubyObject)hash );
|
||||
}
|
||||
|
||||
// Note: we use []= because we're dealing with an OrderedHash, which in 1.8
|
||||
// doesn't have an internal JRuby representation.
|
||||
public void writeRubyHash(String key, RubyHash hash, IRubyObject obj) {
|
||||
RubyString rkey = _runtime.newString(key);
|
||||
JavaEmbedUtils.invokeMethod(_runtime, hash, "[]=",
|
||||
|
@ -115,9 +118,8 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
}
|
||||
|
||||
public void writeRubyArray(String key, RubyArray array, IRubyObject obj) {
|
||||
Long rkey = Long.parseLong(key);
|
||||
RubyFixnum index = new RubyFixnum(_runtime, rkey);
|
||||
array.aset((IRubyObject)index, obj);
|
||||
Long index = Long.parseLong(key);
|
||||
array.store(index, obj);
|
||||
}
|
||||
|
||||
public void arrayStart(String key){
|
||||
|
@ -281,7 +283,7 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
RubyArray result = RubyArray.newArray( _runtime, b.length );
|
||||
|
||||
for ( int i=0; i<b.length; i++ ) {
|
||||
result.aset( RubyNumeric.dbl2num( _runtime, (double)i ), RubyNumeric.dbl2num( _runtime, (double)b[i] ) );
|
||||
result.store( i, _runtime.newFixnum(b[i]) );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -313,8 +315,7 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
if(current instanceof RubyArray) {
|
||||
RubyArray a = (RubyArray)current;
|
||||
Long n = Long.parseLong(name);
|
||||
RubyFixnum index = new RubyFixnum(_runtime, n);
|
||||
a.aset((IRubyObject)index, (IRubyObject)o);
|
||||
a.store(n, (IRubyObject)o);
|
||||
}
|
||||
else {
|
||||
RubyString rkey = RubyString.newString(_runtime, name);
|
||||
|
@ -322,11 +323,11 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
new Object[] { (IRubyObject)rkey, o }, Object.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected RubyObject cur(){
|
||||
return _stack.getLast();
|
||||
}
|
||||
|
||||
|
||||
public Object get(){
|
||||
return _root;
|
||||
}
|
||||
|
@ -339,22 +340,6 @@ public class RubyBSONCallback implements BSONCallback {
|
|||
return _stack.size() < 1;
|
||||
}
|
||||
|
||||
// Helper method for checking whether a Ruby hash has a certain key.
|
||||
private boolean _rbHashHasKey(RubyHash hash, String key) {
|
||||
RubyBoolean b = hash.has_key_p( _runtime.newString( key ) );
|
||||
return b == _runtime.getTrue();
|
||||
}
|
||||
|
||||
// Helper method for getting a value from a Ruby hash.
|
||||
private IRubyObject _rbHashGet(RubyHash hash, Object key) {
|
||||
if (key instanceof String) {
|
||||
return hash.op_aref( _runtime.getCurrentContext(), _runtime.newString((String)key) );
|
||||
}
|
||||
else {
|
||||
return hash.op_aref( _runtime.getCurrentContext(), (RubyObject)key );
|
||||
}
|
||||
}
|
||||
|
||||
static final HashMap<String, Object> _getRuntimeCache(Ruby runtime) {
|
||||
// each JRuby runtime may have different objects for these constants,
|
||||
// so cache them separately for each runtime
|
||||
|
|
Binary file not shown.
|
@ -19,6 +19,7 @@ import org.bson.BSONEncoder;
|
|||
|
||||
import org.jruby.javasupport.JavaEmbedUtils;
|
||||
import org.jruby.javasupport.JavaUtil;
|
||||
import org.jruby.java.proxies.JavaProxy;
|
||||
|
||||
import org.jruby.*;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
|
@ -225,20 +226,8 @@ public class RubyBSONEncoder extends BSONEncoder {
|
|||
if ( val instanceof String )
|
||||
putString(name, val.toString() );
|
||||
|
||||
// TODO: Clean up
|
||||
else if ( val instanceof Number ) {
|
||||
if ( val instanceof Double ) {
|
||||
putNumber(name, (Number)val);
|
||||
}
|
||||
else {
|
||||
long jval = ((Number)val).longValue();
|
||||
if (jval > Integer.MIN_VALUE && jval < Integer.MAX_VALUE) {
|
||||
putNumber(name, (int)jval );
|
||||
}
|
||||
else
|
||||
putNumber(name, (Number)jval );
|
||||
}
|
||||
}
|
||||
else if ( val instanceof Number )
|
||||
putNumber(name, (Number)val);
|
||||
|
||||
else if ( val instanceof Boolean )
|
||||
putBoolean(name, (Boolean)val);
|
||||
|
@ -265,7 +254,6 @@ public class RubyBSONEncoder extends BSONEncoder {
|
|||
putSymbol(name, new Symbol(val.toString()));
|
||||
}
|
||||
|
||||
// TODO: Clean up
|
||||
else if ( val instanceof RubyFixnum ) {
|
||||
long jval = ((RubyFixnum)val).getLongValue();
|
||||
if (jval >= Integer.MIN_VALUE && jval <= Integer.MAX_VALUE) {
|
||||
|
@ -275,12 +263,22 @@ public class RubyBSONEncoder extends BSONEncoder {
|
|||
putNumber(name, (Number)jval );
|
||||
}
|
||||
|
||||
// TODO: Clean up
|
||||
else if ( val instanceof RubyFloat ) {
|
||||
double jval = ((RubyFloat)val).getValue();
|
||||
putNumber(name, (Number)jval );
|
||||
}
|
||||
|
||||
else if ( val instanceof JavaProxy ) {
|
||||
Object obj = ((JavaProxy)val).getObject();
|
||||
if ( obj instanceof ArrayList ) {
|
||||
putIterable( name, ((ArrayList)obj));
|
||||
}
|
||||
else {
|
||||
_rbRaise( (RubyClass)_rbclsInvalidDocument,
|
||||
"Got a JavaProxy object which can't be serialized as a BSON type." );
|
||||
}
|
||||
}
|
||||
|
||||
else if ( val instanceof RubyNil )
|
||||
putNull(name);
|
||||
|
||||
|
@ -316,6 +314,9 @@ public class RubyBSONEncoder extends BSONEncoder {
|
|||
else if( klass.equals( "BSON::ObjectID" ) ) {
|
||||
putRubyObjectId(name, (RubyObject)val );
|
||||
}
|
||||
else if( klass.equals( "Java::JavaUtil::ArrayList" ) ) {
|
||||
putIterable(name, (Iterable)val );
|
||||
}
|
||||
else if ( klass.equals( "BSON::Code" ) ) {
|
||||
putRubyCodeWScope(name, (RubyObject)val );
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,379 @@
|
|||
// BSON Callback
|
||||
// RubyBSONCallback.java
|
||||
package org.jbson;
|
||||
|
||||
import org.jruby.*;
|
||||
import org.jruby.util.ByteList;
|
||||
import org.jruby.RubyString;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
import org.jruby.runtime.Block;
|
||||
import org.jruby.runtime.CallType;
|
||||
import org.jruby.runtime.callsite.CacheEntry;
|
||||
|
||||
import org.jruby.javasupport.JavaEmbedUtils;
|
||||
import org.jruby.javasupport.JavaUtil;
|
||||
|
||||
import org.jruby.parser.ReOptions;
|
||||
|
||||
import org.jruby.RubyArray;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
import org.bson.*;
|
||||
import org.bson.types.*;
|
||||
|
||||
public class RubyBSONJavaCallback implements BSONCallback {
|
||||
|
||||
private RubyHash _root;
|
||||
private RubyModule _rbclsOrderedHash;
|
||||
private RubyModule _rbclsObjectId;
|
||||
private RubyModule _rbclsBinary;
|
||||
private RubyModule _rbclsMinKey;
|
||||
private RubyModule _rbclsMaxKey;
|
||||
private RubyModule _rbclsDBRef;
|
||||
private RubyModule _rbclsCode;
|
||||
private final LinkedList<Object> _stack = new LinkedList<Object>();
|
||||
private final LinkedList<String> _nameStack = new LinkedList<String>();
|
||||
private Ruby _runtime;
|
||||
static final HashMap<Ruby, HashMap> _runtimeCache = new HashMap<Ruby, HashMap>();
|
||||
|
||||
public RubyBSONJavaCallback(Ruby runtime) {
|
||||
_runtime = runtime;
|
||||
_rbclsOrderedHash = _lookupConstant( _runtime, "BSON::OrderedHash" );
|
||||
_rbclsBinary = _lookupConstant( _runtime, "BSON::Binary" );
|
||||
_rbclsDBRef = _lookupConstant( _runtime, "BSON::DBRef" );
|
||||
_rbclsCode = _lookupConstant( _runtime, "BSON::Code" );
|
||||
_rbclsMinKey = _lookupConstant( _runtime, "BSON::MinKey" );
|
||||
_rbclsMaxKey = _lookupConstant( _runtime, "BSON::MaxKey" );
|
||||
_rbclsObjectId = _lookupConstant( _runtime, "BSON::ObjectId");
|
||||
}
|
||||
|
||||
public BSONCallback createBSONCallback(){
|
||||
return new RubyBSONCallback(_runtime);
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
_root = null;
|
||||
_stack.clear();
|
||||
_nameStack.clear();
|
||||
}
|
||||
|
||||
public RubyHash createHash() {
|
||||
RubyHash h = (RubyHash)JavaEmbedUtils.invokeMethod(_runtime, _rbclsOrderedHash, "new",
|
||||
new Object[] { }, Object.class);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
public Object create( boolean array , List<String> path ){
|
||||
if ( array )
|
||||
return new ArrayList<Object>();
|
||||
return createHash();
|
||||
}
|
||||
|
||||
public void objectStart(){
|
||||
if ( _stack.size() > 0 ) {
|
||||
throw new IllegalStateException( "something is wrong" );
|
||||
}
|
||||
|
||||
_root = createHash();
|
||||
_stack.add(_root);
|
||||
}
|
||||
|
||||
public void objectStart(boolean f) {
|
||||
objectStart();
|
||||
}
|
||||
|
||||
public void objectStart(String key){
|
||||
RubyHash hash = createHash();
|
||||
|
||||
_nameStack.addLast( key );
|
||||
|
||||
Object lastObject = _stack.getLast();
|
||||
|
||||
// Yes, this is a bit hacky.
|
||||
if(lastObject instanceof RubyHash) {
|
||||
writeRubyHash(key, (RubyHash)lastObject, (IRubyObject)hash);
|
||||
}
|
||||
else {
|
||||
((ArrayList)lastObject).add(Integer.parseInt(key), hash);
|
||||
//writeRubyArray(key, (RubyArray)lastObject, (IRubyObject)hash);
|
||||
}
|
||||
|
||||
_stack.addLast( (RubyObject)hash );
|
||||
}
|
||||
|
||||
public void writeRubyHash(String key, RubyHash hash, Object obj) {
|
||||
RubyString rkey = _runtime.newString(key);
|
||||
JavaEmbedUtils.invokeMethod(_runtime, hash, "[]=",
|
||||
new Object[] { (IRubyObject)rkey, obj }, Object.class);
|
||||
}
|
||||
|
||||
public void writeRubyArray(String key, RubyArray array, IRubyObject obj) {
|
||||
Long rkey = Long.parseLong(key);
|
||||
RubyFixnum index = new RubyFixnum(_runtime, rkey);
|
||||
array.aset((IRubyObject)index, obj);
|
||||
}
|
||||
|
||||
public void arrayStart(String key){
|
||||
ArrayList<Object> array = new ArrayList<Object>();
|
||||
|
||||
Object lastObject = _stack.getLast();
|
||||
_nameStack.addLast( key );
|
||||
|
||||
if(lastObject instanceof RubyHash) {
|
||||
writeRubyHash(key, (RubyHash)lastObject, array);
|
||||
}
|
||||
else {
|
||||
((ArrayList)lastObject).add(Integer.parseInt(key), array);
|
||||
}
|
||||
|
||||
_stack.addLast( array );
|
||||
}
|
||||
|
||||
public Object objectDone(){
|
||||
Object o =_stack.removeLast();
|
||||
if ( _nameStack.size() > 0 )
|
||||
_nameStack.removeLast();
|
||||
else if ( _stack.size() > 0 ) {
|
||||
throw new IllegalStateException( "something is wrong" );
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// Not used by Ruby decoder
|
||||
public void arrayStart(){
|
||||
}
|
||||
|
||||
public Object arrayDone(){
|
||||
return objectDone();
|
||||
}
|
||||
|
||||
public void gotNull( String name ){
|
||||
_put(name, null);
|
||||
}
|
||||
|
||||
// Undefined should be represented as a lack of key / value.
|
||||
public void gotUndefined( String name ){
|
||||
}
|
||||
|
||||
// TODO: Handle this
|
||||
public void gotUUID( String name , long part1, long part2) {
|
||||
//_put( name , new UUID(part1, part2) );
|
||||
}
|
||||
|
||||
public void gotCode( String name , String code ){
|
||||
Object rb_code_obj = JavaEmbedUtils.invokeMethod(_runtime, _rbclsCode,
|
||||
"new", new Object[] { code }, Object.class);
|
||||
_put( name , (RubyObject)rb_code_obj );
|
||||
}
|
||||
|
||||
public void gotCodeWScope( String name , String code , Object scope ){
|
||||
Object rb_code_obj = JavaEmbedUtils.invokeMethod(_runtime, _rbclsCode,
|
||||
"new", new Object[] { code, (RubyHash)scope }, Object.class);
|
||||
|
||||
_put( name , (RubyObject)rb_code_obj );
|
||||
}
|
||||
|
||||
public void gotMinKey( String name ){
|
||||
Object minkey = JavaEmbedUtils.invokeMethod(_runtime, _rbclsMinKey, "new", new Object[] {}, Object.class);
|
||||
|
||||
_put( name, (RubyObject)minkey);
|
||||
}
|
||||
|
||||
public void gotMaxKey( String name ){
|
||||
Object maxkey = JavaEmbedUtils.invokeMethod(_runtime, _rbclsMaxKey, "new", new Object[] {}, Object.class);
|
||||
|
||||
_put( name, (RubyObject)maxkey);
|
||||
}
|
||||
|
||||
public void gotBoolean( String name , boolean v ){
|
||||
_put(name , v);
|
||||
}
|
||||
|
||||
public void gotDouble( String name , double v ){
|
||||
_put(name , v);
|
||||
}
|
||||
|
||||
public void gotInt( String name , int v ){
|
||||
_put(name , v);
|
||||
}
|
||||
|
||||
public void gotLong( String name , long v ){
|
||||
_put(name , v);
|
||||
}
|
||||
|
||||
public void gotDate( String name , long millis ){
|
||||
RubyTime time = RubyTime.newTime(_runtime, millis).gmtime();
|
||||
_put( name , time );
|
||||
}
|
||||
|
||||
public void gotRegex( String name , String pattern , String flags ){
|
||||
int f = 0;
|
||||
ByteList b = new ByteList(pattern.getBytes());
|
||||
|
||||
if(flags.contains("i")) {
|
||||
f = f | ReOptions.RE_OPTION_IGNORECASE;
|
||||
}
|
||||
if(flags.contains("m")) {
|
||||
f = f | ReOptions.RE_OPTION_MULTILINE;
|
||||
}
|
||||
if(flags.contains("x")) {
|
||||
f = f | ReOptions.RE_OPTION_EXTENDED;
|
||||
}
|
||||
|
||||
_put( name , RubyRegexp.newRegexp(_runtime, b, f) );
|
||||
}
|
||||
|
||||
public void gotString( String name , String v ){
|
||||
_put( name , v );
|
||||
}
|
||||
|
||||
public void gotSymbol( String name , String v ){
|
||||
ByteList bytes = new ByteList(v.getBytes());
|
||||
RubySymbol symbol = _runtime.getSymbolTable().getSymbol(bytes);
|
||||
_put( name , symbol );
|
||||
}
|
||||
|
||||
// Timestamp is currently rendered in Ruby as a two-element array.
|
||||
public void gotTimestamp( String name , int time , int inc ){
|
||||
RubyFixnum rtime = RubyFixnum.newFixnum( _runtime, time );
|
||||
RubyFixnum rinc = RubyFixnum.newFixnum( _runtime, inc );
|
||||
RubyObject[] args = new RubyObject[2];
|
||||
args[0] = rinc;
|
||||
args[1] = rtime;
|
||||
|
||||
RubyArray result = RubyArray.newArray( _runtime, args );
|
||||
|
||||
_put ( name , result );
|
||||
}
|
||||
|
||||
public void gotObjectId( String name , ObjectId id ){
|
||||
IRubyObject arg = (IRubyObject)RubyString.newString(_runtime, id.toString());
|
||||
// //System.out.println(id.toByteArray().length);
|
||||
// byte[] b = id.toByteArray();
|
||||
// RubyArray a = _runtime.newArray();
|
||||
// for(int i=0; i < b.length; i++) {
|
||||
// System.out.println(b[i]);
|
||||
// a.append(_runtime.newFixnum(b[i]));
|
||||
// }
|
||||
Object[] args = new Object[] { arg };
|
||||
|
||||
Object result = JavaEmbedUtils.invokeMethod(_runtime, _rbclsObjectId, "from_string", args, Object.class);
|
||||
|
||||
_put( name, (RubyObject)result );
|
||||
}
|
||||
|
||||
// TODO: Incredibly annoying to deserialize to a Ruby DBRef. Might just
|
||||
// stop supporting this altogether in the driver.
|
||||
public void gotDBRef( String name , String ns , ObjectId id ){
|
||||
// _put( name , new BasicBSONObject( "$ns" , ns ).append( "$id" , id ) );
|
||||
}
|
||||
|
||||
// TODO: I know that this is horrible. To be optimized.
|
||||
private RubyArray ja2ra( byte[] b ) {
|
||||
RubyArray result = RubyArray.newArray( _runtime, b.length );
|
||||
|
||||
for ( int i=0; i<b.length; i++ ) {
|
||||
result.aset( RubyNumeric.dbl2num( _runtime, (double)i ), RubyNumeric.dbl2num( _runtime, (double)b[i] ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void gotBinaryArray( String name , byte[] b ) {
|
||||
RubyArray a = ja2ra( b );
|
||||
|
||||
Object[] args = new Object[] { a, 2 };
|
||||
|
||||
Object result = JavaEmbedUtils.invokeMethod(_runtime, _rbclsBinary, "new", args, Object.class);
|
||||
|
||||
_put( name, (RubyObject)result );
|
||||
}
|
||||
|
||||
// TODO: fix abs stuff here. some kind of bad type issue
|
||||
public void gotBinary( String name , byte type , byte[] data ){
|
||||
RubyArray a = ja2ra( data );
|
||||
|
||||
Object[] args = new Object[] { a, RubyFixnum.newFixnum(_runtime, Math.abs( type )) };
|
||||
|
||||
Object result = JavaEmbedUtils.invokeMethod(_runtime, _rbclsBinary, "new", args, Object.class);
|
||||
|
||||
_put( name, (RubyObject)result );
|
||||
}
|
||||
|
||||
protected void _put( String name , Object o ){
|
||||
Object current = cur();
|
||||
if(current instanceof ArrayList) {
|
||||
((ArrayList)current).add(Integer.parseInt(name), (Object)o);
|
||||
//RubyArray a = (RubyArray)current;
|
||||
//Long n = Long.parseLong(name);
|
||||
//RubyFixnum index = new RubyFixnum(_runtime, n);
|
||||
//a.aset((IRubyObject)index, o);
|
||||
}
|
||||
else {
|
||||
RubyString rkey = RubyString.newString(_runtime, name);
|
||||
JavaEmbedUtils.invokeMethod(_runtime, current, "[]=",
|
||||
new Object[] { (IRubyObject)rkey, o }, Object.class);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object cur(){
|
||||
return _stack.getLast();
|
||||
}
|
||||
|
||||
public Object get(){
|
||||
return _root;
|
||||
}
|
||||
|
||||
protected void setRoot(RubyHash o) {
|
||||
_root = o;
|
||||
}
|
||||
|
||||
protected boolean isStackEmpty() {
|
||||
return _stack.size() < 1;
|
||||
}
|
||||
|
||||
// Helper method for checking whether a Ruby hash has a certain key.
|
||||
private boolean _rbHashHasKey(RubyHash hash, String key) {
|
||||
RubyBoolean b = hash.has_key_p( _runtime.newString( key ) );
|
||||
return b == _runtime.getTrue();
|
||||
}
|
||||
|
||||
// Helper method for getting a value from a Ruby hash.
|
||||
private IRubyObject _rbHashGet(RubyHash hash, Object key) {
|
||||
if (key instanceof String) {
|
||||
return hash.op_aref( _runtime.getCurrentContext(), _runtime.newString((String)key) );
|
||||
}
|
||||
else {
|
||||
return hash.op_aref( _runtime.getCurrentContext(), (RubyObject)key );
|
||||
}
|
||||
}
|
||||
|
||||
static final HashMap<String, Object> _getRuntimeCache(Ruby runtime) {
|
||||
// each JRuby runtime may have different objects for these constants,
|
||||
// so cache them separately for each runtime
|
||||
@SuppressWarnings("unchecked") // aargh! Java!
|
||||
HashMap<String, Object> cache = _runtimeCache.get( runtime );
|
||||
|
||||
if(cache == null) {
|
||||
cache = new HashMap<String, Object>();
|
||||
_runtimeCache.put( runtime, cache );
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
static final RubyModule _lookupConstant(Ruby runtime, String name)
|
||||
{
|
||||
HashMap<String, Object> cache = _getRuntimeCache( runtime );
|
||||
RubyModule module = (RubyModule) cache.get( name );
|
||||
|
||||
if(module == null && !cache.containsKey( name )) {
|
||||
module = runtime.getClassFromPath( name );
|
||||
cache.put( (String)name, (Object)module );
|
||||
}
|
||||
return module;
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ module BSON
|
|||
|
||||
def self.serialize(obj, check_keys=false, move_id=false)
|
||||
raise InvalidDocument, "BSON_JAVA.serialize takes a Hash" unless obj.is_a?(Hash)
|
||||
enc = get_encoder# Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime)
|
||||
enc = Java::OrgJbson::RubyBSONEncoder.new(JRuby.runtime)
|
||||
ByteBuffer.new(enc.encode(obj))
|
||||
end
|
||||
|
||||
|
@ -17,11 +17,8 @@ module BSON
|
|||
end
|
||||
|
||||
def self.deserialize(buf)
|
||||
if buf.is_a? String
|
||||
buf = ByteBuffer.new(buf) if buf
|
||||
end
|
||||
dec = get_decoder
|
||||
callback = Java::OrgJbson::RubyBSONCallback.new(JRuby.runtime)
|
||||
dec = Java::OrgBson::BSONDecoder.new
|
||||
callback = Java::OrgJbson::RubyBSONJavaCallback.new(JRuby.runtime)
|
||||
dec.decode(buf.to_s.to_java_bytes, callback)
|
||||
callback.get
|
||||
end
|
||||
|
|
|
@ -44,6 +44,8 @@ module BSON
|
|||
@data = data || generate
|
||||
end
|
||||
|
||||
attr_accessor :data
|
||||
|
||||
# Determine if the supplied string is legal. Legal strings will
|
||||
# consist of 24 hexadecimal characters.
|
||||
#
|
||||
|
@ -132,6 +134,13 @@ module BSON
|
|||
str
|
||||
end
|
||||
|
||||
def to_e
|
||||
@data.each do |i|
|
||||
print i
|
||||
print ' '
|
||||
end
|
||||
end
|
||||
|
||||
def inspect
|
||||
"BSON::ObjectId('#{to_s}')"
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ class BSONTest < Test::Unit::TestCase
|
|||
|
||||
def setup
|
||||
@encoder = BSON::BSON_JAVA
|
||||
@decoder = BSON::BSON_RUBY#BSON::BSON_JAVA
|
||||
@decoder = BSON::BSON_JAVA
|
||||
end
|
||||
|
||||
def assert_doc_pass(doc, options={})
|
||||
|
@ -338,13 +338,16 @@ class BSONTest < Test::Unit::TestCase
|
|||
assert_doc_pass(doc)
|
||||
end
|
||||
|
||||
def test_timestamp
|
||||
val = {"test" => [4, 20]}
|
||||
assert_equal val, @decoder.deserialize([0x13, 0x00, 0x00, 0x00,
|
||||
0x11, 0x74, 0x65, 0x73,
|
||||
0x74, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x14, 0x00,
|
||||
0x00, 0x00, 0x00])
|
||||
if !(RUBY_PLATFORM =~ /java/)
|
||||
def test_timestamp
|
||||
val = {"test" => [4, 20]}
|
||||
assert_equal val, @decoder.deserialize([0x13, 0x00, 0x00, 0x00,
|
||||
0x11, 0x74, 0x65, 0x73,
|
||||
0x74, 0x00, 0x04, 0x00,
|
||||
0x00, 0x00, 0x14, 0x00,
|
||||
0x00, 0x00, 0x00])
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def test_overflow
|
||||
|
|
Loading…
Reference in New Issue