NEPLg2 Standard Library - ringbuffer - ringbuffer
Web Playground
Web Playground

ringbuffer

固定長こていちょう循環じゅんかんバッファをもちいた FIFO 基盤きばん

目的もくてき

  • push_back / pop_front / peek_frontそなえた FIFO 基盤きばん提供ていきょうします。
  • queue内部実装ないぶじっそうとして使つかえる、まえから構造こうぞう提供ていきょうします。

実装じっそう

  • ヘッダ [len, cap, head, data_ptr] を 16 byte の領域りょういきとして保持ほじします。
  • 要素ようそ本体ほんたいMemPtr<.T>管理かんりし、容量ようりょう不足ぶそくは 2 ばい拡張かくちょうします。
  • 循環じゅんかん順序じゅんじょheadlen から論理順ろんりじゅん計算けいさんします。

注意ちゅうい

  • RingBuffer<.T>内部ないぶヘッダと要素ようそ領域りょういき所有権しょゆうけんちます。
  • ringbuffer_push_back更新後こうしんごRingBuffer<.T>Resultかえします。
  • 拡張かくちょう発生はっせいすると、内部ないぶデータ領域りょういき番地ばんちわりえます。
  • ringbuffer_free 再利用さいりよう禁止きんしです。

計算量けいさんりょう

  • len / is_empty / peek_front / pop_front は O(1) です。
  • push_back償却しょうきゃく O(1)、拡張かくちょう発生時はっせいじ最悪さいあく時間じかん計算量けいさんりょうは O(n) です。

RingBuffer

FIFO をささえる循環じゅんかんバッファの所有者しょゆうしゃ

目的もくてき

  • [len, cap, head, data_ptr] ヘッダと要素ようそ領域りょういき一体いったいとしてあつか所有者しょゆうしゃです。

注意ちゅうい

  • あたいを move すると所有権しょゆうけんも move します。
  • copy 前提ぜんてい軽量けいりょうハンドルではありません。
  • ringbuffer_free責任せきにん所有しょゆうしているがわにあります。

ringbuffer_header_len_ptr

length らん

目的もくてき

  • ヘッダ先頭せんとうの length らんMemPtr<i32> としてます。

実装じっそう

  • hdr の raw address をそのまま MemPtr<i32> としてつつみます。

注意ちゅうい

  • 公開こうかい API ではなく、RingBuffer 内部ないぶ補助ほじょです。

計算量けいさんりょう

  • O(1)

ringbuffer_header_cap_ptr

capacity らん

目的もくてき

  • ヘッダちゅうの capacity らんMemPtr<i32> としてます。

実装じっそう

  • ヘッダ先頭せんとうから 4 byte すすめた位置いちかえします。

注意ちゅうい

  • 公開こうかい API ではなく、RingBuffer 内部ないぶ補助ほじょです。

計算量けいさんりょう

  • O(1)

ringbuffer_header_head_ptr

head らん

目的もくてき

  • 先頭せんとう要素ようそ論理位置ろんりいちあらわhead らんMemPtr<i32> としてます。

実装じっそう

  • ヘッダ先頭せんとうから 8 byte すすめた位置いちかえします。

注意ちゅうい

  • 公開こうかい API ではなく、RingBuffer 内部ないぶ補助ほじょです。

計算量けいさんりょう

  • O(1)

ringbuffer_header_data_ptr_ptr

data pointer らん

目的もくてき

  • 要素ようそ領域りょういきの raw address を保持ほじするらんMemPtr<i32> としてます。

実装じっそう

  • ヘッダ先頭せんとうから 12 byte すすめた位置いちかえします。

注意ちゅうい

  • 公開こうかい API ではなく、RingBuffer 内部ないぶ補助ほじょです。

計算量けいさんりょう

  • O(1)

ringbuffer_new

既定きてい容量ようりょうからバッファをつく

目的もくてき

  • 既定きてい容量ようりょう 8 のから RingBuffer<.T>作成さくせいします。

実装じっそう

  • ringbuffer_with_capacity 8びます。

注意ちゅうい

  • 失敗しっぱいResult::Err Diag としてかえります。

計算量けいさんりょう

  • O(1)

ringbuffer_with_capacity

初期しょき容量ようりょう指定していして作成さくせいする

目的もくてき

  • すくなくとも initial_cap 保持ほじできるから RingBuffer<.T>作成さくせいします。

実装じっそう

  • 容量ようりょう 1 未満みまんは 1 にげます。
  • 16 byte のヘッダと cap * size_of<.T> byte の要素ようそ領域りょういき別々べつべつ確保かくほします。

注意ちゅうい

  • 確保かくほ失敗しっぱいした場合ばあいdiag_out_of_memoryかえします。
  • ヘッダ確保かくほ失敗しっぱいした場合ばあい、すでに確保かくほしたデータ領域りょういき解放かいほうしてから失敗しっぱいします。

計算量けいさんりょう

  • O(1)

ringbuffer_len

要素数ようそすうかえ

目的もくてき

  • 現在げんざい保持ほじしている要素数ようそすうかえします。

実装じっそう

  • ヘッダの length らんむだけです。

注意ちゅうい

  • 変更へんこうともなわないり API です。

計算量けいさんりょう

  • O(1)

ringbuffer_push_back

末尾まつび追加ついかする

目的もくてき

  • 末尾まつびitem追加ついかし、更新後こうしんごRingBuffer<.T>かえします。

実装じっそう

  • きがあれば tail = (head + len) mod cap直接ちょくせつみます。
  • 満杯まんぱいなら 2 ばい拡張かくちょうし、論理順ろんりじゅんどおりにならえてから追加ついかします。

注意ちゅうい

  • 拡張かくちょうきると head は 0 にもどります。
  • 更新後こうしんごRingBuffer<.T>前提ぜんていなので、pipe 記法きほうでは |> push_back ... |> uwok のように束縛そくばくなおします。

計算量けいさんりょう

  • 償却しょうきゃく O(1)、拡張かくちょう発生時はっせいじ最悪さいあく時間じかん計算量けいさんりょうは O(n) です。

ringbuffer_pop_front

先頭せんとうから

目的もくてき

  • 先頭せんとう要素ようそし、存在そんざいしなければ Noneかえします。

実装じっそう

  • len == 0 なら Noneかえします。
  • 要素ようそがある場合ばあいhead 位置いちみ、head = (head + 1) mod caplen - 1更新こうしんします。

注意ちゅうい

  • 要素ようそ物理位置ぶつりいち循環じゅんかんしているので、配列はいれつの 0 ばんとはかぎりません。

計算量けいさんりょう

  • O(1)

ringbuffer_peek_front

先頭せんとう

目的もくてき

  • 先頭せんとう要素ようそ削除さくじょせずに参照さんしょうします。

実装じっそう

  • head 位置いちみ、その要素ようそだけをかえします。

注意ちゅうい

  • からなら Noneかえします。

計算量けいさんりょう

  • O(1)

ringbuffer_clear

内容ないようからにする

目的もくてき

  • 保持ほじしている要素数ようそすうを 0 にもどしてからバッファにします。

実装じっそう

  • len = 0head = 0 だけをえます。

注意ちゅうい

  • 容量ようりょう確保かくほずみメモリは維持いじされます。

計算量けいさんりょう

  • O(1)

ringbuffer_free

内部ないぶメモリを解放かいほうする

目的もくてき

  • 要素ようそ領域りょういきとヘッダ領域りょういき両方りょうほう解放かいほうします。

実装じっそう

  • cap * size_of<.T> byte の要素ようそ領域りょういきdealloc_ptr<.T> し、そのあとで 16 byte のヘッダを dealloc_ptr<u8> します。

注意ちゅうい

  • 解放後かいほうごrb再利用さいりようしてはいけません。

計算量けいさんりょう

  • O(1)