Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More counter fixes #3

Merged
merged 3 commits into from Jul 6, 2011
Merged

More counter fixes #3

merged 3 commits into from Jul 6, 2011

Conversation

otterley
Copy link

@otterley otterley commented Jul 6, 2011

See commits for details.

Michael S. Fischer added 2 commits July 5, 2011 20:06
`count' was both an attribute and a prototype of Counter.  You can't
have both (count() never worked anyway), and there's not much sense in
providing an accessor here, so it's been removed.
This patch adds some additional checking for counters:

* Wrap counters around at 2^32.  Most graphing software (RRDtool etc.)
  can deal with this properly.  Unfortunately wrapping at 2^64 isn't
  possible because JS has a maximum integer resolution of 2^53.

* Don't allow counters to be decremented below 0.
@@ -8,16 +14,18 @@ var Counter = module.exports = function Counter() {

Counter.prototype.inc = function(val) {
if (!val) { val = 1; }
this.count += val;
if (this.count === MAX_COUNTER_VALUE) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be >= instead of ===? If the counter is incremented by something other than 1, it may skip over this value.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the bug you're talking about, but your suggested fix isn't quite right. It should be something like:

if (val < 1) {
  return;
}
if (this.count === MAX_COUNTER_VALUE) {
  this.count = -1;
}
this.count += val;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the case where this.count is MAX_COUNTER_VALUE - 1, and then we get inc(100)?

> var MAX_COUNTER_VALUE = Math.pow(2, 32)
> MAX_COUNTER_VALUE
4294967296
> var count = MAX_COUNTER_VALUE - 1
> count += 100
4294967395
> count === MAX_COUNTER_VALUE
false

Seem like

> count >= MAX_COUNTER_VALUE
true

Fixes it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your test case was not a good simulation.

In my proposal, the value is temporarily set to -1, not MAX_COUNTER_VALUE - 1. Testing for count >= MAX_COUNTER_VALUE is incorrect because we want to wrapped result to compensate for the delta (e.g., if the previous value was MAX_COUNTER_VALUE and we are incrementing by 10, we want the result to be 9).

* Handle counter wrapping properly when val > 1.
* Prevent counter from being decremented below 0.
mikejihbe added a commit that referenced this pull request Jul 6, 2011
Counter fixes - overflow on integers > 2^32. Don't decrement below 0.
@mikejihbe mikejihbe merged commit 5560aae into mikejihbe:master Jul 6, 2011
@mikejihbe
Copy link
Owner

Yeah, this looks better. Thanks guys!

@otterley
Copy link
Author

otterley commented Jul 6, 2011

Actually, there's an off-by-one bug here. Please hold off on disting a new release. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants