Skip to content

Commit

Permalink
(#2839) - Implement revs_limit
Browse files Browse the repository at this point in the history
  • Loading branch information
daleharvey committed Nov 14, 2015
1 parent 7ce4b66 commit 5832d03
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs/_includes/api/create_database.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

* `auto_compaction`: This turns on auto compaction, which means `compact()` is called after every change to the database. Defaults to `false`.
* `adapter`: One of `'idb'`, `'leveldb'`, `'websql'`, or `'http'`. If unspecified, PouchDB will infer this automatically, preferring IndexedDB to WebSQL in browsers that support both (i.e. Chrome, Opera and Android 4.4+).
* `revs_limit`: Specify how many old revisions we keep track (not a copy) of.

**Options for remote databases:**

Expand Down
6 changes: 3 additions & 3 deletions lib/adapters/idb/bulkDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var encodeMetadata = idbUtils.encodeMetadata;
var idbError = idbUtils.idbError;
var openTransactionSafely = idbUtils.openTransactionSafely;

function idbBulkDocs(req, opts, api, idb, Changes, callback) {
function idbBulkDocs(dbOpts, req, opts, api, idb, Changes, callback) {
var docInfos = req.docs;
var txn;
var docStore;
Expand Down Expand Up @@ -91,8 +91,8 @@ function idbBulkDocs(req, opts, api, idb, Changes, callback) {
}

function idbProcessDocs() {

processDocs(docInfos, api, fetchedDocs, txn, results, writeDoc, opts);
processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs,
txn, results, writeDoc, opts);
}

function fetchExistingDocs() {
Expand Down
4 changes: 2 additions & 2 deletions lib/adapters/idb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,8 @@ function init(api, opts, callback) {
callback(null, api._meta.instanceId);
});

api._bulkDocs = function idb_bulkDocs(req, opts, callback) {
idbBulkDocs(req, opts, api, idb, IdbPouch.Changes, callback);
api._bulkDocs = function idb_bulkDocs(req, reqOpts, callback) {
idbBulkDocs(opts, req, reqOpts, api, idb, IdbPouch.Changes, callback);
};

// First we look up the metadata in the ids database, then we fetch the
Expand Down
5 changes: 3 additions & 2 deletions lib/adapters/leveldb/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ function LevelPouch(opts, callback) {
var api = this;
var instanceId;
var stores = {};
var revLimit = opts.revs_limit;
var db;
var name = opts.name;
if (typeof opts.createIfMissing === 'undefined') {
Expand Down Expand Up @@ -822,8 +823,8 @@ function LevelPouch(opts, callback) {
if (err) {
return callback(err);
}
processDocs(docInfos, api, fetchedDocs, txn, results, writeDoc,
opts, finish);
processDocs(revLimit, docInfos, api, fetchedDocs, txn, results,
writeDoc, opts, finish);
});
});
});
Expand Down
5 changes: 3 additions & 2 deletions lib/adapters/websql/bulkDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var stringifyDoc = websqlUtils.stringifyDoc;
var compactRevs = websqlUtils.compactRevs;
var unknownError = websqlUtils.websqlError;

function websqlBulkDocs(req, opts, api, db, Changes, callback) {
function websqlBulkDocs(dbOpts, req, opts, api, db, Changes, callback) {
var newEdits = opts.new_edits;
var userDocs = req.docs;

Expand Down Expand Up @@ -257,7 +257,8 @@ function websqlBulkDocs(req, opts, api, db, Changes, callback) {
}

function websqlProcessDocs() {
processDocs(docInfos, api, fetchedDocs, tx, results, writeDoc, opts);
processDocs(dbOpts.revs_limit, docInfos, api, fetchedDocs, tx,
results, writeDoc, opts);
}

function fetchExistingDocs(callback) {
Expand Down
4 changes: 2 additions & 2 deletions lib/adapters/websql/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -549,8 +549,8 @@ function WebSqlPouch(opts, callback) {
}, websqlError(callback));
};

api._bulkDocs = function (req, opts, callback) {
websqlBulkDocs(req, opts, api, db, WebSqlPouch.Changes, callback);
api._bulkDocs = function (req, reqOpts, callback) {
websqlBulkDocs(opts, req, reqOpts, api, db, WebSqlPouch.Changes, callback);
};

api._get = function (id, opts, callback) {
Expand Down
11 changes: 7 additions & 4 deletions lib/deps/docs/processDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ var merge = require('../../deps/merge');
var collections = require('pouchdb-collections');
var Map = collections.Map;

function processDocs(docInfos, api, fetchedDocs, tx, results, writeDoc, opts,
overallCallback) {
function processDocs(revLimit, docInfos, api, fetchedDocs, tx, results,
writeDoc, opts, overallCallback) {

// Default to 1000 locally
revLimit = revLimit || 1000;

function insertDoc(docInfo, resultsIdx, callback) {
// Cant insert new deleted documents
Expand Down Expand Up @@ -77,11 +80,11 @@ function processDocs(docInfos, api, fetchedDocs, tx, results, writeDoc, opts,
var resultsIdx = value[1];

if (fetchedDocs.has(id)) {
updateDoc(fetchedDocs.get(id), currentDoc, results,
updateDoc(revLimit, fetchedDocs.get(id), currentDoc, results,
resultsIdx, docWritten, writeDoc, newEdits);
} else {
// Ensure stemming applies to new writes as well
var merged = merge([], currentDoc.metadata.rev_tree[0], 1000);
var merged = merge([], currentDoc.metadata.rev_tree[0], revLimit);
currentDoc.metadata.rev_tree = merged.tree;
insertDoc(currentDoc, resultsIdx, docWritten);
}
Expand Down
7 changes: 4 additions & 3 deletions lib/deps/docs/updateDoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ var calculateWinningRev = require('../../deps/merge/winningRev');
var merge = require('../../deps/merge');
var revExists = require('../../deps/merge/revExists');

function updateDoc(prev, docInfo, results, i, cb, writeDoc, newEdits) {
function updateDoc(revLimit, prev, docInfo, results,
i, cb, writeDoc, newEdits) {

if (revExists(prev.rev_tree, docInfo.metadata.rev)) {
results[i] = docInfo;
Expand All @@ -29,7 +30,7 @@ function updateDoc(prev, docInfo, results, i, cb, writeDoc, newEdits) {
docInfo = parseDoc(newDoc, newEdits);
}

var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], 1000);
var merged = merge(prev.rev_tree, docInfo.metadata.rev_tree[0], revLimit);

var inConflict = newEdits && (((previouslyDeleted && deleted) ||
(!previouslyDeleted && merged.conflicts !== 'new_leaf') ||
Expand Down Expand Up @@ -70,4 +71,4 @@ function updateDoc(prev, docInfo, results, i, cb, writeDoc, newEdits) {
true, delta, i, cb);
}

module.exports = updateDoc;
module.exports = updateDoc;
39 changes: 39 additions & 0 deletions tests/integration/test.bulk_docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -958,5 +958,44 @@ adapters.forEach(function (adapter) {
});
});

it('2839 implement revs_limit', function (done) {

// We only implement revs_limit locally
if (adapter === 'http') {
return done();
}

var LIMIT = 50;
var db = new PouchDB(dbs.name, {revs_limit: LIMIT});

// simulate 5000 normal commits with two conflicts at the very end
function uuid() {
return PouchDB.utils.uuid(32, 16).toLowerCase();
}

var numRevs = 5000;
var uuids = [];
for (var i = 0; i < numRevs - 1; i++) {
uuids.push(uuid());
}
var conflict1 = 'a' + uuid();
var doc1 = {
_id: 'doc',
_rev: numRevs + '-' + conflict1,
_revisions: {
start: numRevs,
ids: [conflict1].concat(uuids)
}
};

db.bulkDocs([doc1], {new_edits: false}).then(function () {
return db.get('doc', {revs: true});
}).then(function (doc) {
doc._revisions.ids.length.should.equal(LIMIT);
done();
}).catch(done);
});


});
});

2 comments on commit 5832d03

@chino23
Copy link

@chino23 chino23 commented on 5832d03 Dec 8, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the current default set for revs_limit?
and how does that affect performance?

@nolanlawson
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current limit is 1000, and it affects performance if you modify the same document >1000 times.

Please sign in to comment.