Merge pull request +12410 from c9/stats-via-extension

Stats via vfs extension
pull/263/head
Fabian Jakobs 2016-02-26 11:31:35 +01:00
commit 26e1a7be83
2 zmienionych plików z 270 dodań i 0 usunięć

82
node_modules/c9/cache.js wygenerowano vendored 100644
Wyświetl plik

@ -0,0 +1,82 @@
var Cache = function(maxSize, age) {
this._maxSize = (parseInt(maxSize, 10) === maxSize) ? maxSize : 1000;
this._maxAge = (parseInt(age, 10) === age) ? age : 5000;
this._items = {};
this._keys = [];
};
var proto = Cache.prototype;
proto.set = function(key, value) {
var item = this._items[key];
if (item) {
this.delete(key);
}
this._keys.push(key);
this._items[key] = {
value: value,
lastAccessed: Date.now()
};
this.purge();
};
proto.has = function(key) {
var item = this._items[key];
return (item && !this._hasExpired(item));
};
proto.get = function(key) {
var item = this._items[key];
if (item && !this._hasExpired(item)) {
return item.value;
}
return null;
};
proto.delete = function(key) {
delete this._items[key];
this._keys.splice(this._keys.indexOf(key), 1);
};
proto.purge = function() {
if (this._keys.length > this._maxSize) {
this._purgeItems();
}
};
proto.size = function() {
return this._keys.length;
};
proto._purgeItems = function() {
var maxSize = this._maxSize * 0.75;
// Remove epired items
this._keys.forEach(function(key) {
var item = this._items[key];
if (this._hasExpired(item)) {
this.delete(key);
}
}, this);
// Remove least used items
if (this._keys.length > maxSize) {
this._keys = this._keys.sort(function(a, b) {
return this._items[b].lastAccessed - this._items[a].lastAccessed;
}.bind(this));
while (this._keys.length > maxSize) {
var key = this._keys.pop();
this.delete(key);
}
}
};
proto._hasExpired = function(item) {
return (Date.now() - item.lastAccessed) > this._maxAge;
};
module.exports = Cache;

188
node_modules/c9/cache_test.js wygenerowano vendored 100644
Wyświetl plik

@ -0,0 +1,188 @@
"use strict";
"use server";
var assert = require("assert");
var Cache = require("./cache");
require("c9/inline-mocha")(module);
describe("Cache", function() {
var cache;
var maxSize = 5;
var age = 10;
beforeEach(function() {
cache = new Cache(maxSize, age) ;
});
describe("set", function() {
it("should add the item to the cache", function(){
var item = { a: 1 };
var key = "foo/bar";
cache.set(key, item);
var cachedItem = cache.get(key);
assert.equal(cachedItem, item);
});
it("should increment size", function() {
var item = { a: 1 };
cache.set("foo/bar", item);
cache.set("foo/baz", item);
cache.set("foo/bir", item);
cache.set("foo/biz", item);
cache.set("foo/bur", item);
assert(cache.size(), 5);
});
});
describe("get", function() {
it("should return item when called within age", function() {
var item = { a: 1 };
var key = "foo/bar";
cache.set(key, item);
var cachedItem = cache.get(key);
assert.equal(cachedItem, item);
});
it("should return `null` if item expired", function(done) {
var item = { a: 1 };
var key = "foo/bar";
var cache = new Cache(maxSize, 0) ;
cache.set(key, item);
// Do we use sinon to make this sync?
setTimeout(function() {
var cachedItem = cache.get(key);
assert.equal(cachedItem, null);
done();
}, 0);
});
});
describe("delete", function() {
it("should remove item from cache", function() {
var item = { a: 1 };
var key = "foo/bar";
cache.set(key, item);
cache.delete(key);
var cachedItem = cache.get(key);
assert.equal(cachedItem, null);
});
it("should decrement size", function() {
var item = { a: 1 };
var key = "foo/bar";
cache.set(key, item);
cache.delete(key);
assert.equal(cache.size(), 0);
});
});
describe("purge", function() {
it("should not purge when maxSize is not reached", function() {
var item = { a: 1 };
var cache = new Cache(7) ;
cache.set("foo/bar", item);
cache.set("foo/baz", item);
cache.set("foo/bir", item);
cache.set("foo/biz", item);
assert.equal(cache.size(), 4);
});
it("should purge when maxSize is reached", function() {
var item = { a: 1 };
var cache = new Cache(10) ;
cache.set("1", item);
cache.set("2", item);
cache.set("3", item);
cache.set("4", item);
cache.set("5", item);
cache.set("6", item);
cache.set("7", item);
cache.set("8", item);
cache.set("9", item);
cache.set("10", item);
cache.set("11", item);
assert.equal(cache.size(), 7);
});
it("should purge the least recently used items", function(done) {
var item = { a: 1 };
var cache = new Cache(10, 0) ;
cache.set("1", item);
cache.set("2", item);
cache.set("3", item);
cache.set("4", item);
cache.set("5", item);
cache.set("6", item);
cache.set("7", item);
cache.set("8", item);
cache.set("9", item);
cache.set("10", item);
// New cache hits
setTimeout(function() {
cache.get("1");
cache.get("2");
cache.get("10");
cache.get("4");
cache.get("5");
cache.get("6");
// Trigger purge
cache.set("11", item);
var cachedItem = cache.get("7");
assert.equal(cachedItem, null);
cachedItem = cache.get("8");
assert.equal(cachedItem, null);
cachedItem = cache.get("9");
assert.equal(cachedItem, null);
cachedItem = cache.get("3");
assert.equal(cachedItem, null);
done();
}, 1);
});
it("should purge expired items", function(done) {
var item = { a: 1 };
var cache = new Cache(5, 0) ;
cache.set("1", item);
cache.set("2", item);
cache.set("3", item);
cache.set("4", item);
setTimeout(function() {
cache.set("5", item);
var cachedItem = cache.get("1");
assert.equal(cachedItem, null);
cachedItem = cache.get("2");
assert.equal(cachedItem, null);
cachedItem = cache.get("3");
assert.equal(cachedItem, null);
cachedItem = cache.get("4");
assert.equal(cachedItem, null);
done();
}, 2);
});
});
});