Skip to content

Commit d809e85

Browse files
committed
Working randomObjID & looselyIterateOBjectID implementation (optimization!)
1 parent db2a4d3 commit d809e85

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

src/main/java/picoded/dstack/mongodb/MongoDB_DataObjectMap.java

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.mongodb.client.model.IndexOptions;
3535
import com.mongodb.client.model.Indexes;
3636
import com.mongodb.client.model.FindOneAndUpdateOptions;
37+
import com.mongodb.client.model.Aggregates;
3738

3839
/**
3940
* ## Purpose
@@ -463,6 +464,92 @@ public long queryCount(String whereClause, Object[] whereValues) {
463464
return collection.countDocuments(bsonFilter);
464465
}
465466

467+
//--------------------------------------------------------------------------
468+
//
469+
// Random object and loose iteration support
470+
//
471+
//--------------------------------------------------------------------------
472+
473+
/**
474+
* Gets and return a random object ID
475+
*
476+
* @return Random object ID
477+
**/
478+
public String randomObjectID() {
479+
// Aggregation sample
480+
Document doc = collection.aggregate(Arrays.asList(Aggregates.sample(1))).first();
481+
if( doc != null ) {
482+
return doc.getString("_oid");
483+
}
484+
return null;
485+
}
486+
487+
/**
488+
* Gets and return the next object ID key for iteration given the current ID,
489+
* null gets the first object in iteration.
490+
*
491+
* It is important to note actual iteration sequence is implementation dependent.
492+
* And does not gurantee that newly added objects, after the iteration started,
493+
* will be part of the chain of results.
494+
*
495+
* Similarly if the currentID was removed midway during iteration, the return
496+
* result is not properly defined, and can either be null, or the closest object matched
497+
* or even a random object.
498+
*
499+
* It is however guranteed, if no changes / writes occurs. A complete iteration
500+
* will iterate all existing objects.
501+
*
502+
* The larger intention of this function, is to allow a background thread to slowly
503+
* iterate across all objects, eventually. With an acceptable margin of loss on,
504+
* recently created/edited object. As these objects will eventually be iterated in
505+
* repeated rounds on subsequent calls.
506+
*
507+
* Due to its roughly random nature in production (with concurrent objects generated)
508+
* and its iterative nature as an eventuality. The phrase looselyIterate was chosen,
509+
* to properly reflect its nature.
510+
*
511+
* Another way to phrase it, in worse case scenerio, its completely random, eventually iterating all objects
512+
* In best case scenerio, it does proper iteration as per normal.
513+
*
514+
* @param Current object ID, can be NULL
515+
*
516+
* @return Next object ID, if found
517+
**/
518+
public String looselyIterateObjectID(String currentID) {
519+
// The query filter to use, use "all" if queryClause is null
520+
Bson bsonFilter = null;
521+
if( currentID == null ) {
522+
// our equivalent of all filter
523+
bsonFilter = Filters.exists("_oid", true);
524+
} else {
525+
// greater then
526+
bsonFilter = Filters.gt("_oid", currentID);
527+
}
528+
529+
// Lets fetch the data, for the various _oid
530+
FindIterable<Document> search = collection.find(bsonFilter);
531+
search = search.projection(Projections.include("_oid"));
532+
533+
// The final sorting BSON
534+
Document sortBson = new Document();
535+
sortBson.append("_oid", 1);
536+
537+
// Apply the sorting
538+
search.sort( sortBson );
539+
540+
// Apply the limit of 1
541+
search.limit(1);
542+
543+
// Get the Document object
544+
Document resObj = search.first();
545+
if (resObj == null) {
546+
return null;
547+
}
548+
549+
// Return the next _oid
550+
return resObj.getString("_oid");
551+
}
552+
466553
//--------------------------------------------------------------------------
467554
//
468555
// Maintenance calls

0 commit comments

Comments
 (0)