Comparing version 0.2.7 to 0.2.8
@@ -42,2 +42,15 @@ // Copyright 2013 The Obvious Corporation. | ||
/** | ||
* Get the number of keys currently in the cache. | ||
* | ||
* Note: this function returns the number of keys that are in the cache | ||
* and taking memory, but some of them might have expired already | ||
* and the reaper will remove them when it runs. | ||
* | ||
* @return {number} The number of keys | ||
*/ | ||
InMemoryCache.prototype.getKeyCount = function () { | ||
return Object.keys(this._data).length | ||
} | ||
/** | ||
* Set how frequently the reaper runs. | ||
@@ -44,0 +57,0 @@ * |
@@ -29,3 +29,3 @@ var util = require('util') | ||
var instanceIndex = this._getIndexOfFirstAvailableInstance(start) | ||
if (this._cacheInstances[instanceIndex]) return this._cacheInstances[instanceIndex].instance | ||
if (instanceIndex !== undefined) return this._cacheInstances[instanceIndex].instance | ||
@@ -36,2 +36,3 @@ return null | ||
RedundantCacheGroup.prototype._getIndexOfFirstAvailableInstance = function (start) { | ||
for (var i = (start || 0); i < this._cacheInstances.length; i++) { | ||
@@ -80,35 +81,44 @@ var instance = this._cacheInstances[i].instance | ||
RedundantCacheGroup.prototype.mget = function (keys) { | ||
var instanceIndex = this._getIndexOfFirstAvailableInstance() | ||
RedundantCacheGroup.prototype.mget = function (keys, start) { | ||
var instanceIndex = this._getIndexOfFirstAvailableInstance(start || 0) | ||
var self = this | ||
if (instanceIndex == null) return Q.resolve([]) | ||
// try the first cache | ||
var ret = this._getAvailableInstance(instanceIndex).mget(keys) | ||
var nextInstance = this._getAvailableInstance(instanceIndex + 1) | ||
return this._getAvailableInstance(instanceIndex).mget(keys) | ||
.then(function (res) { | ||
var nextInstanceIndex = self._getIndexOfFirstAvailableInstance(instanceIndex + 1) | ||
var promises = [] | ||
return ret.then(function (res) { | ||
for (var i = 0; i < res.length; i++) { | ||
if (!res[i] && nextInstance) { | ||
var rollUp = [] | ||
while (!res[i] && i < res.length) rollUp.push(keys[i++]) | ||
for (var i = 0; i < keys.length; i++) { | ||
if (!res[i] && nextInstanceIndex != null) { | ||
var rollUp = [] | ||
var startOfHole = i | ||
while (i < keys.length && !res[i]) rollUp.push(keys[i++]) | ||
nextInstance.mget(rollUp) | ||
.then(function (data) { | ||
for (var k = 0; k < data.length; k++) res[k] = data[k] | ||
}) | ||
promises.push(self.mget(rollUp, nextInstanceIndex) | ||
.then(function (itemIndex, data) { | ||
if (data == undefined) return undefined | ||
for (var k = 0; k < data.length; k++) res[itemIndex + k] = data[k] | ||
}.bind(null, startOfHole))) | ||
} | ||
} | ||
} | ||
return res | ||
}.bind(this)) | ||
return Q.all(promises).then(function () { | ||
return res | ||
}) | ||
}) | ||
} | ||
RedundantCacheGroup.prototype.get = function (key) { | ||
var instanceIndex = this._getIndexOfFirstAvailableInstance() | ||
RedundantCacheGroup.prototype.get = function (key, start) { | ||
var instanceIndex = this._getIndexOfFirstAvailableInstance(start || 0) | ||
var self = this | ||
for (var i = instanceIndex, instance; instance = this._getAvailableInstance(i); i++) { | ||
var ret = instance.get(key) | ||
if (ret) return Q.resolve(ret) | ||
} | ||
return Q.resolve(undefined) | ||
if (instanceIndex == null) return Q.resolve(undefined) | ||
return this._getAvailableInstance(instanceIndex).get(key) | ||
.then(function (data) { | ||
if (data === undefined) return self.get(key, instanceIndex + 1) | ||
return data | ||
}) | ||
} | ||
@@ -115,0 +125,0 @@ |
{ | ||
"name": "zcache", | ||
"description": "AWS zone-aware multi-layer cache", | ||
"version": "0.2.7", | ||
"version": "0.2.8", | ||
"homepage": "https://github.com/Obvious/zcache", | ||
@@ -6,0 +6,0 @@ "authors": [ |
@@ -23,4 +23,6 @@ var zcache = require('../index') | ||
exports.testCacheSet = function (test) { | ||
test.equal(0, this.cI.getKeyCount(), 'There is no key in cache') | ||
this.cI.set('foo', 'bar', 10000) | ||
test.equal(this.cI._data['foo'], 'bar', 'bar should be returned') | ||
test.equal(1, this.cI.getKeyCount(), 'There is 1 key in cache') | ||
test.done() | ||
@@ -112,2 +114,3 @@ } | ||
test.equal(this.cI._data['c'], 3, 'c should be 3') | ||
test.equal(3, this.cI.getKeyCount(), 'There are 3 keys in cache') | ||
test.done() | ||
@@ -114,0 +117,0 @@ } |
@@ -14,2 +14,3 @@ var zcache = require('../index') | ||
this.cacheInstance.add(this.memoryInstance2, 1) | ||
this.cacheInstance.connect() | ||
callback() | ||
@@ -19,3 +20,6 @@ }, | ||
tearDown: function (callback) { | ||
if (this.cacheInstance) this.cacheInstance.destroy() | ||
if (this.cacheInstance) { | ||
this.cacheInstance.disconnect() | ||
this.cacheInstance.destroy() | ||
} | ||
callback() | ||
@@ -26,5 +30,12 @@ }, | ||
this.cacheInstance.set('foo', 'bar', 10000) | ||
test.equal(this.memoryInstance1.get('foo'), 'bar', 'bar should be in memory') | ||
test.equal(this.memoryInstance2.get('foo'), 'bar', 'bar should be in memory') | ||
test.done() | ||
this.memoryInstance1.get('foo') | ||
.then(function (data) { | ||
test.equal(data, 'bar', 'bar should be in memoryInstance1') | ||
}) | ||
this.memoryInstance2.get('foo') | ||
.then(function (data) { | ||
test.equal(data, 'bar', 'bar should be in memoryInstance2') | ||
test.done() | ||
}) | ||
}, | ||
@@ -60,2 +71,112 @@ | ||
testCacheMgetMultipleSingleHolesStagger: function (test) { | ||
this.cacheInstance.set('one', 'one', 10000) | ||
// this will be a 'hole' | ||
this.cacheInstance.set('two', 'two', 10000) | ||
this.memoryInstance1.del('two') | ||
this.cacheInstance.set('three', 'three', 10000) | ||
// this will be a 'hole' | ||
this.cacheInstance.set('four', 'four', 10000) | ||
this.memoryInstance1.del('four') | ||
this.cacheInstance.set('five', 'five', 10000) | ||
this.cacheInstance.mget(['one', 'two', 'three', 'four', 'five']) | ||
.then(function (results) { | ||
test.equal(results[0], 'one', 'one should have been found') | ||
test.equal(results[1], 'two', 'two should have been found') | ||
test.equal(results[2], 'three', 'three should have been found') | ||
test.equal(results[3], 'four', 'four should have been found') | ||
test.equal(results[4], 'five', 'five should have been found') | ||
test.done() | ||
}) | ||
}, | ||
testCacheMgetMultipleLargeHolesStagger: function (test) { | ||
this.cacheInstance.set('one', 'one', 10000) | ||
// this will be a 'hole' | ||
this.cacheInstance.set('two', 'two', 10000) | ||
this.memoryInstance1.del('two') | ||
this.cacheInstance.set('three', 'three', 10000) | ||
this.memoryInstance1.del('three') | ||
this.cacheInstance.set('four', 'four', 10000) | ||
// this will be a 'hole' | ||
this.cacheInstance.set('five', 'five', 10000) | ||
this.memoryInstance1.del('five') | ||
this.cacheInstance.set('six', 'six', 10000) | ||
this.memoryInstance1.del('six') | ||
this.cacheInstance.set('seven', 'seven', 10000) | ||
this.cacheInstance.mget(['one', 'two', 'three', 'four', 'five', 'six', 'seven']) | ||
.then(function (results) { | ||
test.equal(results[0], 'one', 'one should have been found') | ||
test.equal(results[1], 'two', 'two should have been found') | ||
test.equal(results[2], 'three', 'three should have been found') | ||
test.equal(results[3], 'four', 'four should have been found') | ||
test.equal(results[4], 'five', 'five should have been found') | ||
test.equal(results[5], 'six', 'six should have been found') | ||
test.equal(results[6], 'seven', 'seven should have been found') | ||
test.done() | ||
}) | ||
}, | ||
testCacheMgetAllHole: function (test) { | ||
this.cacheInstance.set('one', 'one', 10000) | ||
this.memoryInstance1.del('one') | ||
this.cacheInstance.set('two', 'two', 10000) | ||
this.memoryInstance1.del('two') | ||
this.cacheInstance.set('three', 'three', 10000) | ||
this.memoryInstance1.del('three') | ||
this.cacheInstance.mget(['one', 'two', 'three']) | ||
.then(function (results) { | ||
test.equal(results[0], 'one', 'one should have been found') | ||
test.equal(results[1], 'two', 'two should have been found') | ||
test.equal(results[2], 'three', 'three should have been found') | ||
test.done() | ||
}) | ||
}, | ||
testCacheMgetHoleBeginning: function (test) { | ||
this.cacheInstance.set('one', 'one', 10000) | ||
this.memoryInstance1.del('one') | ||
this.cacheInstance.set('two', 'two', 10000) | ||
this.cacheInstance.set('three', 'three', 10000) | ||
this.cacheInstance.mget(['one', 'two', 'three']) | ||
.then(function (results) { | ||
test.equal(results[0], 'one', 'one should have been found') | ||
test.equal(results[1], 'two', 'two should have been found') | ||
test.equal(results[2], 'three', 'three should have been found') | ||
test.done() | ||
}) | ||
}, | ||
testCacheMgetHoleEnd: function (test) { | ||
this.cacheInstance.set('one', 'one', 10000) | ||
this.cacheInstance.set('two', 'two', 10000) | ||
this.cacheInstance.set('three', 'three', 10000) | ||
this.memoryInstance1.del('three') | ||
this.cacheInstance.mget(['one', 'two', 'three']) | ||
.then(function (results) { | ||
test.equal(results[0], 'one', 'one should have been found') | ||
test.equal(results[1], 'two', 'two should have been found') | ||
test.equal(results[2], 'three', 'three should have been found') | ||
test.done() | ||
}) | ||
}, | ||
testCacheMsetStagger: function (test) { | ||
@@ -79,4 +200,4 @@ this.cacheInstance.mset([{key: 'foo', value: 'bar'}, {key: 'fah', value: 'bah'}]) | ||
}) | ||
this.cacheInstance.del('foo') | ||
this.cacheInstance.get('foo') | ||
@@ -83,0 +204,0 @@ .then(function (data) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
92519
2187
0
23