Skip to content
This repository has been archived by the owner on Dec 2, 2020. It is now read-only.

Commit

Permalink
Replace 20-second tier with 10-second tier.
Browse files Browse the repository at this point in the history
This matches Graphite's default, which is useful for comparing metrics from
multiple backends. This also disables computing 5-minute metrics from the 10-
second tier, since for low-frequency events this is vastly more expensive than
computing the 5-minute metrics from the events directly. 10-second metrics are
still available if desired but they are no longer created as a side-effect of
requesting 5-minute metrics. Ideally, Cube could determine automatically whether
to descend to the next tier based on the number of events in each time interval,
but that'll require a bit more effort to implement.
  • Loading branch information
mbostock committed Apr 3, 2012
1 parent 9d71c70 commit 7caede0
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 33 deletions.
9 changes: 5 additions & 4 deletions lib/cube/server/metric.js
Expand Up @@ -57,12 +57,13 @@ exports.getter = function(db) {
// Request any needed fields. // Request any needed fields.
expression.fields(fields); expression.fields(fields);


find(start, stop, tier, reduce.pyramidal && tier.next, callback); find(start, stop, tier, callback);


// The metric is computed recursively, reusing the above variables. // The metric is computed recursively, reusing the above variables.
function find(start, stop, tier, pyramidal, callback) { function find(start, stop, tier, callback) {
var compute = group ? (group.multi ? computeGroups : computeGroup) var compute = group ? (group.multi ? computeGroups : computeGroup)
: pyramidal ? computePyramidal : computeFlat; : tier.next && reduce.pyramidal ? computePyramidal
: computeFlat;


// Query for the desired metric in the cache. // Query for the desired metric in the cache.
type.metrics.find({ type.metrics.find({
Expand Down Expand Up @@ -163,7 +164,7 @@ exports.getter = function(db) {
// Group metrics from the next tier. // Group metrics from the next tier.
function computePyramidal(start, stop) { function computePyramidal(start, stop) {
var bins = {}; var bins = {};
find(start, stop, tier.next, false, function(time, value) { find(start, stop, tier.next, function(time, value) {
var bin = bins[time = tier.floor(time)] || (bins[time] = {size: tier.size(time), values: []}); var bin = bins[time = tier.floor(time)] || (bins[time] = {size: tier.size(time), values: []});
if (bin.values.push(value) === bin.size) { if (bin.values.push(value) === bin.size) {
save(time, reduce(bin.values)); save(time, reduce(bin.values));
Expand Down
14 changes: 6 additions & 8 deletions lib/cube/server/tiers.js
@@ -1,7 +1,7 @@
var tiers = module.exports = {}; var tiers = module.exports = {};


var second = 1000, var second = 1000,
second20 = 20 * second, second10 = 10 * second,
minute = 60 * second, minute = 60 * second,
minute5 = 5 * minute, minute5 = 5 * minute,
hour = 60 * minute, hour = 60 * minute,
Expand All @@ -10,20 +10,18 @@ var second = 1000,
month = 30 * day, month = 30 * day,
year = 365 * day; year = 365 * day;


tiers[second20] = { tiers[second10] = {
key: second20, key: second10,
floor: function(d) { return new Date(Math.floor(d / second20) * second20); }, floor: function(d) { return new Date(Math.floor(d / second10) * second10); },
ceil: tier_ceil, ceil: tier_ceil,
step: function(d) { return new Date(+d + second20); } step: function(d) { return new Date(+d + second10); }
}; };


tiers[minute5] = { tiers[minute5] = {
key: minute5, key: minute5,
floor: function(d) { return new Date(Math.floor(d / minute5) * minute5); }, floor: function(d) { return new Date(Math.floor(d / minute5) * minute5); },
ceil: tier_ceil, ceil: tier_ceil,
step: function(d) { return new Date(+d + minute5); }, step: function(d) { return new Date(+d + minute5); }
next: tiers[second20],
size: function() { return 15; }
}; };


tiers[hour] = { tiers[hour] = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{ {
"name": "cube", "name": "cube",
"version": "0.1.3", "version": "0.1.4",
"description": "A system for time series visualization using MongoDB, Node and D3.", "description": "A system for time series visualization using MongoDB, Node and D3.",
"keywords": ["time series", "visualization"], "keywords": ["time series", "visualization"],
"homepage": "http://square.github.com/cube/", "homepage": "http://square.github.com/cube/",
Expand Down
41 changes: 21 additions & 20 deletions test/tiers-test.js
Expand Up @@ -13,14 +13,14 @@ suite.addBatch({
keys.push(+key); keys.push(+key);
} }
keys.sort(function(a, b) { return a - b; }); keys.sort(function(a, b) { return a - b; });
assert.deepEqual(keys, [2e4, 3e5, 36e5, 864e5, 6048e5, 2592e6]); assert.deepEqual(keys, [1e4, 3e5, 36e5, 864e5, 6048e5, 2592e6]);
} }
}, },


"second20": { "second10": {
topic: tiers[2e4], topic: tiers[1e4],
"has the key 2e4": function(tier) { "has the key 1e4": function(tier) {
assert.strictEqual(tier.key, 2e4); assert.strictEqual(tier.key, 1e4);
}, },
"next is undefined": function(tier) { "next is undefined": function(tier) {
assert.isUndefined(tier.next); assert.isUndefined(tier.next);
Expand All @@ -30,11 +30,11 @@ suite.addBatch({
}, },


"floor": { "floor": {
"rounds down to 20-seconds": function(tier) { "rounds down to 10-seconds": function(tier) {
assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20)); assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20));
assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 20)); assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 20));
assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 20)); assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 20));
assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 20)); assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 30));
assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40));
}, },
"does not modify the passed-in date": function(tier) { "does not modify the passed-in date": function(tier) {
Expand All @@ -45,35 +45,36 @@ suite.addBatch({
}, },


"ceil": { "ceil": {
"rounds up to 5-minutes": function(tier) { "rounds up to 10-seconds": function(tier) {
assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20)); assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20));
assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 30));
assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 30));
assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 40));
assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40));
}, },
"does not modified the specified date": function(tier) { "does not modified the specified date": function(tier) {
var date = utc(2011, 08, 02, 12, 00, 21); var date = utc(2011, 08, 02, 12, 00, 21);
assert.deepEqual(tier.ceil(date), utc(2011, 08, 02, 12, 00, 40)); assert.deepEqual(tier.ceil(date), utc(2011, 08, 02, 12, 00, 30));
assert.deepEqual(date, utc(2011, 08, 02, 12, 00, 21)); assert.deepEqual(date, utc(2011, 08, 02, 12, 00, 21));
} }
}, },


"step": { "step": {
"increments time by twenty minutes": function(tier) { "increments time by ten seconds": function(tier) {
var date = utc(2011, 08, 02, 23, 59, 20); var date = utc(2011, 08, 02, 23, 59, 20);
assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 30));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 40)); assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 40));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 50));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 00)); assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 00));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 10));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 20)); assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 20));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 40));
assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 01, 00));
}, },
"does not round the specified date": function(tier) { "does not round the specified date": function(tier) {
assert.deepEqual(tier.step(utc(2011, 08, 02, 12, 21, 23)), utc(2011, 08, 02, 12, 21, 43)); assert.deepEqual(tier.step(utc(2011, 08, 02, 12, 21, 23)), utc(2011, 08, 02, 12, 21, 33));
}, },
"does not modify the specified date": function(tier) { "does not modify the specified date": function(tier) {
var date = utc(2011, 08, 02, 12, 20, 00); var date = utc(2011, 08, 02, 12, 20, 00);
assert.deepEqual(tier.step(date), utc(2011, 08, 02, 12, 20, 20)); assert.deepEqual(tier.step(date), utc(2011, 08, 02, 12, 20, 10));
assert.deepEqual(date, utc(2011, 08, 02, 12, 20, 00)); assert.deepEqual(date, utc(2011, 08, 02, 12, 20, 00));
} }
} }
Expand All @@ -83,11 +84,11 @@ suite.addBatch({
"has the key 3e5": function(tier) { "has the key 3e5": function(tier) {
assert.strictEqual(tier.key, 3e5); assert.strictEqual(tier.key, 3e5);
}, },
"next is the 20-second tier": function(tier) { "next is undefined": function(tier) {
assert.equal(tier.next, tiers[2e4]); assert.isUndefined(tier.next);
}, },
"size is 15": function(tier) { "size is undefined": function(tier) {
assert.strictEqual(tier.size(), 15); assert.isUndefined(tier.size);
}, },


"floor": { "floor": {
Expand Down

0 comments on commit 7caede0

Please sign in to comment.