Open5
miniio: リングバッファの実装
手動でリングバッファを実装するとか何年ぶりだよ。。という感じなので図を書いて整理。。
リングバッファの構成
リングバッファ...といっても、実際のメモリは環状にできないのでポインタの集合で表現することになる。
-
len
- リングバッファ全体のサイズ -
readptr
- リングバッファの読み取りポインタ -
writeptr
- リングバッファの書き込みポインタ
今回の場合は、オーバーフローは発生させないと仮定してよい。
readptr
< writeptr
(ただし writeptr
!= len
)ケース
これはtrivial。
- write側:
len
-writeptr
のサイズまで一度に書き出せる。 - read側:
writeptr
-readptr
のサイズのデータが読める。
writeptr
== len
ケース
既に読み終わっているところにデータが書けるケース。
- write側:
readptr
のサイズまで一度に書き出せる - read側:
len
-readptr
のサイズのデータが読める
readptr
== 0 ケース
自然に、 readptr
== 0であればバッファが満杯のケースと言える。(場合分けは不要だが、このタイミングでのゼロ長のwriteには注意が必要 -- 後述)
writeptr
< readptr
ケース
バッファの途中に書けるケース。
- write側:
readptr
-writeptr
のサイズまで一度に書き出せる - read側:
len
- (readptr
-writeptr
) のサイズのデータが読み出せる
writeptr
== readptr
ケース
これだけ場合分けが必要。
readptr
== writeptr
== 0 の場合
このケースは、バッファが空っぽであることを表現する。 場合分けが必要 。つまり、 読み取りによって readptr
== writeptr
となった場合はゼロにリセットする と約束する必要がある。
readptr
!= 0 の場合
このケースでは、バッファがいっぱいであることを表現する。↑の場合分けを実現するため、 ゼロ長のwriteではポインタを更新しない と約束する必要がある。そうしないと、 readptr
== 0、 writeptr
== len
のときにゼロ長の書き込みをすると readptr
== writeptr
== 0 になってしまう。