Skip to content
This repository
Browse code

Replace 20-second tier with 10-second tier.

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...
commit 7caede08741fde8bdc376ce7ae231625071b8764 1 parent 9d71c70
Mike Bostock mbostock authored
9 lib/cube/server/metric.js
@@ -57,12 +57,13 @@ exports.getter = function(db) {
57 57 // Request any needed fields.
58 58 expression.fields(fields);
59 59
60   - find(start, stop, tier, reduce.pyramidal && tier.next, callback);
  60 + find(start, stop, tier, callback);
61 61
62 62 // The metric is computed recursively, reusing the above variables.
63   - function find(start, stop, tier, pyramidal, callback) {
  63 + function find(start, stop, tier, callback) {
64 64 var compute = group ? (group.multi ? computeGroups : computeGroup)
65   - : pyramidal ? computePyramidal : computeFlat;
  65 + : tier.next && reduce.pyramidal ? computePyramidal
  66 + : computeFlat;
66 67
67 68 // Query for the desired metric in the cache.
68 69 type.metrics.find({
@@ -163,7 +164,7 @@ exports.getter = function(db) {
163 164 // Group metrics from the next tier.
164 165 function computePyramidal(start, stop) {
165 166 var bins = {};
166   - find(start, stop, tier.next, false, function(time, value) {
  167 + find(start, stop, tier.next, function(time, value) {
167 168 var bin = bins[time = tier.floor(time)] || (bins[time] = {size: tier.size(time), values: []});
168 169 if (bin.values.push(value) === bin.size) {
169 170 save(time, reduce(bin.values));
14 lib/cube/server/tiers.js
... ... @@ -1,7 +1,7 @@
1 1 var tiers = module.exports = {};
2 2
3 3 var second = 1000,
4   - second20 = 20 * second,
  4 + second10 = 10 * second,
5 5 minute = 60 * second,
6 6 minute5 = 5 * minute,
7 7 hour = 60 * minute,
@@ -10,20 +10,18 @@ var second = 1000,
10 10 month = 30 * day,
11 11 year = 365 * day;
12 12
13   -tiers[second20] = {
14   - key: second20,
15   - floor: function(d) { return new Date(Math.floor(d / second20) * second20); },
  13 +tiers[second10] = {
  14 + key: second10,
  15 + floor: function(d) { return new Date(Math.floor(d / second10) * second10); },
16 16 ceil: tier_ceil,
17   - step: function(d) { return new Date(+d + second20); }
  17 + step: function(d) { return new Date(+d + second10); }
18 18 };
19 19
20 20 tiers[minute5] = {
21 21 key: minute5,
22 22 floor: function(d) { return new Date(Math.floor(d / minute5) * minute5); },
23 23 ceil: tier_ceil,
24   - step: function(d) { return new Date(+d + minute5); },
25   - next: tiers[second20],
26   - size: function() { return 15; }
  24 + step: function(d) { return new Date(+d + minute5); }
27 25 };
28 26
29 27 tiers[hour] = {
2  package.json
... ... @@ -1,6 +1,6 @@
1 1 {
2 2 "name": "cube",
3   - "version": "0.1.3",
  3 + "version": "0.1.4",
4 4 "description": "A system for time series visualization using MongoDB, Node and D3.",
5 5 "keywords": ["time series", "visualization"],
6 6 "homepage": "http://square.github.com/cube/",
41 test/tiers-test.js
@@ -13,14 +13,14 @@ suite.addBatch({
13 13 keys.push(+key);
14 14 }
15 15 keys.sort(function(a, b) { return a - b; });
16   - assert.deepEqual(keys, [2e4, 3e5, 36e5, 864e5, 6048e5, 2592e6]);
  16 + assert.deepEqual(keys, [1e4, 3e5, 36e5, 864e5, 6048e5, 2592e6]);
17 17 }
18 18 },
19 19
20   - "second20": {
21   - topic: tiers[2e4],
22   - "has the key 2e4": function(tier) {
23   - assert.strictEqual(tier.key, 2e4);
  20 + "second10": {
  21 + topic: tiers[1e4],
  22 + "has the key 1e4": function(tier) {
  23 + assert.strictEqual(tier.key, 1e4);
24 24 },
25 25 "next is undefined": function(tier) {
26 26 assert.isUndefined(tier.next);
@@ -30,11 +30,11 @@ suite.addBatch({
30 30 },
31 31
32 32 "floor": {
33   - "rounds down to 20-seconds": function(tier) {
  33 + "rounds down to 10-seconds": function(tier) {
34 34 assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20));
35 35 assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 20));
36 36 assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 20));
37   - assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 20));
  37 + assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 30));
38 38 assert.deepEqual(tier.floor(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40));
39 39 },
40 40 "does not modify the passed-in date": function(tier) {
@@ -45,35 +45,36 @@ suite.addBatch({
45 45 },
46 46
47 47 "ceil": {
48   - "rounds up to 5-minutes": function(tier) {
  48 + "rounds up to 10-seconds": function(tier) {
49 49 assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 20)), utc(2011, 08, 02, 12, 00, 20));
50   - assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 40));
51   - assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 40));
  50 + assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 21)), utc(2011, 08, 02, 12, 00, 30));
  51 + assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 23)), utc(2011, 08, 02, 12, 00, 30));
52 52 assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 39)), utc(2011, 08, 02, 12, 00, 40));
53 53 assert.deepEqual(tier.ceil(utc(2011, 08, 02, 12, 00, 40)), utc(2011, 08, 02, 12, 00, 40));
54 54 },
55 55 "does not modified the specified date": function(tier) {
56 56 var date = utc(2011, 08, 02, 12, 00, 21);
57   - assert.deepEqual(tier.ceil(date), utc(2011, 08, 02, 12, 00, 40));
  57 + assert.deepEqual(tier.ceil(date), utc(2011, 08, 02, 12, 00, 30));
58 58 assert.deepEqual(date, utc(2011, 08, 02, 12, 00, 21));
59 59 }
60 60 },
61 61
62 62 "step": {
63   - "increments time by twenty minutes": function(tier) {
  63 + "increments time by ten seconds": function(tier) {
64 64 var date = utc(2011, 08, 02, 23, 59, 20);
  65 + assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 30));
65 66 assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 40));
  67 + assert.deepEqual(date = tier.step(date), utc(2011, 08, 02, 23, 59, 50));
66 68 assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 00));
  69 + assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 10));
67 70 assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 20));
68   - assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 00, 40));
69   - assert.deepEqual(date = tier.step(date), utc(2011, 08, 03, 00, 01, 00));
70 71 },
71 72 "does not round the specified date": function(tier) {
72   - assert.deepEqual(tier.step(utc(2011, 08, 02, 12, 21, 23)), utc(2011, 08, 02, 12, 21, 43));
  73 + assert.deepEqual(tier.step(utc(2011, 08, 02, 12, 21, 23)), utc(2011, 08, 02, 12, 21, 33));
73 74 },
74 75 "does not modify the specified date": function(tier) {
75 76 var date = utc(2011, 08, 02, 12, 20, 00);
76   - assert.deepEqual(tier.step(date), utc(2011, 08, 02, 12, 20, 20));
  77 + assert.deepEqual(tier.step(date), utc(2011, 08, 02, 12, 20, 10));
77 78 assert.deepEqual(date, utc(2011, 08, 02, 12, 20, 00));
78 79 }
79 80 }
@@ -83,11 +84,11 @@ suite.addBatch({
83 84 "has the key 3e5": function(tier) {
84 85 assert.strictEqual(tier.key, 3e5);
85 86 },
86   - "next is the 20-second tier": function(tier) {
87   - assert.equal(tier.next, tiers[2e4]);
  87 + "next is undefined": function(tier) {
  88 + assert.isUndefined(tier.next);
88 89 },
89   - "size is 15": function(tier) {
90   - assert.strictEqual(tier.size(), 15);
  90 + "size is undefined": function(tier) {
  91 + assert.isUndefined(tier.size);
91 92 },
92 93
93 94 "floor": {

0 comments on commit 7caede0

Please sign in to comment.
Something went wrong with that request. Please try again.