Added MongoDB bulk find support to boost performance.

Ylian Saint-Hilaire committed Jan 10, 2021 at 13:57 UTC e9bd782418e00fa19fc13bc630af1ecd1038ffd5
1 file changed +41 -9
db.js
+41 -9
@@ -40,6 +40,8 @@ module.exports.CreateDB = function (parent, func) {
40 obj.pluginsActive = ((parent.config) && (parent.config.settings) && (parent.config.settings.plugins != null) && (parent.config.settings.plugins != false) && ((typeof parent.config.settings.plugins != 'object') || (parent.config.settings.plugins.enabled != false)));
41
42 // MongoDB bulk write state
43 + obj.filePendingGet = null;
44 + obj.filePendingGets = null;
45 obj.filePendingSet = false;
46 obj.filePendingSets = null;
47 obj.filePendingCb = null;
@@ -1056,7 +1058,10 @@ module.exports.CreateDB = function (parent, func) {
1058 if (func != null) { if (obj.filePendingCb == null) { obj.filePendingCb = [ func ]; } else { obj.filePendingCb.push(func); } }
1059 }
1060 };
1059 - obj.Get = function (id, func) {
1061 +
1062 + obj.Get = function (id, func) { // Fast Get operation using a bulk find() to reduce round trips to the database.
1063 + // Encode arguments into return function if any are present.
1064 + var func2 = func;
1065 if (arguments.length > 2) {
1066 var parms = [func];
1067 for (var parmx = 2; parmx < arguments.length; ++parmx) { parms.push(arguments[parmx]); }
@@ -1067,17 +1072,20 @@ module.exports.CreateDB = function (parent, func) {
1072 userCallback.apply(obj, _func2.userArgs);
1073 };
1074 func2.userArgs = parms;
1070 - obj.file.find({ _id: id }).toArray(function (err, docs) {
1071 - if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
1072 - func2(err, performTypedRecordDecrypt(docs));
1073 - });
1075 + }
1076 +
1077 + if (obj.filePendingGets == null) {
1078 + // No pending gets, perform the operation now.
1079 + obj.filePendingGets = {};
1080 + obj.filePendingGets[id] = [func2];
1081 + obj.file.find({ _id: id }).toArray(fileBulkReadCompleted);
1082 } else {
1075 - obj.file.find({ _id: id }).toArray(function (err, docs) {
1076 - if ((docs != null) && (docs.length > 0) && (docs[0].links != null)) { docs[0] = common.unEscapeLinksFieldName(docs[0]); }
1077 - func(err, performTypedRecordDecrypt(docs));
1078 - });
1083 + // Add get to pending list.
1084 + if (obj.filePendingGet == null) { obj.filePendingGet = {}; }
1085 + if (obj.filePendingGet[id] == null) { obj.filePendingGet[id] = [func2]; } else { obj.filePendingGet[id].push(func2); }
1086 }
1087 };
1088 +
1089 obj.GetAll = function (func) { obj.file.find({}).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
1090 obj.GetHash = function (id, func) { obj.file.find({ _id: id }).project({ _id: 0, hash: 1 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
1091 obj.GetAllTypeNoTypeField = function (type, domain, func) { obj.file.find({ type: type, domain: domain }).project({ type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
@@ -1459,6 +1467,30 @@ module.exports.CreateDB = function (parent, func) {
1467 }
1468 }
1469
1470 + // MongoDB pending bulk read operation, perform fast bulk document reads.
1471 + function fileBulkReadCompleted(err, docs) {
1472 + // Send out callbacks with results
1473 + if (docs != null) {
1474 + for (var i in docs) {
1475 + if (docs[i].links != null) { docs[i] = common.unEscapeLinksFieldName(docs[i]); }
1476 + const id = docs[i]._id;
1477 + if (obj.filePendingGets[id] != null) { for (var j in obj.filePendingGets[id]) { obj.filePendingGets[id][j](err, [ docs[i] ]); } delete obj.filePendingGets[id]; }
1478 + }
1479 + }
1480 +
1481 + // If there are not results, send out a null callback
1482 + for (var i in obj.filePendingGets) { for (var j in obj.filePendingGets[i]) { obj.filePendingGets[i][j](err, null); } }
1483 +
1484 + // Move on to process any more pending get operations
1485 + obj.filePendingGets = obj.filePendingGet;
1486 + obj.filePendingGet = null;
1487 + if (obj.filePendingGets != null) {
1488 + var findlist = [];
1489 + for (var i in obj.filePendingGets) { findlist.push(i); }
1490 + obj.file.find({ _id: { $in: findlist } }).toArray(fileBulkReadCompleted);
1491 + }
1492 + }
1493 +
1494 // MongoDB pending bulk write operation, perform fast bulk document replacement.
1495 function fileBulkWriteCompleted() {
1496 // Callbacks