Skip to content

Commit 2dbbf9d

Browse files
committed
JAVA-505: using cached DBDecoder in most cases to avoid excessive memory allocation caused by too many instances of DefaultDBDecoder being created
1 parent a2273e6 commit 2dbbf9d

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

src/main/com/mongodb/DBCollection.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public final DBObject findOne( Object obj )
329329
* @dochub find
330330
*/
331331
public final DBObject findOne( Object obj, DBObject fields ) {
332-
Iterator<DBObject> iterator = __find(new BasicDBObject("_id", obj), fields, 0, -1, 0, getOptions(), getReadPreference(), _decoderFactory.create() );
332+
Iterator<DBObject> iterator = __find( new BasicDBObject("_id", obj), fields, 0, -1, 0, getOptions(), getReadPreference(), getDecoder() );
333333
return (iterator != null ? iterator.next() : null);
334334
}
335335

@@ -644,14 +644,20 @@ public final DBObject findOne( DBObject o, DBObject fields ) {
644644
* @dochub find
645645
*/
646646
public final DBObject findOne( DBObject o, DBObject fields, ReadPreference readPref ) {
647-
Iterator<DBObject> i = __find( o , fields , 0 , -1 , 0, getOptions(), readPref, _decoderFactory.create() );
647+
Iterator<DBObject> i = __find( o , fields , 0 , -1 , 0, getOptions(), readPref, getDecoder() );
648648
DBObject obj = (i == null ? null : i.next());
649649
if ( obj != null && ( fields != null && fields.keySet().size() > 0 ) ){
650650
obj.markAsPartialObject();
651651
}
652652
return obj;
653653
}
654654

655+
// Only create a new decoder if there is a decoder factory explicitly set on the collection. Otherwise return null
656+
// so that DBPort will use a cached decoder from the default factory.
657+
private DBDecoder getDecoder() {
658+
return _decoderFactory != null ? _decoderFactory.create() : null;
659+
}
660+
655661

656662
/**
657663
* calls {@link DBCollection#apply(com.mongodb.DBObject, boolean)} with ensureID=true
@@ -1143,7 +1149,6 @@ protected DBCollection( DB base , String name ){
11431149
_name = name;
11441150
_fullName = _db.getName() + "." + name;
11451151
_options = new Bytes.OptionHolder( _db._options );
1146-
_decoderFactory = _db.getMongo().getMongoOptions().dbDecoderFactory;
11471152
_encoderFactory = _db.getMongo().getMongoOptions().dbEncoderFactory;
11481153
}
11491154

@@ -1415,24 +1420,39 @@ public int getOptions(){
14151420
return _options.get();
14161421
}
14171422

1423+
/**
1424+
* Set a customer decoder factory for this collection. Set to null to use the default from MongoOptions.
1425+
* @param fact the factory to set.
1426+
*/
14181427
public void setDBDecoderFactory(DBDecoderFactory fact) {
1419-
if (fact == null)
1420-
_decoderFactory = _db.getMongo().getMongoOptions().dbDecoderFactory;
1421-
else
1422-
_decoderFactory = fact;
1428+
_decoderFactory = fact;
14231429
}
14241430

1431+
/**
1432+
* Get the decoder factory for this collection. A null return value means that the default from MongoOptions
1433+
* is being used.
1434+
* @return the factory
1435+
*/
14251436
public DBDecoderFactory getDBDecoderFactory() {
14261437
return _decoderFactory;
14271438
}
14281439

1440+
/**
1441+
* Set a customer encoder factory for this collection. Set to null to use the default from MongoOptions.
1442+
* @param fact the factory to set.
1443+
*/
14291444
public void setDBEncoderFactory(DBEncoderFactory fact) {
14301445
if (fact == null)
14311446
_encoderFactory = _db.getMongo().getMongoOptions().dbEncoderFactory;
14321447
else
14331448
_encoderFactory = fact;
14341449
}
14351450

1451+
/**
1452+
* Get the encoder factory for this collection. A null return value means that the default from MongoOptions
1453+
* is being used.
1454+
* @return the factory
1455+
*/
14361456
public DBEncoderFactory getDBEncoderFactory() {
14371457
return _encoderFactory;
14381458
}

src/main/com/mongodb/DBCursor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ private void _check()
366366
foo.put( "$snapshot", true );
367367
}
368368

369-
_it = _collection.__find( foo, _keysWanted, _skip, _batchSize, _limit , _options , _readPref , _decoderFact.create() );
369+
_it = _collection.__find( foo, _keysWanted, _skip, _batchSize, _limit , _options , _readPref , getDecoder());
370370
}
371371

372372
if ( _it == null ){
@@ -375,6 +375,12 @@ private void _check()
375375
}
376376
}
377377

378+
// Only create a new decoder if there is a decoder factory explicitly set on the collection. Otherwise return null
379+
// so that the collection can use a cached decoder
380+
private DBDecoder getDecoder() {
381+
return _decoderFact != null ? _decoderFact.create() : null;
382+
}
383+
378384
/**
379385
* if there is a hint to use, use it
380386
*/

src/main/com/mongodb/DBPort.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ synchronized CommandResult getLastError( DB db , WriteConcern concern ) throws I
143143

144144
synchronized private Response findOne( DB db , String coll , DBObject q ) throws IOException {
145145
OutMessage msg = OutMessage.query( db._mongo , 0 , db.getName() + "." + coll , 0 , -1 , q , null );
146-
Response res = go( msg , db.getCollection( coll ) , DefaultDBDecoder.FACTORY.create() );
146+
Response res = go( msg , db.getCollection( coll ) , null );
147147
return res;
148148
}
149149

150150
synchronized private Response findOne( String ns , DBObject q ) throws IOException{
151151
OutMessage msg = OutMessage.query( null , 0 , ns , 0 , -1 , q , null );
152-
Response res = go( msg , null , true, null, DefaultDBDecoder.FACTORY.create() );
152+
Response res = go( msg , null , true, null, null );
153153
return res;
154154
}
155155

0 commit comments

Comments
 (0)