Permalink
Browse files

added length and redundantLength

  • Loading branch information...
pathsny committed Apr 21, 2011
1 parent ee5205f commit 93c8d08b6425c69d36bdc2d780514b674bdf8ac5
Showing with 111 additions and 18 deletions.
  1. +24 −16 lib/dirty/dirty.js
  2. +74 −0 test/simple/test-dirty.js
  3. +13 −2 test/system/test-compact.js
View
@@ -18,7 +18,8 @@ var Dirty = exports.Dirty = function(path) {
this._writeStream = null;
this._compactingFilters = [];
this._indexFns = {};
-
+ this._length = 0;
+ this._redundantLength = 0;
this._load();
};
@@ -33,15 +34,20 @@ Dirty.prototype.set = function(key, val, cb) {
} else {
this._queue.push([key, cb]);
}
-
this._maybeFlush();
};
-Dirty.prototype._updateDocs = function(key, val) {
+Dirty.prototype._updateDocs = function(key, val, skipRedundantRows) {
this._updateIndexes(key, val);
+ if (key in this._docs) {
+ this._length--;
+ if (!skipRedundantRows) this._redundantLength++;
+ }
if (val === undefined) {
+ if (!skipRedundantRows) this._redundantLength++;
delete this._docs[key];
} else {
+ this._length++;
this._docs[key] = val;
}
};
@@ -66,8 +72,7 @@ Dirty.prototype._load = function() {
if (!this.path) {
return;
}
-
- var self = this, buffer = '', length = 0;
+ var self = this, buffer = '';
this._readStream = fs.createReadStream(this.path, {
encoding: 'utf-8',
flags: 'r'
@@ -95,15 +100,6 @@ Dirty.prototype._load = function() {
return '';
}
- if (row.val === undefined) {
- if (row.key in self._docs) {
- length--;
- }
- } else {
- if (!(row.key in self._docs)) {
- length++;
- }
- }
self._updateDocs(row.key, row.val);
return '';
});
@@ -112,7 +108,7 @@ Dirty.prototype._load = function() {
if (buffer.length) {
self.emit('error', new Error('Corrupted row at the end of the db: '+buffer));
}
- self.emit('load', length);
+ self.emit('load', self._length);
});
this._recreateWriteStream();
};
@@ -192,6 +188,14 @@ Dirty.prototype.__defineGetter__("_compactPath", function() {
return this.path + ".compact";
});
+Dirty.prototype.__defineGetter__('length', function(){
+ return this._length;
+});
+
+Dirty.prototype.__defineGetter__('redundantLength', function(){
+ return this._redundantLength;
+});
+
Dirty.prototype.compact = function(cb) {
if (this.compacting) return;
var self = this;
@@ -210,6 +214,8 @@ Dirty.prototype._startCompacting = function() {
var self = this;
this._queueBackup = this._queue;
this._queue = [];
+ this._redundantLengthBackup = this._redundantLength;
+ this._redundantLength = 0;
var ws = fs.createWriteStream(this._compactPath, {
encoding: 'utf-8',
flags: 'w'
@@ -238,11 +244,13 @@ Dirty.prototype.on('compacted', function(){
Dirty.prototype.on('compactingError', function(){
this._queue = this._queueBackup.concat(this._queue);
+ this._redundantLength += this._redundantLengthBackup;
this._endCompacting();
});
Dirty.prototype._endCompacting = function() {
this._queueBackup = [];
+ this._redundantLengthBackup = 0;
this.compacting = false;
this._maybeFlush();
};
@@ -260,7 +268,7 @@ Dirty.prototype._writeCompactedData = function(ws) {
if (this._compactingFilters.some(function(filterFn){
return filterFn(k, doc);
})) {
- this._updateDocs(k, undefined);
+ this._updateDocs(k, undefined, true);
continue;
}
bundleStr += JSON.stringify({key: k, val: doc})+'\n';
View
@@ -599,3 +599,77 @@ test(function Indexes(){
})();
});
+test(function length(){
+ (function setup(){
+ dirty.forEach(function(k,v){
+ dirty.rm(k);
+ })
+ assert.equal(0, dirty.length);
+ })();
+
+ (function testAddingAnItemIncreasesLength(){
+ dirty.set('steam',['fire', 'ice']);
+ assert.equal(1, dirty.length);
+ })();
+
+ (function testModifyingAnItemDoesntChangeLength(){
+ dirty.set('steam', ['fire', 'water']);
+ assert.equal(1, dirty.length);
+ })();
+
+ (function testRemovingAnItemReducesLength(){
+ dirty.rm('steam');
+ assert.equal(0, dirty.length);
+ })();
+
+ (function testReAddingADeletedItemIncreasesLength(){
+ dirty.set('steam', ['fire', 'water']);
+ assert.equal(1, dirty.length);
+ })();
+
+ (function testReAddingAnExistingItemDoesNotIncreaseLength(){
+ dirty.set('steam', ['fire', 'water']);
+ assert.equal(1, dirty.length);
+ })();
+})
+
+test(function redundantLength(){
+ var original_length;
+ (function setup(){
+ dirty.forEach(function(k,v){
+ dirty.rm(k);
+ })
+ original_length = dirty.redundantLength;
+ })();
+
+ (function testAddingAnItemDoesNotIncreaseRedundantLength(){
+ dirty.set('arcane','spread');
+ assert.equal(original_length, dirty.redundantLength);
+ })();
+
+ (function testReAddingAnExistingItemIncreasesRedundantLength(){
+ dirty.set('arcane','spread');
+ assert.equal(original_length + 1, dirty.redundantLength);
+ })();
+
+ (function testModifyingAnItemIncreasesRedundantLength(){
+ dirty.set('arcane', 'beam');
+ assert.equal(original_length + 2, dirty.redundantLength);
+ })();
+
+ (function testRemovingAnExistingItemIncreasesRedundantLengthByTwo(){
+ dirty.rm('arcane');
+ assert.equal(original_length + 4, dirty.redundantLength);
+ })();
+
+ (function testRemovingANonExistingItemIncreasesRedundantLength(){
+ dirty.rm('arcane');
+ assert.equal(original_length + 5, dirty.redundantLength);
+ })();
+
+ (function testReAddingADeletedItemDoesNotIncreasRedundantLength(){
+ dirty.set('arcane', 'beam');
+ assert.equal(original_length + 5, dirty.redundantLength);
+ })();
+})
+
@@ -19,18 +19,29 @@ db.on('load', function(){
db.set('green', 'llanowar Elves');
db.set('purple', 'some magic');
db.set('flan', 'is good');
+ assert.equal(7, db.length);
+ assert.equal(0, db.redundantLength);
db.on('drain', function(){
+ db.set('green', 'llanowar Elves');
db.set('green', 'giant growth');
+ db.rm('red');
+ db.rm('red');
+ assert.equal(5, db.redundantLength);
+ db.set('red', 'lightning bolt')
+ assert.equal(7, db.length);
+ assert.equal(5, db.redundantLength);
db.compact();
db.on('compacted', function(){
assert.strictEqual(
fs.readFileSync(DB_FILE, 'utf-8'),
- JSON.stringify({key: 'red', 'val': 'lightning Bolt'})+'\n'+
JSON.stringify({key: 'black', 'val': 'dark ritual'})+'\n'+
JSON.stringify({key: 'blue', 'val': 'ancestral recall'})+'\n'+
JSON.stringify({key: 'white', 'val': 'healing salve'})+'\n'+
- JSON.stringify({key: 'green', 'val': 'giant growth'})+'\n'
+ JSON.stringify({key: 'green', 'val': 'giant growth'})+'\n'+
+ JSON.stringify({key: 'red', 'val': 'lightning bolt'})+'\n'
);
+ assert.equal(5, db.length);
+ assert.equal(0, db.redundantLength);
});
});
});

0 comments on commit 93c8d08

Please sign in to comment.