Live data from Hacker News

I've been writing ring buffers wrong all these years

snellman.net

41–50 of 175 posts

Re: I've been writing ring buffers wrong all these years

#42

Earlier quoted context omitted.

No, it's not. A non-power-of-two will lead to incorrect behavior, implementing the data structure the way the author describes, for precisely the reason given by your parent comment. There are other implementations that don't suffer from this (described in the comments there), but it's not simply a matter of replacing bitwise-and with a more generic computation of the modulus. Imagine we had four bit integers and a t…

I never claimed you should use a modulus operation.

You said,

> It's unclear to me why the focus on a 2^n sized buffer just so you can use & for the mask.

In fact it is required for correctness to use the approach he specified with any choice of masking operation.

Re: I've been writing ring buffers wrong all these years

#43
post #14

Earlier quoted context omitted.

It's not just an optimization, it's necessary for correct operation. With a non-power of two buffer the integer wraparound causes a discontinuity.

No, it's an optimization.

Array size of 5 produces a mask of 0100

Write index of 8 = 1000

Masking those together to create a write position 1000 & 0100 = 0

Doesn't work out correctly, got 0, would expect to get 2. In fact, you could never get a write position of 1, 2, or 3 with an array size of 5.

Re: I've been writing ring buffers wrong all these years

#44

Earlier quoted context omitted.

No, it's an optimization.

Array size of 5 produces a mask of 0100 Write index of 8 = 1000 Masking those together to create a write position 1000 & 0100 = 0 Doesn't work out correctly, got 0, would expect to get 2. In fact, you could never get a write position of 1, 2, or 3 with an array size of 5.

This is not the problem.

You are assuming still using &, which is very obviously incorrect with a very obvious fix (%5) which is still wrong because of behavior at overflow.

Re: I've been writing ring buffers wrong all these years

#45

My C is rusty, but won't this act... oddly... on integer overflow? size() { return write - read; } 0 - UINT_MAX -1 = ? [EDIT] Changed constant to reflect use of unsigned integers, which I forgot to specify initially.

Actually, this method counts on it.

What I find interesting are the trade-offs: machine vs explicit integer wrap-around and buffers with maximum ~size(int)/2 vs ~size(int).

Re: I've been writing ring buffers wrong all these years

#46
post #4

> Join me next week for the exciting sequel to this post, "I've been tying my shoelaces wrong all these years". Probably. Use the Ian Knot: http://www.fieggen.com/shoelace/ianknot.htm Seriously, spend 20 mins practising this, and you'll never go back to the clumsy old way again.

I love that method, and have used it exclusively for years, but the best thing about Ian's site is the explanation of the Granny Knot: http://www.fieggen.com/shoelace/grannyknot.htm

So many people walk around assuming they need to do complicated double knots to stop their shoelaces untying themselves. If only they knew they were doing Granny Knots, and that a standard knot is perfectly secure if tied properly.

Re: I've been writing ring buffers wrong all these years

#47

My C is rusty, but won't this act... oddly... on integer overflow? size() { return write - read; } 0 - UINT_MAX -1 = ? [EDIT] Changed constant to reflect use of unsigned integers, which I forgot to specify initially.

In all examples, `read` and `write` are unsigned, and since they both are the same type, no integer conversions are performed, ergo no overflow.

PS. No wrap-around either, for different reasons.

Re: I've been writing ring buffers wrong all these years

#48

Earlier quoted context omitted.

I never claimed you should use a modulus operation.

You said, > It's unclear to me why the focus on a 2^n sized buffer just so you can use & for the mask. In fact it is required for correctness to use the approach he specified with any choice of masking operation.

Any choice?

He only ever calls mask() after an increment. There are other ways of detecting the overflow and wrap to 0 that don't involve modulus.

Re: I've been writing ring buffers wrong all these years

#50
post #4

> Join me next week for the exciting sequel to this post, "I've been tying my shoelaces wrong all these years". Probably. Use the Ian Knot: http://www.fieggen.com/shoelace/ianknot.htm Seriously, spend 20 mins practising this, and you'll never go back to the clumsy old way again.

I prefer the double slipknot (mentioned below as Ian's Secure Knot). I started doing it for basketball, but it not only looks better (more even) on normal, dress shoes, but it neves come off on its own (but is easy to pull apart voluntarily). Also, it's not more complicated than a normal knot, it's more or less doing it "twice, in reverse".
Post reply on HN