New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

zcache

Package Overview
Dependencies
Maintainers
7
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zcache - npm Package Compare versions

Comparing version 0.2.5 to 0.2.7

dump.rdb

53

lib/CacheInstance.js

@@ -19,2 +19,4 @@ var events = require('events')

}
this._accessCount = 0
this._hitCount = 0
}

@@ -108,2 +110,30 @@ util.inherits(CacheInstance, events.EventEmitter)

/**
* Get the number of cache accesses.
*
* @return {number}
*/
CacheInstance.prototype.getAccessCount = function () {
return this._accessCount
}
/**
* Get the number of cache hits.
*
* @return {number}
*/
CacheInstance.prototype.getHitCount = function () {
return this._hitCount
}
/**
* Reset the access count and hit count to get counts during time intervals.
*
* @return {number}
*/
CacheInstance.prototype.resetCount = function () {
this._hitCount = 0
this._accessCount = 0
}
/**
* Get service information about this cache instance if it is a standlone service.

@@ -120,2 +150,25 @@ *

/**
* Update the access count and hit count according to the result of get/mget.
*
* @param {Array.<Object>|Object} data The data fetched by get or mget.
* @return {Function} A function that updates the counts and returns the parameter
* that is passed into it. It is handy to chain to a promise.
*/
CacheInstance.prototype.updateCount = function() {
var self = this
return function (data) {
if (Array.isArray(data)) {
self._accessCount += data.length
for (var i = 0; i < data.length; i++) {
if (typeof data[i] !== 'undefined' && data[i] !== null) self._hitCount += 1
}
} else {
self._accessCount += 1
if (typeof data !== 'undefined' && data !== null) self._hitCount += 1
}
return data
}
}
/**
* Update the stats of a certain operation on this cache.

@@ -122,0 +175,0 @@ *

91

lib/InMemoryCache.js

@@ -0,1 +1,3 @@

// Copyright 2013 The Obvious Corporation.
var Q = require('kew')

@@ -5,2 +7,14 @@ var util = require('util')

/**
* A complete in-memory in-process cache. It stores all the key/values in memory
* and usually keeps them for a short period of time. The purpose is to accommodate
* the access patterns where the same piece of data is required for multiple times
* in a short period of time.
*
* You can set the TTL of each invidicual key, and you can also set a global TTL
* for all the keys. A reaper is invoked periodically to remove expired keys.
*
* @constructor
* @implements {CacheInstance}
*/
function InMemoryCache() {

@@ -28,26 +42,7 @@ CacheInstance.call(this)

// create a reaper which scans through all of the items in _data every
// this._reaperIntervalMs millisseconds, if the item has expired then
// it's deleted.
InMemoryCache.prototype._createReaper = function () {
return setInterval(function () {
Object.keys(this._expireAt).map(function (key) {
if (this._expireAt[key] < Date.now()) this.del(key)
}.bind(this))
}.bind(this), this._reaperIntervalMs)
}
// Destroy the reaper interval if it exists
InMemoryCache.prototype._destroyReaper = function () {
if (!!this._reaperInterval) clearInterval(this._reaperInterval)
}
// Destroy the reaper interval and create a new reaper
// this is done when you reset the reaper interval
InMemoryCache.prototype._resetReaper = function () {
this._destroyReaper()
this._reaperInterval = this._createReaper()
}
// set the reaper to run every everyMs ms
/**
* Set how frequently the reaper runs.
*
* @param {number} everyMs The interval of two consecutive runs of the reaper, in milliseconds.
*/
InMemoryCache.prototype.setReaperInterval = function (everyMs) {

@@ -58,3 +53,7 @@ this._reaperIntervalMs = everyMs

// set a custom ttl for every object added to the cache from here on out
/**
* Set a custom ttl for every object added to the cache from here on out.
*
* @param {number} maxAgeMs The TTL of the objects in this cache, in milliseconds.
*/
InMemoryCache.prototype.overrideMaxAgeMs = function (maxAgeMs) {

@@ -64,2 +63,3 @@ this._maxAgeOverride = maxAgeMs

/** @inheritDoc */
InMemoryCache.prototype.isAvailable = function () {

@@ -69,2 +69,3 @@ return this._isAvailable

/** @inheritDoc */
InMemoryCache.prototype.connect = function () {

@@ -77,2 +78,3 @@ this._isAvailable = true

/** @inheritDoc */
InMemoryCache.prototype.disconnect = function () {

@@ -84,2 +86,3 @@ this._destroyReaper()

/** @inheritDoc */
InMemoryCache.prototype.destroy = function () {

@@ -93,10 +96,18 @@ this._destroyReaper()

/** @inheritDoc */
InMemoryCache.prototype.get = function (key) {
return (this._expireAt[key] > Date.now() ? this._data[key] : undefined)
return this.mget([key]).then(function (data) {
return data[0]
})
}
/** @inheritDoc */
InMemoryCache.prototype.mget = function (keys) {
var ret = []
this._accessCount += keys.length
for (var i = 0; i < keys.length; i++) {
ret.push(this.get(keys[i]))
if (this._expireAt[keys[i]] > Date.now()) {
ret[i] = this._data[keys[i]]
this._hitCount += 1
}
}

@@ -106,2 +117,3 @@ return Q.resolve(ret)

/** @inheritDoc */
InMemoryCache.prototype.set = function (key, val, maxAgeMs) {

@@ -112,2 +124,3 @@ this._expireAt[key] = Date.now() + (this._maxAgeOverride || maxAgeMs )

/** @inheritDoc */
InMemoryCache.prototype.mset = function (items, maxAgeMs) {

@@ -119,2 +132,3 @@ for (var i = 0; i < items.length; i++) {

/** @inheritDoc */
InMemoryCache.prototype.del = function (key) {

@@ -126,2 +140,25 @@ ;delete this._data[key]

// Create a reaper which scans through all of the items in _data every
// this._reaperIntervalMs millisseconds, if the item has expired then
// it's deleted.
InMemoryCache.prototype._createReaper = function () {
return setInterval(function () {
Object.keys(this._expireAt).map(function (key) {
if (this._expireAt[key] < Date.now()) this.del(key)
}.bind(this))
}.bind(this), this._reaperIntervalMs)
}
// Destroy the reaper interval if it exists
InMemoryCache.prototype._destroyReaper = function () {
if (!!this._reaperInterval) clearInterval(this._reaperInterval)
}
// Destroy the reaper interval and create a new reaper
// this is done when you reset the reaper interval
InMemoryCache.prototype._resetReaper = function () {
this._destroyReaper()
this._reaperInterval = this._createReaper()
}
module.exports = InMemoryCache

@@ -85,2 +85,3 @@ var redis = require('redis')

return deferred.promise
.then(this.updateCount())
.then(this.updateStats('mget'))

@@ -87,0 +88,0 @@ }

{
"name": "zcache",
"description": "AWS zone-aware multi-layer cache",
"version": "0.2.5",
"version": "0.2.7",
"homepage": "https://github.com/Obvious/zcache",

@@ -6,0 +6,0 @@ "authors": [

@@ -7,2 +7,3 @@ var zcache = require('../index')

this.cI.connect()
this.cI.resetCount()
callback()

@@ -13,2 +14,3 @@ }

this.cI.disconnect()
this.cI.destroy()
callback()

@@ -33,5 +35,8 @@ }

setTimeout(function () {
test.equal(this.cI.get('foo'), undefined, 'foo should have expired by now')
test.done()
}.bind(this), 2501)
this.cI.get('foo')
.then(function (data) {
test.equal(data, undefined, 'foo should have expired by now')
test.done()
})
}.bind(this), 2)
}

@@ -64,8 +69,14 @@

this.cI.set('foo', 'bar', 500)
var self = this
// undefined should be returned since the item has expired, but before the reaper could clean it
setTimeout(function () {
test.equal(this.cI.get('foo'), undefined, 'foo should still be in the cache')
test.done()
}.bind(this), 750)
self.cI.get('foo')
.then(function (data) {
test.equal(data, undefined, 'foo should still be in the cache')
test.equal(1, self.cI.getAccessCount(), 'The number of accesses is 1')
test.equal(0, self.cI.getHitCount(), 'The number of hits is 0 - the cache entry has expired')
test.done()
})
}, 750)
}

@@ -76,4 +87,10 @@

this.cI._expireAt['foo'] = Date.now() + 1000
test.equal(this.cI.get('foo'), 1, '1 should be returned')
test.done()
var self = this
this.cI.get('foo')
.then(function (data) {
test.equal(data, 1, '1 should be returned')
test.equal(1, self.cI.getAccessCount(), 'The number of accesses is 1')
test.equal(1, self.cI.getHitCount(), 'The number of hits is 1')
test.done()
})
}

@@ -104,3 +121,3 @@

this.cI.mset([{key: 'a', value: 1}, {key: 'b', value: 2}, {key: 'c', value: 3}], 1000)
var self = this
this.cI.mget(['a', 'b', 'c'])

@@ -112,4 +129,4 @@ .then(function (keys) {

test.equal(keys[2], 3, 'c should be 3')
})
.fin(function () {
test.equal(3, self.cI.getAccessCount(), 'The number of accesses is 3')
test.equal(3, self.cI.getHitCount(), 'The number of hits is 3')
test.done()

@@ -124,15 +141,14 @@ })

this.cI.mset([{key: 'a', value: 1}, {key: 'b', value: 2}, {key: 'c', value: 3}], 100)
var self = this
setTimeout(function () {
this.cI.mget(['a', 'b', 'c'])
self.cI.mget(['a', 'b', 'c'])
.then(function (keys) {
if (keys.length != 3) test.fail('there should be 3 items returned')
test.equal(keys[0], undefined, 'a should be undefined')
test.equal(keys[1], undefined, 'b should be undefined')
test.equal(keys[2], undefined, 'c should be undefined')
})
.fin(function () {
test.equal(3, self.cI.getAccessCount(), 'The number of accesses is 3')
test.equal(0, self.cI.getHitCount(), 'The number of hits is 0')
test.done()
})
}.bind(this), 1101)
}, 1101)
}

@@ -47,3 +47,3 @@ var zcache = require('../index')

.then(function (vals) {
test.equal(vals[0], undefined)
test.equal(vals[0], null)
})

@@ -60,8 +60,9 @@ .then(function () {

.then(function () {
return cacheInstance.mget(['a', 'b'])
return cacheInstance.mget(['a', 'b', 'c'])
})
.then(function (vals) {
test.equal(vals.length, 2, 'Should have precisely 2 results')
test.equal(vals.length, 3, 'Should have precisely 3 results')
test.equal(vals[0], '456')
test.equal(vals[1], '789')
test.equal(vals[2], null)
test.equal(1, cacheInstance.getStats('set').count(), 'set() is called for once')

@@ -72,2 +73,4 @@ test.equal(1, cacheInstance.getStats('mset').count(), 'mset() is called for once')

test.equal(1, cacheInstance.getStats('del').count(), 'del() is call for once')
test.equal(5, cacheInstance.getAccessCount(), 'The number of cache access is 5')
test.equal(3, cacheInstance.getHitCount(), 'The number of cache hit is 3')
return cacheInstance.getServerInfo()

@@ -74,0 +77,0 @@ })

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc