Keep an internal counter of the underlying datafile size to compact it when it grows too big

pull/2/head
Louis Chatriot 12 years ago
parent 60621775c0
commit 40ad547dc2
  1. 10
      lib/datastore.js
  2. 94
      test/db.test.js

@ -13,6 +13,8 @@ var fs = require('fs')
function Datastore (filename) { function Datastore (filename) {
this.filename = filename; this.filename = filename;
this.data = []; this.data = [];
this.datafileSize = 0;
} }
@ -34,11 +36,13 @@ Datastore.prototype._loadDatabase = function (cb) {
fs.exists(self.filename, function (exists) { fs.exists(self.filename, function (exists) {
if (!exists) { if (!exists) {
self.data = []; self.data = [];
self.datafileSize = 0;
fs.writeFile(self.filename, '', 'utf8', function (err) { return callback(err); }); fs.writeFile(self.filename, '', 'utf8', function (err) { return callback(err); });
} else { } else {
fs.readFile(self.filename, 'utf8', function (err, rawData) { fs.readFile(self.filename, 'utf8', function (err, rawData) {
if (err) { return callback(err); } if (err) { return callback(err); }
self.data = Datastore.treatRawData(rawData); self.data = Datastore.treatRawData(rawData);
self.datafileSize = self.data.length;
self.persistCachedDatabase(callback); self.persistCachedDatabase(callback);
}); });
} }
@ -130,8 +134,8 @@ Datastore.prototype._insert = function (newDoc, cb) {
if (err) { return callback(err); } if (err) { return callback(err); }
var insertedDoc = model.deserialize(persistableNewDoc); var insertedDoc = model.deserialize(persistableNewDoc);
self.data.push(insertedDoc); // Make sure the doc is the same on the disk and in memory self.data.push(insertedDoc);
// Some docs can't be stringified correctly self.datafileSize += 1;
return callback(null, insertedDoc); return callback(null, insertedDoc);
}); });
}; };
@ -200,6 +204,8 @@ Datastore.prototype.persistNewState = function (newDocs, cb) {
, callback = cb || function () {} , callback = cb || function () {}
; ;
self.datafileSize += newDocs.length;
newDocs.forEach(function (doc) { newDocs.forEach(function (doc) {
toPersist += model.serialize(doc) + '\n'; toPersist += model.serialize(doc) + '\n';
}); });

@ -28,6 +28,8 @@ describe('Database', function () {
, function (cb) { , function (cb) {
d.loadDatabase(function (err) { d.loadDatabase(function (err) {
assert.isNull(err); assert.isNull(err);
d.datafileSize.should.equal(0);
d.data.length.should.equal(0);
return cb(); return cb();
}); });
} }
@ -152,6 +154,34 @@ describe('Database', function () {
}); });
}); });
it('datafileSize is the size of the dataset upon a databaseLoad', function (done) {
var now = new Date()
, rawData = model.serialize({ _id: "1", a: 2, ages: [1, 5, 12] }) + '\n' +
model.serialize({ _id: "2", hello: 'world' }) + '\n' +
model.serialize({ _id: "3", nested: { today: now } })
;
d.data.length.should.equal(0);
d.datafileSize.should.equal(0);
fs.writeFile(testDb, rawData, 'utf8', function () {
d.loadDatabase(function () {
d.data.length.should.equal(3);
d.datafileSize.should.equal(3);
d.find({}, function (err, docs) {
docs.sort(function (a, b) { return a._id - b._id; });
docs.length.should.equal(3);
_.isEqual(docs[0], { _id: "1", a: 2, ages: [1, 5, 12] }).should.equal(true);
_.isEqual(docs[1], { _id: "2", hello: 'world' }).should.equal(true);
_.isEqual(docs[2], { _id: "3", nested: { today: now } }).should.equal(true);
done();
});
});
});
});
}); // ==== End of 'Loading the database data from file and persistence' ==== // }); // ==== End of 'Loading the database data from file and persistence' ==== //
@ -270,6 +300,24 @@ describe('Database', function () {
}); });
}); });
it('datafileSize is incremented by 1 upon every insert', function (done) {
d.datafileSize.should.equal(0);
d.data.length.should.equal(0);
d.insert({ a: 3 }, function () {
d.datafileSize.should.equal(1);
d.data.length.should.equal(1);
d.insert({ a: 3 }, function () {
d.datafileSize.should.equal(2);
d.data.length.should.equal(2);
d.insert({ a: 3 }, function () {
d.datafileSize.should.equal(3);
d.data.length.should.equal(3);
done();
});
});
});
});
}); // ==== End of 'Insert' ==== // }); // ==== End of 'Insert' ==== //
@ -817,6 +865,29 @@ describe('Database', function () {
}); });
}); });
it('datafileSize stays correct upon updates', function (done) {
d.insert({ a: 2 }, function () {
d.insert({ a: 3 }, function () {
d.insert({ a: 5 }, function () {
d.datafileSize.should.equal(3);
d.data.length.should.equal(3);
d.update({ a: 3 }, { $set: { a: 4 } }, {}, function () {
d.datafileSize.should.equal(4);
d.data.length.should.equal(3);
d.update({ a: { $in: [2, 4] } }, { $set: { a: 5 } }, { multi: true }, function () {
d.datafileSize.should.equal(6);
d.data.length.should.equal(3);
done();
});
});
});
});
});
});
}); // ==== End of 'Update' ==== // }); // ==== End of 'Update' ==== //
@ -966,6 +1037,29 @@ describe('Database', function () {
}); });
}); });
it('datafileSize stays correct upon removes', function (done) {
d.insert({ a: 2 }, function () {
d.insert({ a: 3 }, function () {
d.insert({ a: 5 }, function () {
d.datafileSize.should.equal(3);
d.data.length.should.equal(3);
d.remove({ a: 3 }, {}, function () {
d.datafileSize.should.equal(4);
d.data.length.should.equal(2);
d.remove({ a: { $in: [2, 5] } }, { multi: true }, function () {
d.datafileSize.should.equal(6);
d.data.length.should.equal(0);
done();
});
});
});
});
});
});
}); // ==== End of 'Remove' ==== // }); // ==== End of 'Remove' ==== //

Loading…
Cancel
Save