From 945b6ac44f39b700f7dead3a340aeaef3fc8261c Mon Sep 17 00:00:00 2001 From: Ruslan Dzhumakaliev Date: Tue, 29 Aug 2023 10:52:28 -0700 Subject: [PATCH 1/2] CountMinSketch: support incrementing counter by a given number --- lib/countMinSketch.js | 13 ++++++++++--- test/countminsketch-test.js | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/countMinSketch.js b/lib/countMinSketch.js index 8adcf22..0cffc9e 100644 --- a/lib/countMinSketch.js +++ b/lib/countMinSketch.js @@ -81,8 +81,15 @@ function CountMinSketch(maxEntries, epsilon, delta, lgWidth, counts, hashFunctio /** * Record an observation of the given key. * @param {String} key Key to increment the observation count for. + * @param {Number} incrementBy Number to increment counter by */ - function increment(key) { + function increment(key, incrementBy=1) { + if (incrementBy < 0) { + throw new Error(`Can't increment by a negative number`); + } else if (incrementBy === 0) { + return; + } + // Map the key to an integer value var ix = hashing.fnv1a(key); var est = MAX_INT; @@ -100,11 +107,11 @@ function CountMinSketch(maxEntries, epsilon, delta, lgWidth, counts, hashFunctio for (i = 0; i < hashFunctions.length; i++) { j = multiplyShift(lgWidth, hashFunctions[i], ix); if (counts[i][j] === est) - counts[i][j] = est + 1; + counts[i][j] = est + incrementBy; } // Update the priority queue with the updated [count, key] tuple - updateHeap(key, est + 1); + updateHeap(key, est + incrementBy); } function updateHeap(key, est) { diff --git a/test/countminsketch-test.js b/test/countminsketch-test.js index 442c513..60c28e0 100644 --- a/test/countminsketch-test.js +++ b/test/countminsketch-test.js @@ -18,7 +18,7 @@ vows.describe('CountMinSketch').addBatch({ assert.equal(top[0][0], 1); assert.equal(top[0][1], '4d6e5acebcd1b3fac0000000'); }, - 'can increment': function(cms) { + 'can increment by 1': function(cms) { cms.increment('4d6e5acebcd1b3fac0000000'); cms.increment('4d6e5acebcd1b3fac0000000'); @@ -27,6 +27,19 @@ vows.describe('CountMinSketch').addBatch({ assert.equal(top[0][0], 3); assert.equal(top[0][1], '4d6e5acebcd1b3fac0000000'); }, + 'can increment by a given number': function(cms) { + cms.increment('4d6e5acebcd1b3fac0000000', 2); + cms.increment('4d6e5acebcd1b3fac0000000', 3); + cms.increment('4d6e5acebcd1b3fac0000000', 0); + + var top = cms.getTopK(); + assert.equal(top.length, 1); + assert.equal(top[0][0], 8); + assert.equal(top[0][1], '4d6e5acebcd1b3fac0000000'); + }, + 'returns an exception when increment number is negative': function(cms) { + assert.throws(() => cms.increment('4d6e5acebcd1b3fac0000000', -2), Error); + }, 'can add 1000000': function(cms) { var i; for (i = 1; i < 999999; i++) From e226925e064c193aedc6043367bb79c509363e99 Mon Sep 17 00:00:00 2001 From: Ruslan Dzhumakaliev Date: Thu, 31 Aug 2023 10:26:14 -0700 Subject: [PATCH 2/2] remove increment by negative number check --- lib/countMinSketch.js | 6 ------ test/countminsketch-test.js | 6 ++---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/lib/countMinSketch.js b/lib/countMinSketch.js index 0cffc9e..63aea7c 100644 --- a/lib/countMinSketch.js +++ b/lib/countMinSketch.js @@ -84,12 +84,6 @@ function CountMinSketch(maxEntries, epsilon, delta, lgWidth, counts, hashFunctio * @param {Number} incrementBy Number to increment counter by */ function increment(key, incrementBy=1) { - if (incrementBy < 0) { - throw new Error(`Can't increment by a negative number`); - } else if (incrementBy === 0) { - return; - } - // Map the key to an integer value var ix = hashing.fnv1a(key); var est = MAX_INT; diff --git a/test/countminsketch-test.js b/test/countminsketch-test.js index 60c28e0..8aea4fc 100644 --- a/test/countminsketch-test.js +++ b/test/countminsketch-test.js @@ -30,16 +30,14 @@ vows.describe('CountMinSketch').addBatch({ 'can increment by a given number': function(cms) { cms.increment('4d6e5acebcd1b3fac0000000', 2); cms.increment('4d6e5acebcd1b3fac0000000', 3); + cms.increment('4d6e5acebcd1b3fac0000000', -1); cms.increment('4d6e5acebcd1b3fac0000000', 0); var top = cms.getTopK(); assert.equal(top.length, 1); - assert.equal(top[0][0], 8); + assert.equal(top[0][0], 7); assert.equal(top[0][1], '4d6e5acebcd1b3fac0000000'); }, - 'returns an exception when increment number is negative': function(cms) { - assert.throws(() => cms.increment('4d6e5acebcd1b3fac0000000', -2), Error); - }, 'can add 1000000': function(cms) { var i; for (i = 1; i < 999999; i++)