How it works¶
This section shows different buffer corner cases and provides basic understanding how data are managed internally.
Let’s start with reference of abbreviations in picture:
R
represents Read pointer. Read on read/write operations. Modified on read operation onlyW
represents Write pointer. Read on read/write operations. Modified on write operation onlyS
represents Size of buffer. Used on all operations, never modified (atomic value)Valid number of
W
andR
pointers are between0
andS - 1
Buffer size is
S = 8
, thus valid number range forW
andR
pointers is0 - 7
.R
andW
numbers overflow atS
, thus valid range is always0, 1, 2, 3, ..., S - 2, S - 1, 0, 1, 2, 3, ..., S - 2, S - 1, 0, ...
Example
S = 4
:0, 1, 2, 3, 0, 1, 2, 3, 0, 1, ...
Maximal number of bytes buffer can hold is always
S - 1
, thus example buffer can hold up to7
bytesR
andW
pointers always point to the next read/write operationWhen
W == R
, buffer is considered empty.When
W == R - 1
, buffer is considered full.W == R - 1
is valid only ifW
andR
overflow at buffer sizeS
.Always add
S
to calculated number and then use modulusS
to get final value
Note
Example 1, add 2
numbers: 2 + 3 = (3 + 2 + S) % S = (3 + 2 + 4) % 4 = (5 + 4) % 4 = 1
Example 2, subtract 2
numbers: 2 - 3 = (2 - 3 + S) % S = (2 - 3 + 4) % 4 = (-1 + 4) % 4 = 3
Different image cases:
Case A: Buffer is empty as
W == R = 0 == 0
Case B: Buffer holds
W - R = 4 - 0 = 4
bytes asW > R
Case C: Buffer is full as
W == R - 1
or7 == 0 - 1
or7 = (0 - 1 + S) % S = (0 - 1 + 8) % 8 = (-1 + 8) % 8 = 7
R
andW
can holdS
different values, from0
toS - 1
, that is modulus ofS
Buffer holds
W - R = 7 - 0 = 7
bytes asW > R
Case D: Buffer holds
S - (R - W) = 8 - (5 - 3) = 6
bytes asR > W
Case E: Buffer is full as
W == R - 1
(4 = 5 - 1
) and holdsS - (R - W) = 8 - (5 - 4) ) = 7
bytes