I see two possible ways around this.
The first keeps the same capacity for your queue but requires that the capacity must be less than 255.
The idea is to write exactly as you are now but, rather than looking for the lowest number, you first look for the discontinuity in the sequence, the point where the difference from one cell to the next is not one. Taking your initial situation:
FA FB FC FD FE
00 FB FC FD FE (discontinuous at fe->fa, use fa)
00 01 FC FD FE (discontinuous at 00->fb, use fb)
00 01 02 FD FE (discontinuous at 01->fc, use fc)
The reason why it needs to be less that 255 is that, once it's that big, there is no discontinuity, because the numbers will wrap around exactly once each cycle.
Another way is to simply use the special marker ff
to indicate the next free slot no matter what.
The way this works is that, whenever you write a record to an entry, you also write the next entry but with an ff
marker.
Then, to find the next entry to populate, you simply look for the first ff
. In the startup phase, there will be multiple ff
markers and you just choose the first but once they're exhausted, each write will give you another one:
ff ff ff ff ff ff
00 ff ff ff ff ff
00 01 ff ff ff ff
00 01 02 ff ff ff
00 01 02 03 ff ff
00 01 02 03 04 ff
ff 01 02 03 04 05
06 ff 02 03 04 05
This reduces your circular buffer capacity by one and results in twice as many reads as the original scheme so I'd prefer the first scheme above for minimal writes.
However, if you want larger buffers (greater than 254 elements), this is one way to achieve it.