Skip to content

Commit

Permalink
メソッド群にコメントを追加した
Browse files Browse the repository at this point in the history
  • Loading branch information
yuezato committed Apr 19, 2019
1 parent de1b5f1 commit 84510a6
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 113 deletions.
10 changes: 5 additions & 5 deletions src/storage/data_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ impl<N> DataRegion<N>
where
N: NonVolatileMemory,
{
#[allow(dead_code)]
pub(crate) fn allocator(&self) -> &DataPortionAllocator {
&self.allocator
}

/// 新しい`DataRegion`インスタンスを生成する.
pub fn new(metric_builder: &MetricBuilder, allocator: DataPortionAllocator, nvm: N) -> Self {
let capacity = allocator.metrics().capacity_bytes;
Expand Down Expand Up @@ -108,6 +103,11 @@ where
fn block_count(&self, size: u32) -> u32 {
(size + u32::from(self.block_size.as_u16()) - 1) / u32::from(self.block_size.as_u16())
}

// The following methods are for unit tests.
pub(crate) fn allocator(&self) -> &DataPortionAllocator {
&self.allocator
}
}

#[derive(Debug, Clone)]
Expand Down
103 changes: 86 additions & 17 deletions src/storage/journal/delayed_release_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ use std::vec::Vec;
use storage::portion::{DataPortion, DataPortionU64};

/// 削除操作によって消されたDataPortionを表すためのVec<DataPortion64>に対するnew type。
///
/// DataPortionではなくDataPortionU64を用いるのは、
/// Portionに対してPortionU64に対するのと同様の理由で、
/// 可能な限りメモリ上の表現を圧縮したいため。
#[derive(Debug, Clone)]
struct DataPortion64s(Vec<DataPortionU64>);

Expand All @@ -14,34 +18,50 @@ impl DataPortion64s {
}

/// 遅延解放のために必要になる情報と操作を集約する構造体。
///
/// 主要なメソッドの役割は以下の通り:
/// * set_initial_delete_recordsメソッド
/// * 幾つの削除レコードが起動時に見つかったか(=open時に永続化が確定しているか)を保存する。
/// * このメソッドは高々一度しか呼び出せない。
/// * detect_new_synced_delete_recordsメソッド
/// * GCキューに削除レコードが幾つ追加されたか(=幾つの削除レコードが永続化したか)を保存する。
/// * このメソッドは何度呼び出されても良い。
/// * insert_data_portionsメソッド
/// * open以降に、「単発の」Delete及びDeleteRangeメソッドで解放対象となったデータポーション群を順序付け、バッファに保存する。
/// * (take_)releasable_data_portionsメソッド
/// 1. set_initial_delete_recordsメソッドと, detect_new_synced_delete_recordsメソッドにより
/// この構造体は幾つの削除レコードが「open以降に」永続化されたか分かる。この数をNとする。
/// 2. insert_data_portionsメソッドでバッファに保存したデータポーション群のうち、前からN個は安全に解放可能であるので、
/// これを返す。
#[derive(Debug)]
pub struct DelayedReleaseInfo {
// ジャーナル領域をopenした以降に追加したDelete及びDeleteRangeレコードで、永続化が確定済みのものの数
// ジャーナル領域をopenした以降に追加したDelete及びDeleteRangeレコードで、永続化が確定済み(解放可能)のものの数。
num_of_releasable_delete_records: usize,
// ジャーナル領域のrestore時に処理済みのDelete及びDeleteRangeレコードで、未だGCキューに投入されていないものの数
// ジャーナル領域のrestore時に処理済みのDelete及びDeleteRangeレコードで、未だGCキューに投入されていないものの数
num_of_unqueued_initial_delete_records: usize,
// 永続化済みのDelete及びDeleteRangeレコードに紐づく、解放可能なPortionを表現するための集合
// 永続化済みのDelete及びDeleteRangeレコードに紐づく、解放可能なPortionを表現するための集合
entries: Vec<DataPortion64s>,
already_set_initial_delete_records_called: bool,
}
impl DelayedReleaseInfo {
pub fn new() -> Self {
DelayedReleaseInfo {
num_of_releasable_delete_records: 0,
num_of_unqueued_initial_delete_records: 0,
entries: Vec::new(),
already_set_initial_delete_records_called: false,
}
}

#[allow(dead_code)]
pub(in storage::journal) fn num_of_releasable_delete_records(&self) -> usize {
self.num_of_releasable_delete_records
}

#[allow(dead_code)]
pub(in storage::journal) fn num_of_unqueued_initial_delete_records(&self) -> usize {
self.num_of_unqueued_initial_delete_records
}

/// 安全に解放可能なデータポーションの一覧を返す。
/// このメソッドは非破壊的である。すなわち次が成立する:
/// ```#[ignore]
/// use storage::portion::{DataPortion, DataPortionU64};
/// ...
/// let portions1 = info.releasable_data_portions();
/// let portions2 = info.releasable_data_portions();
/// assert_eq!(portions1, portions2);
/// ```
pub fn releasable_data_portions(&self) -> Vec<DataPortion> {
let n = self.num_of_releasable_delete_records;
(&self.entries)[..n]
Expand All @@ -50,6 +70,14 @@ impl DelayedReleaseInfo {
.collect()
}

/// 安全に解放可能なデータポーションの一覧を返し、かつ内部バッファを消去する。
/// このメソッドは破壊的であり、すなわち次が成立する:
/// ```#[ignore]
/// let info = DelayedReleaseInfo::new();
/// ...
/// let portions = info.take_releasable_data_portions();
/// assert_eq!(info.releasable_data_portions(), vec![]);
/// ```
pub fn take_releasable_data_portions(&mut self) -> Vec<DataPortion> {
let n = self.num_of_releasable_delete_records;
self.num_of_releasable_delete_records = 0;
Expand All @@ -59,10 +87,20 @@ impl DelayedReleaseInfo {
.collect()
}

/// ジャーナル領域のrestore処理中に見つけたDeleteレコードとDeleteRangeレコードの総数を記録するためのメソッド。
pub fn set_initial_delete_records(&mut self, u: usize) {
self.num_of_unqueued_initial_delete_records = u;
if !self.already_set_initial_delete_records_called {
self.num_of_unqueued_initial_delete_records = u;
self.already_set_initial_delete_records_called = true;
} else {
panic!("set_initial_delete_records has been called in multiple times");
}
}

/// 永続化が確定したDeleteレコードとDeleteRangeレコードを
/// 「新たに」`u`個見つけた場合に呼び出して登録するためのメソッド。
///
/// 既に発見したDelete(Range)レコードを登録しないように、呼び出し側が注意する必要がある。
pub fn detect_new_synced_delete_records(&mut self, u: usize) {
if self.num_of_unqueued_initial_delete_records == 0 {
self.num_of_releasable_delete_records += u;
Expand All @@ -75,11 +113,27 @@ impl DelayedReleaseInfo {
}
}

/// 削除操作が行われて、LumpIndexから外れたデータポーション群を内部バッファに登録するためのメソッド。
///
/// 注意:
/// * このメソッドは、個別のDelete及びDeleteRange毎に呼び出す必要がある。
/// * 複数のDelete及びDeleteRangeの結果外れたデータポーション群をまとめて登録してはならない。
pub fn insert_data_portions(&mut self, portions: Vec<DataPortion>) {
self.entries.push(DataPortion64s(
portions.into_iter().map(Into::into).collect(),
));
}

// 以下はユニットテスト用のメソッド
#[allow(dead_code)]
pub(crate) fn num_of_releasable_delete_records(&self) -> usize {
self.num_of_releasable_delete_records
}

#[allow(dead_code)]
pub(crate) fn num_of_unqueued_initial_delete_records(&self) -> usize {
self.num_of_unqueued_initial_delete_records
}
}

#[cfg(test)]
Expand Down Expand Up @@ -123,10 +177,10 @@ mod tests {
fn num_of_releasable_delete_records_reflects_correct_number() -> TestResult {
let mut info = DelayedReleaseInfo::new();

// Journal領域のopen中に、併せて5つのDeleteまたはDeleteRangeレコードとする
// Journal領域のopen中に、併せて5つのDeleteまたはDeleteRangeレコードを発見したとする
info.set_initial_delete_records(5);

// fill_gc_queue中に、3つのDeleteまたはDeleteRangeレコードを見つけたとする
// fill_gc_queue中に、3つの永続化されたDeleteまたはDeleteRangeレコードを見つけたとする
info.detect_new_synced_delete_records(3);

// open時にみつけたDeleteまたはDeleteRangeレコードのうち
Expand Down Expand Up @@ -154,24 +208,35 @@ mod tests {
fn releasable_data_portions_works() -> TestResult {
let mut info = DelayedReleaseInfo::new();

// Journal領域のopen中に、併せて2つのDeleteまたはDeleteRangeレコードを発見したとする。
info.set_initial_delete_records(2);

// 解放可能か不明なデータポーションが3つ登録されたとする。
info.insert_data_portions(vec![make_dataportion(0, 0)]);
info.insert_data_portions(vec![make_dataportion(1, 1)]);
info.insert_data_portions(vec![make_dataportion(2, 2)]);

// (fill_gc_queueなどで)1つの永続化済みDeleteまたはDeleteRangeレコードを発見した。
// これはopen中に見つけたDelete(Range)レコードの1つ目に対応する。
info.detect_new_synced_delete_records(1);
assert_eq!(info.releasable_data_portions(), vec![]);

// 新たに2つの永続化済みDeleteまたはDeleteRangeレコードを発見した。
// open中に見つけた2つ目のDelete(Range)レコードに加えて、
// open以降に新たに削除されたレコードも見つけられたことを意味する。
info.detect_new_synced_delete_records(2);
assert_eq!(
info.releasable_data_portions(),
vec![make_dataportion(0, 0)]
);

// 解放可能化不明なデータポーション群が1つ登録されたとする。
// 実際にはDeleteRangeにより一括で複数削除されることに対応する。
let portions: Vec<DataPortion> = (20..30).map(|i| make_dataportion(i, i)).collect();

info.insert_data_portions(portions.clone());

// 新たに3つの永続化済みDeleteまたはDeleteRangeレコードを発見した。
// 全ての内部バッファに登録済みの領域が安全に解放可能な状態に到達したことに等しい。
info.detect_new_synced_delete_records(3);

let mut tmp = vec![
Expand All @@ -186,6 +251,10 @@ mod tests {
}

#[test]
/*
* releasable_data_portions_worksと類似したテストの
* take_releasable_data_portionsバージョン。
*/
fn take_releasable_data_portions_works() -> TestResult {
let mut info = DelayedReleaseInfo::new();

Expand Down
2 changes: 1 addition & 1 deletion src/storage/journal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub use self::options::JournalRegionOptions;
pub use self::record::{JournalEntry, JournalRecord};
pub use self::region::JournalRegion;

pub mod delayed_release_info;
mod delayed_release_info;
mod header;
mod nvm_buffer;
mod options;
Expand Down
Loading

0 comments on commit 84510a6

Please sign in to comment.