From 7a331c47abfea694e27477bfe4a91ed9d49b677d Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Mon, 10 Jun 2019 13:00:25 +0800 Subject: [PATCH 01/35] test_generate_filename supports windows --- src/db/filename.rs | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/db/filename.rs b/src/db/filename.rs index cd0c5da..5bafa74 100644 --- a/src/db/filename.rs +++ b/src/db/filename.rs @@ -132,29 +132,32 @@ mod tests { fn test_generate_filename() { let dirname = "test"; let mut tests = if cfg!(windows) { - vec![ - (FileType::Log, 10, "test\\000010.log"), - (FileType::Lock, 1, "test\\LOCK"), - (FileType::Table, 123, "test\\000123.sst"), - (FileType::Manifest, 9, "test\\MANIFEST-000009"), - (FileType::Current, 1, "test\\CURRENT"), - (FileType::Temp, 100, "test\\000100.dbtmp"), - (FileType::InfoLog, 1, "test\\LOG"), - (FileType::OldInfoLog, 1, "test\\LOG.old"), - ] + let tests_windows = vec![ + (FileType::Log, 10, "test\\000010.log"), + (FileType::Lock, 1, "test\\LOCK"), + (FileType::Table, 123, "test\\000123.sst"), + (FileType::Manifest, 9, "test\\MANIFEST-000009"), + (FileType::Current, 1, "test\\CURRENT"), + (FileType::Temp, 100, "test\\000100.dbtmp"), + (FileType::InfoLog, 1, "test\\LOG"), + (FileType::OldInfoLog, 1, "test\\LOG.old"), + ]; + tests_windows } else { - vec![ - (FileType::Log, 10, "test/000010.log"), - (FileType::Lock, 1, "test/LOCK"), - (FileType::Table, 123, "test/000123.sst"), - (FileType::Manifest, 9, "test/MANIFEST-000009"), - (FileType::Current, 1, "test/CURRENT"), - (FileType::Temp, 100, "test/000100.dbtmp"), - (FileType::InfoLog, 1, "test/LOG"), - (FileType::OldInfoLog, 1, "test/LOG.old"), - ] + let tests_unix = vec![ + (FileType::Log, 10, "test/000010.log"), + (FileType::Lock, 1, "test/LOCK"), + (FileType::Table, 123, "test/000123.sst"), + (FileType::Manifest, 9, "test/MANIFEST-000009"), + (FileType::Current, 1, "test/CURRENT"), + (FileType::Temp, 100, "test/000100.dbtmp"), + (FileType::InfoLog, 1, "test/LOG"), + (FileType::OldInfoLog, 1, "test/LOG.old"), + ]; + tests_unix }; - + + for (ft, seq, expect) in tests.drain(..) { let name = generate_filename(dirname, ft, seq); assert_eq!(name.as_str(), expect); From b4e360f18c07a15f10572c2e68385d3db43b9074 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Mon, 10 Jun 2019 20:23:31 +0800 Subject: [PATCH 02/35] te2 tests's functions supports windows --- src/db/filename.rs | 90 +++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/src/db/filename.rs b/src/db/filename.rs index 5bafa74..fa9057c 100644 --- a/src/db/filename.rs +++ b/src/db/filename.rs @@ -124,6 +124,9 @@ pub fn update_current(env: &S, dbname: &str, manifest_file_num: u64) result } + + + #[cfg(test)] mod tests { use super::*; @@ -132,7 +135,7 @@ mod tests { fn test_generate_filename() { let dirname = "test"; let mut tests = if cfg!(windows) { - let tests_windows = vec![ + vec![ (FileType::Log, 10, "test\\000010.log"), (FileType::Lock, 1, "test\\LOCK"), (FileType::Table, 123, "test\\000123.sst"), @@ -141,10 +144,10 @@ mod tests { (FileType::Temp, 100, "test\\000100.dbtmp"), (FileType::InfoLog, 1, "test\\LOG"), (FileType::OldInfoLog, 1, "test\\LOG.old"), - ]; - tests_windows + ] + } else { - let tests_unix = vec![ + vec![ (FileType::Log, 10, "test/000010.log"), (FileType::Lock, 1, "test/LOCK"), (FileType::Table, 123, "test/000123.sst"), @@ -153,8 +156,7 @@ mod tests { (FileType::Temp, 100, "test/000100.dbtmp"), (FileType::InfoLog, 1, "test/LOG"), (FileType::OldInfoLog, 1, "test/LOG.old"), - ]; - tests_unix + ] }; @@ -166,48 +168,54 @@ mod tests { #[test] fn test_parse_filename() { + let mut tests = if cfg!(windows) { - vec![ - ("a\\b\\c\\000123.log", Some((FileType::Log, 123))), - ("a\\b\\c\\LOCK", Some((FileType::Lock, 0))), - ("a\\b\\c\\010666.sst", Some((FileType::Table, 10666))), - ("a\\b\\c\\MANIFEST-000009", Some((FileType::Manifest, 9))), - ("a\\b\\c\\000123.dbtmp", Some((FileType::Temp, 123))), - ("a\\b\\c\\CURRENT", Some((FileType::Current, 0))), - ("a\\b\\c\\LOG", Some((FileType::InfoLog, 0))), - ("a\\b\\c\\LOG.old", Some((FileType::OldInfoLog, 0))), - ("a\\b\\c\\test.123", None), - ("a\\b\\c\\LOG.", None), - ("a\\b\\c\\LOG.new", None), - ("a\\b\\c\\000def.log", None), - ("a\\b\\c\\MANIFEST-abcedf", None), - ("a\\b\\c\\MANIFEST", None), - ("a\\b\\c\\MANIFEST-123123-abcdef", None), + vec![ + ("a\\b\\c\\000123.log", Some((FileType::Log, 123))), + ("a\\b\\c\\LOCK", Some((FileType::Lock, 0))), + ("a\\b\\c\\010666.sst", Some((FileType::Table, 10666))), + ("a\\b\\c\\MANIFEST-000009", Some((FileType::Manifest, 9))), + ("a\\b\\c\\000123.dbtmp", Some((FileType::Temp, 123))), + ("a\\b\\c\\CURRENT", Some((FileType::Current, 0))), + ("a\\b\\c\\LOG", Some((FileType::InfoLog, 0))), + ("a\\b\\c\\LOG.old", Some((FileType::OldInfoLog, 0))), + + ("a\\b\\c\\test.123", None), + ("a\\b\\c\\LOG.", None), + ("a\\b\\c\\LOG.new", None), + ("a\\b\\c\\000def.log", None), + ("a\\b\\c\\MANIFEST-abcedf", None), + ("a\\b\\c\\MANIFEST", None), + ("a\\b\\c\\MANIFEST-123123-abcdef", None), ] + } else { - vec![ - ("a/b/c/000123.log", Some((FileType::Log, 123))), - ("a/b/c/LOCK", Some((FileType::Lock, 0))), - ("a/b/c/010666.sst", Some((FileType::Table, 10666))), - ("a/b/c/MANIFEST-000009", Some((FileType::Manifest, 9))), - ("a/b/c/000123.dbtmp", Some((FileType::Temp, 123))), - ("a/b/c/CURRENT", Some((FileType::Current, 0))), - ("a/b/c/LOG", Some((FileType::InfoLog, 0))), - ("a/b/c/LOG.old", Some((FileType::OldInfoLog, 0))), - // invalid conditions - ("a/b/c/test.123", None), - ("a/b/c/LOG.", None), - ("a/b/c/LOG.new", None), - ("a/b/c/000def.log", None), - ("a/b/c/MANIFEST-abcedf", None), - ("a/b/c/MANIFEST", None), - ("a/b/c/MANIFEST-123123-abcdef", None), - ] + vec![ + ("a/b/c/000123.log", Some((FileType::Log, 123))), + ("a/b/c/LOCK", Some((FileType::Lock, 0))), + ("a/b/c/010666.sst", Some((FileType::Table, 10666))), + ("a/b/c/MANIFEST-000009", Some((FileType::Manifest, 9))), + ("a/b/c/000123.dbtmp", Some((FileType::Temp, 123))), + ("a/b/c/CURRENT", Some((FileType::Current, 0))), + ("a/b/c/LOG", Some((FileType::InfoLog, 0))), + ("a/b/c/LOG.old", Some((FileType::OldInfoLog, 0))), + // invalid conditions + ("a/b/c/test.123", None), + ("a/b/c/LOG.", None), + ("a/b/c/LOG.new", None), + ("a/b/c/000def.log", None), + ("a/b/c/MANIFEST-abcedf", None), + ("a/b/c/MANIFEST", None), + ("a/b/c/MANIFEST-123123-abcdef", None), + ] }; - + + for (filename, expect) in tests.drain(..) { let result = parse_filename(filename); assert_eq!(result, expect); } } + + } From 343eb96b43309a8dd760727a104ad4d56c16efe9 Mon Sep 17 00:00:00 2001 From: fullstop000 Date: Mon, 10 Jun 2019 20:47:56 +0800 Subject: [PATCH 03/35] cargo fmt --- src/db/filename.rs | 122 +++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 66 deletions(-) diff --git a/src/db/filename.rs b/src/db/filename.rs index fa9057c..2df5839 100644 --- a/src/db/filename.rs +++ b/src/db/filename.rs @@ -124,9 +124,6 @@ pub fn update_current(env: &S, dbname: &str, manifest_file_num: u64) result } - - - #[cfg(test)] mod tests { use super::*; @@ -135,31 +132,29 @@ mod tests { fn test_generate_filename() { let dirname = "test"; let mut tests = if cfg!(windows) { - vec![ - (FileType::Log, 10, "test\\000010.log"), - (FileType::Lock, 1, "test\\LOCK"), - (FileType::Table, 123, "test\\000123.sst"), - (FileType::Manifest, 9, "test\\MANIFEST-000009"), - (FileType::Current, 1, "test\\CURRENT"), - (FileType::Temp, 100, "test\\000100.dbtmp"), - (FileType::InfoLog, 1, "test\\LOG"), - (FileType::OldInfoLog, 1, "test\\LOG.old"), - ] - + vec![ + (FileType::Log, 10, "test\\000010.log"), + (FileType::Lock, 1, "test\\LOCK"), + (FileType::Table, 123, "test\\000123.sst"), + (FileType::Manifest, 9, "test\\MANIFEST-000009"), + (FileType::Current, 1, "test\\CURRENT"), + (FileType::Temp, 100, "test\\000100.dbtmp"), + (FileType::InfoLog, 1, "test\\LOG"), + (FileType::OldInfoLog, 1, "test\\LOG.old"), + ] } else { - vec![ - (FileType::Log, 10, "test/000010.log"), - (FileType::Lock, 1, "test/LOCK"), - (FileType::Table, 123, "test/000123.sst"), - (FileType::Manifest, 9, "test/MANIFEST-000009"), - (FileType::Current, 1, "test/CURRENT"), - (FileType::Temp, 100, "test/000100.dbtmp"), - (FileType::InfoLog, 1, "test/LOG"), - (FileType::OldInfoLog, 1, "test/LOG.old"), - ] + vec![ + (FileType::Log, 10, "test/000010.log"), + (FileType::Lock, 1, "test/LOCK"), + (FileType::Table, 123, "test/000123.sst"), + (FileType::Manifest, 9, "test/MANIFEST-000009"), + (FileType::Current, 1, "test/CURRENT"), + (FileType::Temp, 100, "test/000100.dbtmp"), + (FileType::InfoLog, 1, "test/LOG"), + (FileType::OldInfoLog, 1, "test/LOG.old"), + ] }; - - + for (ft, seq, expect) in tests.drain(..) { let name = generate_filename(dirname, ft, seq); assert_eq!(name.as_str(), expect); @@ -168,54 +163,49 @@ mod tests { #[test] fn test_parse_filename() { - let mut tests = if cfg!(windows) { - vec![ - ("a\\b\\c\\000123.log", Some((FileType::Log, 123))), - ("a\\b\\c\\LOCK", Some((FileType::Lock, 0))), - ("a\\b\\c\\010666.sst", Some((FileType::Table, 10666))), - ("a\\b\\c\\MANIFEST-000009", Some((FileType::Manifest, 9))), - ("a\\b\\c\\000123.dbtmp", Some((FileType::Temp, 123))), - ("a\\b\\c\\CURRENT", Some((FileType::Current, 0))), - ("a\\b\\c\\LOG", Some((FileType::InfoLog, 0))), - ("a\\b\\c\\LOG.old", Some((FileType::OldInfoLog, 0))), - - ("a\\b\\c\\test.123", None), - ("a\\b\\c\\LOG.", None), - ("a\\b\\c\\LOG.new", None), - ("a\\b\\c\\000def.log", None), - ("a\\b\\c\\MANIFEST-abcedf", None), - ("a\\b\\c\\MANIFEST", None), - ("a\\b\\c\\MANIFEST-123123-abcdef", None), + vec![ + ("a\\b\\c\\000123.log", Some((FileType::Log, 123))), + ("a\\b\\c\\LOCK", Some((FileType::Lock, 0))), + ("a\\b\\c\\010666.sst", Some((FileType::Table, 10666))), + ("a\\b\\c\\MANIFEST-000009", Some((FileType::Manifest, 9))), + ("a\\b\\c\\000123.dbtmp", Some((FileType::Temp, 123))), + ("a\\b\\c\\CURRENT", Some((FileType::Current, 0))), + ("a\\b\\c\\LOG", Some((FileType::InfoLog, 0))), + ("a\\b\\c\\LOG.old", Some((FileType::OldInfoLog, 0))), + ("a\\b\\c\\test.123", None), + ("a\\b\\c\\LOG.", None), + ("a\\b\\c\\LOG.new", None), + ("a\\b\\c\\000def.log", None), + ("a\\b\\c\\MANIFEST-abcedf", None), + ("a\\b\\c\\MANIFEST", None), + ("a\\b\\c\\MANIFEST-123123-abcdef", None), ] - } else { - vec![ - ("a/b/c/000123.log", Some((FileType::Log, 123))), - ("a/b/c/LOCK", Some((FileType::Lock, 0))), - ("a/b/c/010666.sst", Some((FileType::Table, 10666))), - ("a/b/c/MANIFEST-000009", Some((FileType::Manifest, 9))), - ("a/b/c/000123.dbtmp", Some((FileType::Temp, 123))), - ("a/b/c/CURRENT", Some((FileType::Current, 0))), - ("a/b/c/LOG", Some((FileType::InfoLog, 0))), - ("a/b/c/LOG.old", Some((FileType::OldInfoLog, 0))), - // invalid conditions - ("a/b/c/test.123", None), - ("a/b/c/LOG.", None), - ("a/b/c/LOG.new", None), - ("a/b/c/000def.log", None), - ("a/b/c/MANIFEST-abcedf", None), - ("a/b/c/MANIFEST", None), - ("a/b/c/MANIFEST-123123-abcdef", None), - ] + vec![ + ("a/b/c/000123.log", Some((FileType::Log, 123))), + ("a/b/c/LOCK", Some((FileType::Lock, 0))), + ("a/b/c/010666.sst", Some((FileType::Table, 10666))), + ("a/b/c/MANIFEST-000009", Some((FileType::Manifest, 9))), + ("a/b/c/000123.dbtmp", Some((FileType::Temp, 123))), + ("a/b/c/CURRENT", Some((FileType::Current, 0))), + ("a/b/c/LOG", Some((FileType::InfoLog, 0))), + ("a/b/c/LOG.old", Some((FileType::OldInfoLog, 0))), + // invalid conditions + ("a/b/c/test.123", None), + ("a/b/c/LOG.", None), + ("a/b/c/LOG.new", None), + ("a/b/c/000def.log", None), + ("a/b/c/MANIFEST-abcedf", None), + ("a/b/c/MANIFEST", None), + ("a/b/c/MANIFEST-123123-abcdef", None), + ] }; - - + for (filename, expect) in tests.drain(..) { let result = parse_filename(filename); assert_eq!(result, expect); } } - } From f15cc46ad3ac63dae9dcf85a2a161820e97a3b76 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sun, 27 Oct 2019 09:15:27 +0800 Subject: [PATCH 04/35] add some set_*** testcase in version_edit --- src/version/version_edit.rs | 39 +++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index 3bca433..88c98b3 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -435,9 +435,9 @@ mod tests { fn assert_encode_decode(edit: &VersionEdit) { let mut encoded = vec![]; - edit.encode_to(&mut encoded); + edit.encode_to(&mut encoded); let mut parsed = VersionEdit::new(7); - parsed.decoded_from(encoded.as_slice()).expect(""); + parsed.decoded_from(encoded.as_slice()).expect(""); let mut encoded2 = vec![]; parsed.encode_to(&mut encoded2); assert_eq!(encoded, encoded2) @@ -480,6 +480,7 @@ mod tests { let mut edit = VersionEdit::new(7); let filename = String::from("Hello"); edit.set_comparator_name(filename); +<<<<<<< HEAD assert_eq!("Hello", edit.comparator_name.unwrap().as_str()); } @@ -489,11 +490,24 @@ mod tests { let log_num = u64::max_value(); edit.set_log_number(log_num); assert_eq!(edit.log_number.unwrap(), log_num); +======= + assert_eq!("Hello",edit.comparator_name.unwrap().as_str()); + } + + + #[test] + fn test_set_log_number() { + let mut edit = VersionEdit::new(7); + let log_num =u64::max_value(); + edit.set_log_number(log_num); + assert_eq!(edit.log_number.unwrap(),log_num); +>>>>>>> add some set_*** testcase in version_edit } #[test] fn test_set_prev_log_number() { let mut edit = VersionEdit::new(7); +<<<<<<< HEAD let prev_log_num = u64::max_value(); edit.set_prev_log_number(prev_log_num); assert_eq!(edit.prev_log_number.unwrap(), prev_log_num); @@ -513,5 +527,26 @@ mod tests { let last_sequence = u64::max_value(); edit.set_last_sequence(last_sequence); assert_eq!(edit.last_sequence.unwrap(), last_sequence); +======= + let prev_log_num =u64::max_value(); + edit.set_prev_log_number(prev_log_num); + assert_eq!(edit.prev_log_number.unwrap(),prev_log_num); + } + + #[test] + fn test_set_next_file(){ + let mut edit = VersionEdit::new(7); + let next_file =u64::max_value(); + edit.set_next_file(next_file); + assert_eq!(edit.next_file_number.unwrap(),next_file); + } + + #[test] + fn test_set_last_sequence() { + let mut edit = VersionEdit::new(7); + let last_sequence =u64::max_value(); + edit.set_last_sequence(last_sequence); + assert_eq!(edit.last_sequence.unwrap(),last_sequence); +>>>>>>> add some set_*** testcase in version_edit } } From e9e41f879b4bed94c71f9ef76483ea577a2bab80 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Wed, 30 Oct 2019 20:24:13 +0800 Subject: [PATCH 05/35] cargo fmt --- src/version/version_edit.rs | 42 +++++++------------------------------ 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index 88c98b3..04dcf7e 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -435,9 +435,9 @@ mod tests { fn assert_encode_decode(edit: &VersionEdit) { let mut encoded = vec![]; - edit.encode_to(&mut encoded); + edit.encode_to(&mut encoded); let mut parsed = VersionEdit::new(7); - parsed.decoded_from(encoded.as_slice()).expect(""); + parsed.decoded_from(encoded.as_slice()).expect(""); let mut encoded2 = vec![]; parsed.encode_to(&mut encoded2); assert_eq!(encoded, encoded2) @@ -480,7 +480,7 @@ mod tests { let mut edit = VersionEdit::new(7); let filename = String::from("Hello"); edit.set_comparator_name(filename); -<<<<<<< HEAD + assert_eq!("Hello", edit.comparator_name.unwrap().as_str()); } @@ -489,25 +489,17 @@ mod tests { let mut edit = VersionEdit::new(7); let log_num = u64::max_value(); edit.set_log_number(log_num); - assert_eq!(edit.log_number.unwrap(), log_num); -======= - assert_eq!("Hello",edit.comparator_name.unwrap().as_str()); - } + assert_eq!(edit.log_number.unwrap(), log_num); - #[test] - fn test_set_log_number() { - let mut edit = VersionEdit::new(7); - let log_num =u64::max_value(); - edit.set_log_number(log_num); - assert_eq!(edit.log_number.unwrap(),log_num); ->>>>>>> add some set_*** testcase in version_edit } #[test] fn test_set_prev_log_number() { let mut edit = VersionEdit::new(7); -<<<<<<< HEAD + + let prev_log_num =u64::max_value(); + let prev_log_num = u64::max_value(); edit.set_prev_log_number(prev_log_num); assert_eq!(edit.prev_log_number.unwrap(), prev_log_num); @@ -527,26 +519,8 @@ mod tests { let last_sequence = u64::max_value(); edit.set_last_sequence(last_sequence); assert_eq!(edit.last_sequence.unwrap(), last_sequence); -======= - let prev_log_num =u64::max_value(); - edit.set_prev_log_number(prev_log_num); - assert_eq!(edit.prev_log_number.unwrap(),prev_log_num); - } - #[test] - fn test_set_next_file(){ - let mut edit = VersionEdit::new(7); - let next_file =u64::max_value(); - edit.set_next_file(next_file); - assert_eq!(edit.next_file_number.unwrap(),next_file); } - #[test] - fn test_set_last_sequence() { - let mut edit = VersionEdit::new(7); - let last_sequence =u64::max_value(); - edit.set_last_sequence(last_sequence); - assert_eq!(edit.last_sequence.unwrap(),last_sequence); ->>>>>>> add some set_*** testcase in version_edit - } + } From d0b24ea3324d28472d8f8fd550cd167be75d2ad6 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 31 Oct 2019 12:58:53 +0800 Subject: [PATCH 06/35] cargo fmt --check --- src/version/version_edit.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index 04dcf7e..255c427 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -522,5 +522,4 @@ mod tests { } - } From 3489f0a004fca947c2e2219b797a19240b120c36 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Fri, 1 Nov 2019 12:37:09 +0800 Subject: [PATCH 07/35] cargo fmt --check before rustc updated --- src/version/version_edit.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index 255c427..27e7df9 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -521,5 +521,4 @@ mod tests { assert_eq!(edit.last_sequence.unwrap(), last_sequence); } - } From 5634f416eabfbb5339a04cbb3f7d4d89eb579841 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Tue, 5 Nov 2019 19:46:10 +0800 Subject: [PATCH 08/35] parenthesis added --- src/version/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version/mod.rs b/src/version/mod.rs index 17fb11a..0b4287c 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -780,4 +780,4 @@ mod tests { ); } } -} +} \ No newline at end of file From d3fdc3bff1043f34ac26c857c6730aa14b4b1872 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Wed, 6 Nov 2019 20:14:50 +0800 Subject: [PATCH 09/35] cargo fmt --- src/version/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/version/mod.rs b/src/version/mod.rs index 0b4287c..7606add 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -698,6 +698,7 @@ impl Iterator for LevelFileNumIterator { Ok(()) } } +<<<<<<< HEAD #[cfg(test)] mod tests { use super::*; @@ -780,4 +781,6 @@ mod tests { ); } } -} \ No newline at end of file +} +======= +>>>>>>> cargo fmt From 946dcfe80595c9ad39d71d1c93a89243b2ae4870 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sat, 16 Nov 2019 18:28:29 +0800 Subject: [PATCH 10/35] add testcases for Version::find_file --- src/version/mod.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/version/mod.rs b/src/version/mod.rs index 7606add..d7bfb37 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -699,6 +699,9 @@ impl Iterator for LevelFileNumIterator { } } <<<<<<< HEAD +<<<<<<< HEAD +======= +>>>>>>> add testcases for Version::find_file #[cfg(test)] mod tests { use super::*; @@ -706,6 +709,7 @@ mod tests { use crate::util::comparator::BytewiseComparator; use crate::util::slice::Slice; +<<<<<<< HEAD struct FindFileTests { pub files: Vec>, cmp: InternalKeyComparator, @@ -717,24 +721,52 @@ mod tests { let cmp = InternalKeyComparator::new(Arc::new(BytewiseComparator::default())); Self { files, cmp } +======= + struct FileMetaDatas { + pub files: Vec>, + } + + //find_file需要files,这个files是&[Arc],因此需要的是 + + impl FileMetaDatas { + fn new() -> Self { + let files: Vec> = Vec::new(); + Self { files } +>>>>>>> add testcases for Version::find_file } fn generate(&mut self, smallest: &Slice, largest: &Slice) { let mut file = FileMetaData::default(); +<<<<<<< HEAD file.number = self.files.len() as u64 + 1; file.smallest = InternalKey::new(smallest.as_slice(), 100, ValueType::Value); file.largest = InternalKey::new(largest.as_slice(), 100, ValueType::Value); +======= + file.number = (self.files.len() + 1) as u64; + file.smallest = Rc::new(InternalKey::new(smallest, 100, ValueType::Value)); + file.largest = Rc::new(InternalKey::new(largest, 100, ValueType::Value)); +>>>>>>> add testcases for Version::find_file self.files.push(Arc::new(file)); } fn find(&self, key: &Slice) -> usize { +<<<<<<< HEAD let ikey = InternalKey::new(key.as_slice(), 100, ValueType::Value); let target = Slice::from(ikey.data()); Version::find_file(self.cmp.clone(), &self.files, &target.as_slice()) +======= + let target = Slice::from(InternalKey::new(key, 100, ValueType::Value).data()); + let bcmp = Arc::new(InternalKeyComparator::new(Arc::new( + BytewiseComparator::new(), + ))); + + Version::find_file(bcmp, &self.files, &target) +>>>>>>> add testcases for Version::find_file } } #[test] +<<<<<<< HEAD fn test_find_file_with_single_file() { let mut test_suites = FindFileTests::new(); assert_eq!(0, test_suites.find(&Slice::from("Foo"))); @@ -784,3 +816,34 @@ mod tests { } ======= >>>>>>> cargo fmt +======= + fn test_find_file() { + let mut file_metas = FileMetaDatas::new(); + assert_eq!(0, file_metas.find(&Slice::from("Foo"))); + + file_metas.generate(&Slice::from("p"), &Slice::from("q")); + assert_eq!(0, file_metas.find(&Slice::from("a"))); + assert_eq!(0, file_metas.find(&Slice::from("p"))); + assert_eq!(0, file_metas.find(&Slice::from("q"))); + assert_eq!(1, file_metas.find(&Slice::from("q1"))); + assert_eq!(1, file_metas.find(&Slice::from("z"))); + } + + #[test] + fn test_find_files2() { + let mut file_metas = FileMetaDatas::new(); + file_metas.generate(&Slice::from("150"), &Slice::from("200")); + file_metas.generate(&Slice::from("200"), &Slice::from("250")); + file_metas.generate(&Slice::from("300"), &Slice::from("350")); + file_metas.generate(&Slice::from("400"), &Slice::from("450")); + assert_eq!(0, file_metas.find(&Slice::from("100"))); + assert_eq!(0, file_metas.find(&Slice::from("150"))); + assert_eq!(1, file_metas.find(&Slice::from("201"))); + assert_eq!(2, file_metas.find(&Slice::from("251"))); + assert_eq!(2, file_metas.find(&Slice::from("301"))); + assert_eq!(2, file_metas.find(&Slice::from("350"))); + assert_eq!(3, file_metas.find(&Slice::from("351"))); + assert_eq!(4, file_metas.find(&Slice::from("451"))); + } +} +>>>>>>> add testcases for Version::find_file From fb70318fda1c3bf11125912dcd35ce2610c7d112 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sat, 16 Nov 2019 18:47:13 +0800 Subject: [PATCH 11/35] My own comments deleted --- src/version/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/version/mod.rs b/src/version/mod.rs index d7bfb37..dd68bbd 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -726,8 +726,7 @@ mod tests { pub files: Vec>, } - //find_file需要files,这个files是&[Arc],因此需要的是 - + impl FileMetaDatas { fn new() -> Self { let files: Vec> = Vec::new(); From 38564a19ee0e2e0d41a1aa7a72d1d56c7185273e Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sun, 17 Nov 2019 20:50:21 +0800 Subject: [PATCH 12/35] Fix FileMetaDatas.geneerator() error --- src/version/mod.rs | 65 ---------------------------------------------- 1 file changed, 65 deletions(-) diff --git a/src/version/mod.rs b/src/version/mod.rs index dd68bbd..17fb11a 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -698,10 +698,6 @@ impl Iterator for LevelFileNumIterator { Ok(()) } } -<<<<<<< HEAD -<<<<<<< HEAD -======= ->>>>>>> add testcases for Version::find_file #[cfg(test)] mod tests { use super::*; @@ -709,7 +705,6 @@ mod tests { use crate::util::comparator::BytewiseComparator; use crate::util::slice::Slice; -<<<<<<< HEAD struct FindFileTests { pub files: Vec>, cmp: InternalKeyComparator, @@ -721,51 +716,24 @@ mod tests { let cmp = InternalKeyComparator::new(Arc::new(BytewiseComparator::default())); Self { files, cmp } -======= - struct FileMetaDatas { - pub files: Vec>, - } - - - impl FileMetaDatas { - fn new() -> Self { - let files: Vec> = Vec::new(); - Self { files } ->>>>>>> add testcases for Version::find_file } fn generate(&mut self, smallest: &Slice, largest: &Slice) { let mut file = FileMetaData::default(); -<<<<<<< HEAD file.number = self.files.len() as u64 + 1; file.smallest = InternalKey::new(smallest.as_slice(), 100, ValueType::Value); file.largest = InternalKey::new(largest.as_slice(), 100, ValueType::Value); -======= - file.number = (self.files.len() + 1) as u64; - file.smallest = Rc::new(InternalKey::new(smallest, 100, ValueType::Value)); - file.largest = Rc::new(InternalKey::new(largest, 100, ValueType::Value)); ->>>>>>> add testcases for Version::find_file self.files.push(Arc::new(file)); } fn find(&self, key: &Slice) -> usize { -<<<<<<< HEAD let ikey = InternalKey::new(key.as_slice(), 100, ValueType::Value); let target = Slice::from(ikey.data()); Version::find_file(self.cmp.clone(), &self.files, &target.as_slice()) -======= - let target = Slice::from(InternalKey::new(key, 100, ValueType::Value).data()); - let bcmp = Arc::new(InternalKeyComparator::new(Arc::new( - BytewiseComparator::new(), - ))); - - Version::find_file(bcmp, &self.files, &target) ->>>>>>> add testcases for Version::find_file } } #[test] -<<<<<<< HEAD fn test_find_file_with_single_file() { let mut test_suites = FindFileTests::new(); assert_eq!(0, test_suites.find(&Slice::from("Foo"))); @@ -813,36 +781,3 @@ mod tests { } } } -======= ->>>>>>> cargo fmt -======= - fn test_find_file() { - let mut file_metas = FileMetaDatas::new(); - assert_eq!(0, file_metas.find(&Slice::from("Foo"))); - - file_metas.generate(&Slice::from("p"), &Slice::from("q")); - assert_eq!(0, file_metas.find(&Slice::from("a"))); - assert_eq!(0, file_metas.find(&Slice::from("p"))); - assert_eq!(0, file_metas.find(&Slice::from("q"))); - assert_eq!(1, file_metas.find(&Slice::from("q1"))); - assert_eq!(1, file_metas.find(&Slice::from("z"))); - } - - #[test] - fn test_find_files2() { - let mut file_metas = FileMetaDatas::new(); - file_metas.generate(&Slice::from("150"), &Slice::from("200")); - file_metas.generate(&Slice::from("200"), &Slice::from("250")); - file_metas.generate(&Slice::from("300"), &Slice::from("350")); - file_metas.generate(&Slice::from("400"), &Slice::from("450")); - assert_eq!(0, file_metas.find(&Slice::from("100"))); - assert_eq!(0, file_metas.find(&Slice::from("150"))); - assert_eq!(1, file_metas.find(&Slice::from("201"))); - assert_eq!(2, file_metas.find(&Slice::from("251"))); - assert_eq!(2, file_metas.find(&Slice::from("301"))); - assert_eq!(2, file_metas.find(&Slice::from("350"))); - assert_eq!(3, file_metas.find(&Slice::from("351"))); - assert_eq!(4, file_metas.find(&Slice::from("451"))); - } -} ->>>>>>> add testcases for Version::find_file From 0a262c2417134bc00c12a327e8d3975245a672f3 Mon Sep 17 00:00:00 2001 From: Fullstop000 Date: Thu, 21 Nov 2019 14:10:19 +0800 Subject: [PATCH 13/35] re-arrange tests Signed-off-by: Fullstop000 --- src/version/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/version/mod.rs b/src/version/mod.rs index 17fb11a..b4a4d86 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -713,7 +713,13 @@ mod tests { impl FindFileTests { fn new() -> Self { let files: Vec> = Vec::new(); +<<<<<<< HEAD let cmp = InternalKeyComparator::new(Arc::new(BytewiseComparator::default())); +======= + let cmp = Arc::new(InternalKeyComparator::new(Arc::new( + BytewiseComparator::new(), + ))); +>>>>>>> re-arrange tests Self { files, cmp } } From 66966919d61bf5a3a57f3fee6eff9d786e3ba0fd Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 6 Feb 2020 20:29:03 +0800 Subject: [PATCH 14/35] assoicated type in iterator.rs --- src/iterator.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/iterator.rs b/src/iterator.rs index 6cb0447..2e88211 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -25,7 +25,11 @@ use std::mem; /// /// An `Iterator` should be invalid once created pub trait Iterator { +<<<<<<< HEAD type Key; +======= + type Key ; +>>>>>>> assoicated type in iterator.rs type Value; /// An iterator is either positioned at a key/value pair, or /// not valid. This method returns true iff the iterator is valid. @@ -90,7 +94,12 @@ pub trait DerivedIterFactory { fn derive(&self, value: &[u8]) -> Result; } +<<<<<<< HEAD impl, F: DerivedIterFactory> ConcatenateIterator { +======= +impl ConcatenateIterator { + +>>>>>>> assoicated type in iterator.rs pub fn new(origin: I, factory: F) -> Self { Self { origin, @@ -188,12 +197,18 @@ impl, F: DerivedIterFactory> Concatenate } } +<<<<<<< HEAD impl, F: DerivedIterFactory> Iterator for ConcatenateIterator { type Key = <::Iter as Iterator>::Key; type Value = <::Iter as Iterator>::Value; +======= +impl Iterator for ConcatenateIterator { + type Key = Slice; + type Value = Slice; +>>>>>>> assoicated type in iterator.rs fn valid(&self) -> bool { if let Some(di) = &self.derived { di.valid() From 07a7a2cdaa040a517892e2221fab779256e7124b Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Fri, 7 Feb 2020 20:25:42 +0800 Subject: [PATCH 15/35] completed assoicated type implementation --- src/iterator.rs | 19 ++++--------------- src/version/mod.rs | 6 ------ 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/iterator.rs b/src/iterator.rs index 2e88211..c472de1 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -25,11 +25,7 @@ use std::mem; /// /// An `Iterator` should be invalid once created pub trait Iterator { -<<<<<<< HEAD type Key; -======= - type Key ; ->>>>>>> assoicated type in iterator.rs type Value; /// An iterator is either positioned at a key/value pair, or /// not valid. This method returns true iff the iterator is valid. @@ -94,12 +90,10 @@ pub trait DerivedIterFactory { fn derive(&self, value: &[u8]) -> Result; } -<<<<<<< HEAD + impl, F: DerivedIterFactory> ConcatenateIterator { -======= -impl ConcatenateIterator { - ->>>>>>> assoicated type in iterator.rs + + pub fn new(origin: I, factory: F) -> Self { Self { origin, @@ -197,18 +191,13 @@ impl ConcatenateIterator { } } -<<<<<<< HEAD + impl, F: DerivedIterFactory> Iterator for ConcatenateIterator { type Key = <::Iter as Iterator>::Key; type Value = <::Iter as Iterator>::Value; -======= -impl Iterator for ConcatenateIterator { - type Key = Slice; - type Value = Slice; ->>>>>>> assoicated type in iterator.rs fn valid(&self) -> bool { if let Some(di) = &self.derived { di.valid() diff --git a/src/version/mod.rs b/src/version/mod.rs index b4a4d86..17fb11a 100644 --- a/src/version/mod.rs +++ b/src/version/mod.rs @@ -713,13 +713,7 @@ mod tests { impl FindFileTests { fn new() -> Self { let files: Vec> = Vec::new(); -<<<<<<< HEAD let cmp = InternalKeyComparator::new(Arc::new(BytewiseComparator::default())); -======= - let cmp = Arc::new(InternalKeyComparator::new(Arc::new( - BytewiseComparator::new(), - ))); ->>>>>>> re-arrange tests Self { files, cmp } } From d68806e2490347fd2978eab13a4e68c224c5c366 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sun, 9 Feb 2020 12:33:10 +0800 Subject: [PATCH 16/35] completed assoicated type implemenation --- src/db/iterator.rs | 53 ++++++++++++++++++++++++++++++++++++++ src/db/mod.rs | 4 +++ src/sstable/mod.rs | 17 ++++++++++++ src/version/version_set.rs | 45 ++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 0962e5a..54ef72d 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,9 +62,13 @@ pub struct DBIterator { saved_value: Slice, } +<<<<<<< HEAD impl, S: Storage + Clone> Iterator for DBIterator { type Key = Slice; type Value = Slice; +======= +impl, S: Storage + Clone> Iterator for DBIterator { +>>>>>>> completed assoicated type implemenation fn valid(&self) -> bool { self.valid } @@ -183,7 +187,11 @@ impl, S: Storage + Clone> Iterator for D } } +<<<<<<< HEAD impl, S: Storage + Clone> DBIterator { +======= +impl, S: Storage + Clone> DBIterator { +>>>>>>> completed assoicated type implemenation pub fn new(iter: I, db: Arc>, sequence: u64, ucmp: Arc) -> Self { Self { valid: false, @@ -342,12 +350,16 @@ impl DBIteratorCore { } } +<<<<<<< HEAD impl< C: Comparator, M: Iterator, T: Iterator, > KMergeCore for DBIteratorCore { +======= +impl, T: Iterator> KMergeCore for DBIteratorCore { +>>>>>>> completed assoicated type implemenation fn cmp(&self) -> &dyn Comparator { &self.cmp } @@ -392,6 +404,7 @@ impl< index } +<<<<<<< HEAD fn get_child(&self, i: usize) -> &dyn Iterator { if i < self.mem_iters.len() { self.mem_iters.get(i).unwrap() as &dyn Iterator @@ -408,11 +421,29 @@ impl< let current = i - self.mem_iters.len(); self.table_iters.get_mut(current).unwrap() as &mut dyn Iterator +======= + fn get_child(&self, i: usize) -> &dyn Iterator { + if i < self.mem_iters.len() { + self.mem_iters.get(i).unwrap() as &dyn Iterator + } else { + let current = i - self.mem_iters.len(); + self.table_iters.get(current).unwrap() as &dyn Iterator + } + } + + fn get_child_mut(&mut self, i: usize) -> &mut dyn Iterator { + if i < self.mem_iters.len() { + self.mem_iters.get_mut(i).unwrap() as &mut dyn Iterator + } else { + let current = i - self.mem_iters.len(); + self.table_iters.get_mut(current).unwrap() as &mut dyn Iterator +>>>>>>> completed assoicated type implemenation } } fn for_each_child(&mut self, mut f: F) where +<<<<<<< HEAD F: FnMut(&mut dyn Iterator), { self.mem_iters @@ -421,29 +452,51 @@ impl< self.table_iters .iter_mut() .for_each(|i| f(i as &mut dyn Iterator)); +======= + F: FnMut(&mut dyn Iterator), + { + self.mem_iters + .iter_mut() + .for_each(|i| f(i as &mut dyn Iterator)); + self.table_iters + .iter_mut() + .for_each(|i| f(i as &mut dyn Iterator)); +>>>>>>> completed assoicated type implemenation } fn for_not_ith(&mut self, n: usize, mut f: F) where +<<<<<<< HEAD F: FnMut(&mut dyn Iterator, &dyn Comparator), +======= + F: FnMut(&mut dyn Iterator, &dyn Comparator), +>>>>>>> completed assoicated type implemenation { if n < self.mem_iters.len() { for (i, child) in self.mem_iters.iter_mut().enumerate() { if i != n { +<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) +======= + f(child as &mut dyn Iterator, &self.cmp) +>>>>>>> completed assoicated type implemenation } } } else { let current = n - self.mem_iters.len(); for (i, child) in self.table_iters.iter_mut().enumerate() { if i != current { +<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) +======= + f(child as &mut dyn Iterator, &self.cmp) +>>>>>>> completed assoicated type implemenation } } } diff --git a/src/db/mod.rs b/src/db/mod.rs index 7104f72..5f386ea 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1368,7 +1368,11 @@ pub(crate) fn build_table( storage: &S, db_name: &str, table_cache: &TableCache, +<<<<<<< HEAD iter: &mut dyn Iterator, +======= + iter: &mut dyn Iterator, +>>>>>>> completed assoicated type implemenation meta: &mut FileMetaData, ) -> Result<()> { meta.file_size = 0; diff --git a/src/sstable/mod.rs b/src/sstable/mod.rs index 45e541e..16c136f 100644 --- a/src/sstable/mod.rs +++ b/src/sstable/mod.rs @@ -477,7 +477,11 @@ mod tests { // Helper class for tests to unify the interface between // BlockBuilder/TableBuilder and Block/Table trait Constructor { +<<<<<<< HEAD type Iter: Iterator; +======= + type Iter: Iterator; +>>>>>>> completed assoicated type implemenation fn new(is_reversed: bool) -> Self; @@ -588,7 +592,11 @@ mod tests { } } +<<<<<<< HEAD impl> Iterator for KeyConvertingIterator { +======= + impl> Iterator for KeyConvertingIterator { +>>>>>>> completed assoicated type implemenation type Key = Slice; type Value = Slice; fn valid(&self) -> bool { @@ -661,9 +669,14 @@ mod tests { } impl Iterator for EntryIterator { +<<<<<<< HEAD type Key = Slice; type Value = Slice; +======= + type Key = Slice; + type Value = Slice; +>>>>>>> completed assoicated type implemenation fn valid(&self) -> bool { self.current < self.data.len() } @@ -997,7 +1010,11 @@ mod tests { // Return a String represents current entry of the given iterator #[inline] +<<<<<<< HEAD fn format_entry(iter: &dyn Iterator) -> String { +======= + fn format_entry(iter: &dyn Iterator) -> String { +>>>>>>> completed assoicated type implemenation format!("'{:?}->{:?}'", iter.key(), iter.value()) } diff --git a/src/version/version_set.rs b/src/version/version_set.rs index fd4fc28..cb4229b 100644 --- a/src/version/version_set.rs +++ b/src/version/version_set.rs @@ -569,7 +569,11 @@ impl VersionSet { &mut self, db_name: &str, table_cache: TableCache, +<<<<<<< HEAD mem_iter: &mut dyn Iterator, +======= + mem_iter: &mut dyn Iterator, +>>>>>>> completed assoicated type implemenation edit: &mut VersionEdit, ) -> Result<()> { let base = self.current(); @@ -1113,6 +1117,7 @@ impl KMergeCore for SSTableIters { index } +<<<<<<< HEAD fn get_child(&self, i: usize) -> &dyn Iterator { if i < self.level0.len() { self.leveln.get(i).unwrap() as &dyn Iterator @@ -1128,11 +1133,29 @@ impl KMergeCore for SSTableIters { } else { let current = i - self.level0.len(); self.leveln.get_mut(current).unwrap() as &mut dyn Iterator +======= + fn get_child(&self, i: usize) -> &dyn Iterator { + if i < self.level0.len() { + self.leveln.get(i).unwrap() as &dyn Iterator + } else { + let current = i - self.level0.len(); + self.leveln.get(current).unwrap() as &dyn Iterator + } + } + + fn get_child_mut(&mut self, i: usize) -> &mut dyn Iterator { + if i < self.level0.len() { + self.leveln.get_mut(i).unwrap() as &mut dyn Iterator + } else { + let current = i - self.level0.len(); + self.leveln.get_mut(current).unwrap() as &mut dyn Iterator +>>>>>>> completed assoicated type implemenation } } fn for_each_child(&mut self, mut f: F) where +<<<<<<< HEAD F: FnMut(&mut dyn Iterator), { self.level0 @@ -1141,29 +1164,51 @@ impl KMergeCore for SSTableIters { self.leveln .iter_mut() .for_each(|i| f(i as &mut dyn Iterator)); +======= + F: FnMut(&mut dyn Iterator), + { + self.level0 + .iter_mut() + .for_each(|i| f(i as &mut dyn Iterator)); + self.leveln + .iter_mut() + .for_each(|i| f(i as &mut dyn Iterator)); +>>>>>>> completed assoicated type implemenation } fn for_not_ith(&mut self, n: usize, mut f: F) where +<<<<<<< HEAD F: FnMut(&mut dyn Iterator, &dyn Comparator), +======= + F: FnMut(&mut dyn Iterator, &dyn Comparator), +>>>>>>> completed assoicated type implemenation { if n < self.level0.len() { for (i, child) in self.level0.iter_mut().enumerate() { if i != n { +<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) +======= + f(child as &mut dyn Iterator, &self.cmp) +>>>>>>> completed assoicated type implemenation } } } else { let current = n - self.level0.len(); for (i, child) in self.leveln.iter_mut().enumerate() { if i != current { +<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) +======= + f(child as &mut dyn Iterator, &self.cmp) +>>>>>>> completed assoicated type implemenation } } } From 5c14c1675360435d9921cda2f42e79d2eadcf619 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Sun, 9 Feb 2020 13:39:34 +0800 Subject: [PATCH 17/35] fix conflict files --- src/db/iterator.rs | 55 ++------------------------------------------ src/mem/skiplist.rs | 1 + src/sstable/block.rs | 1 + src/sstable/mod.rs | 19 ++------------- 4 files changed, 6 insertions(+), 70 deletions(-) diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 54ef72d..cbe1999 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,13 +62,10 @@ pub struct DBIterator { saved_value: Slice, } -<<<<<<< HEAD + impl, S: Storage + Clone> Iterator for DBIterator { type Key = Slice; type Value = Slice; -======= -impl, S: Storage + Clone> Iterator for DBIterator { ->>>>>>> completed assoicated type implemenation fn valid(&self) -> bool { self.valid } @@ -187,11 +184,7 @@ impl, S: Storage + Clone> Iterator for DBIter } } -<<<<<<< HEAD impl, S: Storage + Clone> DBIterator { -======= -impl, S: Storage + Clone> DBIterator { ->>>>>>> completed assoicated type implemenation pub fn new(iter: I, db: Arc>, sequence: u64, ucmp: Arc) -> Self { Self { valid: false, @@ -350,16 +343,13 @@ impl DBIteratorCore { } } -<<<<<<< HEAD + impl< C: Comparator, M: Iterator, T: Iterator, > KMergeCore for DBIteratorCore { -======= -impl, T: Iterator> KMergeCore for DBIteratorCore { ->>>>>>> completed assoicated type implemenation fn cmp(&self) -> &dyn Comparator { &self.cmp } @@ -404,7 +394,6 @@ impl, T: Iterator &dyn Iterator { if i < self.mem_iters.len() { self.mem_iters.get(i).unwrap() as &dyn Iterator @@ -421,29 +410,11 @@ impl, T: Iterator -======= - fn get_child(&self, i: usize) -> &dyn Iterator { - if i < self.mem_iters.len() { - self.mem_iters.get(i).unwrap() as &dyn Iterator - } else { - let current = i - self.mem_iters.len(); - self.table_iters.get(current).unwrap() as &dyn Iterator - } - } - - fn get_child_mut(&mut self, i: usize) -> &mut dyn Iterator { - if i < self.mem_iters.len() { - self.mem_iters.get_mut(i).unwrap() as &mut dyn Iterator - } else { - let current = i - self.mem_iters.len(); - self.table_iters.get_mut(current).unwrap() as &mut dyn Iterator ->>>>>>> completed assoicated type implemenation } } fn for_each_child(&mut self, mut f: F) where -<<<<<<< HEAD F: FnMut(&mut dyn Iterator), { self.mem_iters @@ -452,51 +423,29 @@ impl, T: Iterator)); -======= - F: FnMut(&mut dyn Iterator), - { - self.mem_iters - .iter_mut() - .for_each(|i| f(i as &mut dyn Iterator)); - self.table_iters - .iter_mut() - .for_each(|i| f(i as &mut dyn Iterator)); ->>>>>>> completed assoicated type implemenation } fn for_not_ith(&mut self, n: usize, mut f: F) where -<<<<<<< HEAD F: FnMut(&mut dyn Iterator, &dyn Comparator), -======= - F: FnMut(&mut dyn Iterator, &dyn Comparator), ->>>>>>> completed assoicated type implemenation { if n < self.mem_iters.len() { for (i, child) in self.mem_iters.iter_mut().enumerate() { if i != n { -<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) -======= - f(child as &mut dyn Iterator, &self.cmp) ->>>>>>> completed assoicated type implemenation } } } else { let current = n - self.mem_iters.len(); for (i, child) in self.table_iters.iter_mut().enumerate() { if i != current { -<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) -======= - f(child as &mut dyn Iterator, &self.cmp) ->>>>>>> completed assoicated type implemenation } } } diff --git a/src/mem/skiplist.rs b/src/mem/skiplist.rs index bc4678e..bc77d25 100644 --- a/src/mem/skiplist.rs +++ b/src/mem/skiplist.rs @@ -266,6 +266,7 @@ pub struct SkiplistIterator { } impl Iterator for SkiplistIterator { + type Key = Slice; type Value = Slice; /// Returns true whether the iterator is positioned at a valid node diff --git a/src/sstable/block.rs b/src/sstable/block.rs index e6f0f17..d4db018 100644 --- a/src/sstable/block.rs +++ b/src/sstable/block.rs @@ -218,6 +218,7 @@ impl BlockIterator { } impl Iterator for BlockIterator { + type Key = Slice; type Value = Slice; #[inline] diff --git a/src/sstable/mod.rs b/src/sstable/mod.rs index 16c136f..ddbd494 100644 --- a/src/sstable/mod.rs +++ b/src/sstable/mod.rs @@ -477,11 +477,7 @@ mod tests { // Helper class for tests to unify the interface between // BlockBuilder/TableBuilder and Block/Table trait Constructor { -<<<<<<< HEAD type Iter: Iterator; -======= - type Iter: Iterator; ->>>>>>> completed assoicated type implemenation fn new(is_reversed: bool) -> Self; @@ -592,11 +588,7 @@ mod tests { } } -<<<<<<< HEAD impl> Iterator for KeyConvertingIterator { -======= - impl> Iterator for KeyConvertingIterator { ->>>>>>> completed assoicated type implemenation type Key = Slice; type Value = Slice; fn valid(&self) -> bool { @@ -669,14 +661,11 @@ mod tests { } impl Iterator for EntryIterator { -<<<<<<< HEAD + type Key = Slice; type Value = Slice; -======= - type Key = Slice; - type Value = Slice; ->>>>>>> completed assoicated type implemenation + fn valid(&self) -> bool { self.current < self.data.len() } @@ -1010,11 +999,7 @@ mod tests { // Return a String represents current entry of the given iterator #[inline] -<<<<<<< HEAD fn format_entry(iter: &dyn Iterator) -> String { -======= - fn format_entry(iter: &dyn Iterator) -> String { ->>>>>>> completed assoicated type implemenation format!("'{:?}->{:?}'", iter.key(), iter.value()) } From e35c113245e54389a8777455b444e1b546b44bcf Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Mon, 10 Feb 2020 14:36:13 +0800 Subject: [PATCH 18/35] fix conflict changes --- src/db/iterator.rs | 4 ++++ src/sstable/block.rs | 3 +++ src/version/version_set.rs | 45 -------------------------------------- 3 files changed, 7 insertions(+), 45 deletions(-) diff --git a/src/db/iterator.rs b/src/db/iterator.rs index cbe1999..866ab67 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,8 +62,12 @@ pub struct DBIterator { saved_value: Slice, } +<<<<<<< HEAD impl, S: Storage + Clone> Iterator for DBIterator { +======= +impl, S: Storage + Clone> Iterator for DBIterator { +>>>>>>> fix conflict changes type Key = Slice; type Value = Slice; fn valid(&self) -> bool { diff --git a/src/sstable/block.rs b/src/sstable/block.rs index d4db018..f35bece 100644 --- a/src/sstable/block.rs +++ b/src/sstable/block.rs @@ -218,7 +218,10 @@ impl BlockIterator { } impl Iterator for BlockIterator { +<<<<<<< HEAD +======= +>>>>>>> fix conflict changes type Key = Slice; type Value = Slice; #[inline] diff --git a/src/version/version_set.rs b/src/version/version_set.rs index cb4229b..fd4fc28 100644 --- a/src/version/version_set.rs +++ b/src/version/version_set.rs @@ -569,11 +569,7 @@ impl VersionSet { &mut self, db_name: &str, table_cache: TableCache, -<<<<<<< HEAD mem_iter: &mut dyn Iterator, -======= - mem_iter: &mut dyn Iterator, ->>>>>>> completed assoicated type implemenation edit: &mut VersionEdit, ) -> Result<()> { let base = self.current(); @@ -1117,7 +1113,6 @@ impl KMergeCore for SSTableIters { index } -<<<<<<< HEAD fn get_child(&self, i: usize) -> &dyn Iterator { if i < self.level0.len() { self.leveln.get(i).unwrap() as &dyn Iterator @@ -1133,29 +1128,11 @@ impl KMergeCore for SSTableIters { } else { let current = i - self.level0.len(); self.leveln.get_mut(current).unwrap() as &mut dyn Iterator -======= - fn get_child(&self, i: usize) -> &dyn Iterator { - if i < self.level0.len() { - self.leveln.get(i).unwrap() as &dyn Iterator - } else { - let current = i - self.level0.len(); - self.leveln.get(current).unwrap() as &dyn Iterator - } - } - - fn get_child_mut(&mut self, i: usize) -> &mut dyn Iterator { - if i < self.level0.len() { - self.leveln.get_mut(i).unwrap() as &mut dyn Iterator - } else { - let current = i - self.level0.len(); - self.leveln.get_mut(current).unwrap() as &mut dyn Iterator ->>>>>>> completed assoicated type implemenation } } fn for_each_child(&mut self, mut f: F) where -<<<<<<< HEAD F: FnMut(&mut dyn Iterator), { self.level0 @@ -1164,51 +1141,29 @@ impl KMergeCore for SSTableIters { self.leveln .iter_mut() .for_each(|i| f(i as &mut dyn Iterator)); -======= - F: FnMut(&mut dyn Iterator), - { - self.level0 - .iter_mut() - .for_each(|i| f(i as &mut dyn Iterator)); - self.leveln - .iter_mut() - .for_each(|i| f(i as &mut dyn Iterator)); ->>>>>>> completed assoicated type implemenation } fn for_not_ith(&mut self, n: usize, mut f: F) where -<<<<<<< HEAD F: FnMut(&mut dyn Iterator, &dyn Comparator), -======= - F: FnMut(&mut dyn Iterator, &dyn Comparator), ->>>>>>> completed assoicated type implemenation { if n < self.level0.len() { for (i, child) in self.level0.iter_mut().enumerate() { if i != n { -<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) -======= - f(child as &mut dyn Iterator, &self.cmp) ->>>>>>> completed assoicated type implemenation } } } else { let current = n - self.level0.len(); for (i, child) in self.leveln.iter_mut().enumerate() { if i != current { -<<<<<<< HEAD f( child as &mut dyn Iterator, &self.cmp, ) -======= - f(child as &mut dyn Iterator, &self.cmp) ->>>>>>> completed assoicated type implemenation } } } From 229810276ed9f07d2b3f2518b8bf81ef8a5a2648 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Mon, 10 Feb 2020 15:06:38 +0800 Subject: [PATCH 19/35] remove unnecessary information --- src/db/iterator.rs | 7 +++++++ src/db/mod.rs | 4 ++++ src/mem/skiplist.rs | 3 +++ src/sstable/mod.rs | 6 ++++++ 4 files changed, 20 insertions(+) diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 866ab67..3c9cfab 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,12 +62,16 @@ pub struct DBIterator { saved_value: Slice, } +<<<<<<< HEAD <<<<<<< HEAD impl, S: Storage + Clone> Iterator for DBIterator { ======= impl, S: Storage + Clone> Iterator for DBIterator { >>>>>>> fix conflict changes +======= +impl, S: Storage + Clone> Iterator for DBIterator { +>>>>>>> remove unnecessary information type Key = Slice; type Value = Slice; fn valid(&self) -> bool { @@ -347,7 +351,10 @@ impl DBIteratorCore { } } +<<<<<<< HEAD +======= +>>>>>>> remove unnecessary information impl< C: Comparator, M: Iterator, diff --git a/src/db/mod.rs b/src/db/mod.rs index 5f386ea..4c547ad 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1368,11 +1368,15 @@ pub(crate) fn build_table( storage: &S, db_name: &str, table_cache: &TableCache, +<<<<<<< HEAD <<<<<<< HEAD iter: &mut dyn Iterator, ======= iter: &mut dyn Iterator, >>>>>>> completed assoicated type implemenation +======= + iter: &mut dyn Iterator, +>>>>>>> remove unnecessary information meta: &mut FileMetaData, ) -> Result<()> { meta.file_size = 0; diff --git a/src/mem/skiplist.rs b/src/mem/skiplist.rs index bc77d25..c1fab8a 100644 --- a/src/mem/skiplist.rs +++ b/src/mem/skiplist.rs @@ -266,7 +266,10 @@ pub struct SkiplistIterator { } impl Iterator for SkiplistIterator { +<<<<<<< HEAD +======= +>>>>>>> remove unnecessary information type Key = Slice; type Value = Slice; /// Returns true whether the iterator is positioned at a valid node diff --git a/src/sstable/mod.rs b/src/sstable/mod.rs index ddbd494..3d49a4d 100644 --- a/src/sstable/mod.rs +++ b/src/sstable/mod.rs @@ -661,11 +661,17 @@ mod tests { } impl Iterator for EntryIterator { +<<<<<<< HEAD type Key = Slice; type Value = Slice; +======= + type Key = Slice; + type Value = Slice; + +>>>>>>> remove unnecessary information fn valid(&self) -> bool { self.current < self.data.len() } From 3f036a7fac13ddc4effe2d5d0819fd45266170b5 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Mon, 10 Feb 2020 16:19:25 +0800 Subject: [PATCH 20/35] added associated type for db --- src/db/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/db/mod.rs b/src/db/mod.rs index 4c547ad..2c4d896 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1518,7 +1518,11 @@ mod tests { db: WickDB, } +<<<<<<< HEAD fn iter_to_string(iter: &dyn Iterator) -> String { +======= + fn iter_to_string(iter: &dyn Iterator) -> String { +>>>>>>> added associated type for db if iter.valid() { format!("{:?}->{:?}", iter.key(), iter.value()) } else { From 731255f69cfbd3c92e9f9fa1d8c79e5334b80536 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 13 Feb 2020 15:23:44 +0800 Subject: [PATCH 21/35] make sure InternalKey live longer than Slice --- src/db/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 2c4d896..3841f5e 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1537,7 +1537,7 @@ mod tests { fn cases(mut opt_hook: F) -> Vec where F: FnMut(Options) -> Options, - { + { vec![ TestOption::Default, TestOption::Reuse, From 1f8cdd8cc0ff3cd17e17f519c70b1932d5889781 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 13 Feb 2020 16:49:52 +0800 Subject: [PATCH 22/35] cargo fmt --- src/db/mod.rs | 14 +------------- src/version/version_set.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 3841f5e..7104f72 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1368,15 +1368,7 @@ pub(crate) fn build_table( storage: &S, db_name: &str, table_cache: &TableCache, -<<<<<<< HEAD -<<<<<<< HEAD iter: &mut dyn Iterator, -======= - iter: &mut dyn Iterator, ->>>>>>> completed assoicated type implemenation -======= - iter: &mut dyn Iterator, ->>>>>>> remove unnecessary information meta: &mut FileMetaData, ) -> Result<()> { meta.file_size = 0; @@ -1518,11 +1510,7 @@ mod tests { db: WickDB, } -<<<<<<< HEAD fn iter_to_string(iter: &dyn Iterator) -> String { -======= - fn iter_to_string(iter: &dyn Iterator) -> String { ->>>>>>> added associated type for db if iter.valid() { format!("{:?}->{:?}", iter.key(), iter.value()) } else { @@ -1537,7 +1525,7 @@ mod tests { fn cases(mut opt_hook: F) -> Vec where F: FnMut(Options) -> Options, - { + { vec![ TestOption::Default, TestOption::Reuse, diff --git a/src/version/version_set.rs b/src/version/version_set.rs index fd4fc28..8a9de31 100644 --- a/src/version/version_set.rs +++ b/src/version/version_set.rs @@ -1032,8 +1032,17 @@ impl DerivedIterFactory for FileIterFactory { } else { let file_number = decode_fixed_64(value); let file_size = decode_fixed_64(&value[std::mem::size_of::()..]); +<<<<<<< HEAD self.table_cache .new_iter(self.icmp.clone(), self.options, file_number, file_size) +======= + self.table_cache.new_iter( + self.icmp.clone(), + self.options, + file_number, + file_size, + ) +>>>>>>> cargo fmt } } } From 85fb6bea0059d4546868d1b54ad8d041a6c21011 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 13 Feb 2020 19:35:24 +0800 Subject: [PATCH 23/35] cargo fmt again --- src/version/version_set.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/version/version_set.rs b/src/version/version_set.rs index 8a9de31..d9d0e14 100644 --- a/src/version/version_set.rs +++ b/src/version/version_set.rs @@ -1032,6 +1032,7 @@ impl DerivedIterFactory for FileIterFactory { } else { let file_number = decode_fixed_64(value); let file_size = decode_fixed_64(&value[std::mem::size_of::()..]); +<<<<<<< HEAD <<<<<<< HEAD self.table_cache .new_iter(self.icmp.clone(), self.options, file_number, file_size) @@ -1043,6 +1044,10 @@ impl DerivedIterFactory for FileIterFactory { file_size, ) >>>>>>> cargo fmt +======= + self.table_cache + .new_iter(self.icmp.clone(), self.options, file_number, file_size) +>>>>>>> cargo fmt again } } } From f3420a7608ba2164519b89f885a4c880be1cc6af Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 23 Apr 2020 17:29:48 +0800 Subject: [PATCH 24/35] add Rotator trait --- src/logger.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/logger.rs b/src/logger.rs index f8cc04a..a740e59 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -18,7 +18,7 @@ use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; use std::sync::Mutex; - +use std::io; /// A `slog` based logger which can be used with `log` crate /// /// See `slog` at https://github.com/slog-rs/slog @@ -64,6 +64,8 @@ impl Logger { }; Self { inner, level } } + + } impl Log for Logger { @@ -153,6 +155,74 @@ impl Drain for FileBasedDrain { } } +trait Rotator: Send { + + /// Check if the option is enabled in configuration. + /// Return true if the `rotator` is valid. + fn is_enabled(&self) -> bool; + + /// Call by operator, initializes the states of rotators. + fn prepare(&mut self, file: &dyn File) -> io::Result<()>; + + /// Return if the file need to be rotated. + fn should_rotate(&self) -> bool; + + /// Call by operator, update rotators' state while the operator try to write some data. + fn on_write(&mut self, data: &[u8]) -> io::Result<()>; + + /// Call by operator, update rotators' state while the operator execute a rotation. + fn on_rotate(&mut self) -> io::Result<()>; + + +} + + +struct RotatedFileBySize { + rotation_size: u64, + file_size: u64 +} + +impl RotatedFileBySize { + fn new(rotation_size: u64) -> Self { + RotatedFileBySize { + rotation_size, + file_size: 0, + } + } +} + +impl Rotator for RotatedFileBySize { + + fn is_enabled(&self) -> bool { + self.rotation_size != 0 + } + + + fn prepare(&mut self, file: &dyn File) -> io::Result<()>{ + self.file_size += file.len().unwrap(); + Ok(()) + } + + + fn should_rotate(&self) -> bool { + self.file_size > self.rotation_size + } + + fn on_write(&mut self, data: &[u8]) -> io::Result<()>{ + self.file_size += data.len() as u64; + Ok(()) + } + + + fn on_rotate(&mut self) -> io::Result<()>{ + self.file_size =0; + Ok(()) + } + + +} + + #[cfg(test)] mod tests { From 5a2ae75cc320af87504b20e67e06599694987344 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Fri, 24 Apr 2020 17:47:25 +0800 Subject: [PATCH 25/35] add add_rotator to FileBaseDrain --- src/logger.rs | 72 ++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 32 deletions(-) diff --git a/src/logger.rs b/src/logger.rs index a740e59..299dbad 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -13,12 +13,14 @@ use crate::db::filename::{generate_filename, FileType}; use crate::storage::{File, Storage}; +use crate::error::Result; use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; use std::sync::Mutex; -use std::io; + + /// A `slog` based logger which can be used with `log` crate /// /// See `slog` at https://github.com/slog-rs/slog @@ -106,8 +108,8 @@ impl Log for Logger { } } } - fn flush(&self) {} + } fn log_to_slog_level(level: log::Level) -> Level { @@ -122,13 +124,34 @@ fn log_to_slog_level(level: log::Level) -> Level { struct FileBasedDrain { inner: Mutex, + rotators:Vec>, } impl FileBasedDrain { fn new(f: F) -> Self { FileBasedDrain { inner: Mutex::new(f), + rotators:vec![], + } + } + + fn add_rotator(mut self,rotator:R) -> Self { + if rotator.is_enabled() { + self.rotators.push(Box::new(rotator)); } + self + } + + + fn flush(&mut self) -> Result<()> { + let mut file = self.inner.lock().unwrap(); + for rotator in self.rotators.iter() { + if rotator.should_rotate(file.len().unwrap()){ + file.flush()? + } + + } + file.flush() } } @@ -140,7 +163,7 @@ impl Drain for FileBasedDrain { &self, record: &slog::Record, values: &slog::OwnedKVList, - ) -> Result { + ) -> std::result::Result { // Ignore errors here let _ = self.inner.lock().unwrap().write( format!( @@ -151,10 +174,15 @@ impl Drain for FileBasedDrain { ) .as_bytes(), ); + + Ok(()) } + + } + trait Rotator: Send { /// Check if the option is enabled in configuration. @@ -162,16 +190,14 @@ trait Rotator: Send { fn is_enabled(&self) -> bool; /// Call by operator, initializes the states of rotators. - fn prepare(&mut self, file: &dyn File) -> io::Result<()>; + // fn prepare(&mut self, file: &dyn File) -> io::Result<()>; /// Return if the file need to be rotated. - fn should_rotate(&self) -> bool; - - /// Call by operator, update rotators' state while the operator try to write some data. - fn on_write(&mut self, data: &[u8]) -> io::Result<()>; + fn should_rotate(&self, size:u64) -> bool; - /// Call by operator, update rotators' state while the operator execute a rotation. - fn on_rotate(&mut self) -> io::Result<()>; + // fn on_write(&mut self, buf:&[u8]) -> Result<()>; + // Call by operator, update rotators' state while the operator execute a rotation. + // fn on_rotate(&mut self) -> Result<()>; } @@ -179,14 +205,14 @@ trait Rotator: Send { struct RotatedFileBySize { rotation_size: u64, - file_size: u64 + // file_size: u64 } impl RotatedFileBySize { fn new(rotation_size: u64) -> Self { RotatedFileBySize { rotation_size, - file_size: 0, + // file_size: 0, } } } @@ -196,30 +222,12 @@ impl Rotator for RotatedFileBySize { fn is_enabled(&self) -> bool { self.rotation_size != 0 } - - - fn prepare(&mut self, file: &dyn File) -> io::Result<()>{ - self.file_size += file.len().unwrap(); - Ok(()) - } - fn should_rotate(&self) -> bool { - self.file_size > self.rotation_size + fn should_rotate(&self,size: u64) -> bool { + size > self.rotation_size } - fn on_write(&mut self, data: &[u8]) -> io::Result<()>{ - self.file_size += data.len() as u64; - Ok(()) - } - - - fn on_rotate(&mut self) -> io::Result<()>{ - self.file_size =0; - Ok(()) - } - - } From f631794407fc63277f710de73e7c620fcba7fe8c Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Wed, 6 May 2020 20:50:36 +0800 Subject: [PATCH 26/35] initially complete `RotatedFileBySize` --- Cargo.lock | 1 + Cargo.toml | 2 +- src/logger.rs | 179 ++++++++++++++++++++++++++++--------------------- src/options.rs | 8 +-- 4 files changed, 110 insertions(+), 80 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a6e44a..e27ca71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -700,6 +700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "wickdb" version = "0.1.0" dependencies = [ + "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "crc32c 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index c94248e..4cf330d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ num-derive = "0.3" slog = "2.5.2" slog-term = "2.5.0" slog-async = "2.4.0" - +chrono = "0.4" [dev-dependencies] criterion = "0.3.0" diff --git a/src/logger.rs b/src/logger.rs index 299dbad..49899b9 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -12,19 +12,27 @@ // limitations under the License. use crate::db::filename::{generate_filename, FileType}; -use crate::storage::{File, Storage}; use crate::error::Result; +use crate::storage::{File, Storage}; use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; +use chrono::prelude::*; use std::sync::Mutex; - - /// A `slog` based logger which can be used with `log` crate /// /// See `slog` at https://github.com/slog-rs/slog /// See `log` at https://github.com/rust-lang/log +/// + +fn create_file(storage:&S,dp_path:&str,timestamp:i64) -> Result { + let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); + storage.rename(dp_path, new_path.as_str())?; + storage.create(dp_path) + +} + pub struct Logger { inner: slog::Logger, level: LevelFilter, @@ -37,11 +45,11 @@ impl Logger { /// If `inner` is `None` /// - In dev mode, use a std output /// - In release mode, use a storage specific file with name `LOG` - pub fn new( + pub fn new( inner: Option, level: LevelFilter, - storage: &S, - db_path: &str, + storage:S, + db_path: String, ) -> Self { let inner = match inner { Some(l) => l, @@ -54,20 +62,19 @@ impl Logger { } else { // Use a file `Log` to record all logs // TODO: add file rotation - let file = storage - .create(generate_filename(db_path, FileType::InfoLog, 0).as_str()) - .unwrap(); - let drain = slog_async::Async::new(FileBasedDrain::new(file)) - .build() - .fuse(); + let file = create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); + let file_fn = move|path:String| {create_file(&storage, + path.as_str(),Local::now().timestamp())}; + let drain =FileBasedDrain::new(file,db_path.clone(), + file_fn) + .add_rotator(RotatedFileBySize::new(0)); + let drain = slog_async::Async::new(drain).build().fuse(); slog::Logger::root(drain, o!()) } } }; Self { inner, level } } - - } impl Log for Logger { @@ -109,7 +116,6 @@ impl Log for Logger { } } fn flush(&self) {} - } fn log_to_slog_level(level: log::Level) -> Level { @@ -122,40 +128,50 @@ fn log_to_slog_level(level: log::Level) -> Level { } } -struct FileBasedDrain { +struct FileBasedDrain { inner: Mutex, - rotators:Vec>, + rotators: Vec>, + dp_path:String, + new_file:BoxResult> } -impl FileBasedDrain { - fn new(f: F) -> Self { +impl FileBasedDrain { + fn new(f:F,path:String,new_file: H) -> Self + where H:'static+Send+Fn(String)->Result + { FileBasedDrain { + dp_path: path.clone(), inner: Mutex::new(f), - rotators:vec![], + rotators: vec![], + new_file:Box::new(new_file) } } - fn add_rotator(mut self,rotator:R) -> Self { + fn add_rotator(mut self, rotator: R) -> Self { if rotator.is_enabled() { - self.rotators.push(Box::new(rotator)); + self.rotators.push(Box::new(rotator)); + } + for rotator in (&self).rotators.iter() { + rotator.prepare(&*self.inner.lock().unwrap()).unwrap(); } self } + fn flush(&self) ->Result<()>{ + self.inner.lock().unwrap().flush()?; + let new_file = (self.new_file)(self.dp_path.clone()).unwrap(); - fn flush(&mut self) -> Result<()> { - let mut file = self.inner.lock().unwrap(); + let mut old_file = self.inner.lock().unwrap(); + std::mem::replace(&mut *old_file, new_file); for rotator in self.rotators.iter() { - if rotator.should_rotate(file.len().unwrap()){ - file.flush()? - } - + rotator.on_rotate()?; } - file.flush() + return Ok(()); + } } -impl Drain for FileBasedDrain { +impl Drain for FileBasedDrain { type Ok = (); type Err = slog::Never; @@ -164,72 +180,84 @@ impl Drain for FileBasedDrain { record: &slog::Record, values: &slog::OwnedKVList, ) -> std::result::Result { - // Ignore errors here - let _ = self.inner.lock().unwrap().write( - format!( - "[{}] : {:?} \n {:?} \n", - record.level(), - record.msg(), - values - ) - .as_bytes(), + let by = format!( + "[{}] : {:?} \n {:?} \n", + record.level(), + record.msg(), + values ); - - + for rotator in self.rotators.iter() { + if rotator.should_rotate() { + self.flush().unwrap(); + return Ok(()); + } + } + + for rotator in self.rotators.iter() { + rotator.on_write(by.as_bytes()).unwrap(); + } + // Ignore errors here + let _ = self.inner.lock().unwrap().write(by.as_bytes()); + Ok(()) } - - } + trait Rotator: Send { - - /// Check if the option is enabled in configuration. - /// Return true if the `rotator` is valid. - fn is_enabled(&self) -> bool; - - /// Call by operator, initializes the states of rotators. - // fn prepare(&mut self, file: &dyn File) -> io::Result<()>; - - /// Return if the file need to be rotated. - fn should_rotate(&self, size:u64) -> bool; - - // fn on_write(&mut self, buf:&[u8]) -> Result<()>; - // Call by operator, update rotators' state while the operator execute a rotation. - // fn on_rotate(&mut self) -> Result<()>; - - -} + /// Check if the option is enabled in configuration. + /// Return true if the `rotator` is valid. + fn is_enabled(&self) -> bool; + /// Call by operator, initializes the states of rotators. + fn prepare(&self, file: &dyn File) -> Result<()>; + + /// Return if the file need to be rotated. + fn should_rotate(&self) -> bool; + + fn on_write(&self, buf: &[u8]) -> Result<()>; + // Call by operator, update rotators' state while the operator execute a rotation. + fn on_rotate(&self) -> Result<()>; +} struct RotatedFileBySize { rotation_size: u64, - // file_size: u64 + file_size: Mutex, } impl RotatedFileBySize { fn new(rotation_size: u64) -> Self { RotatedFileBySize { rotation_size, - // file_size: 0, + file_size: Mutex::new(0), } } } impl Rotator for RotatedFileBySize { - - fn is_enabled(&self) -> bool { + fn is_enabled(&self) -> bool { self.rotation_size != 0 - } - - - fn should_rotate(&self,size: u64) -> bool { - size > self.rotation_size - } + } + fn prepare(&self, file: &dyn File) -> Result<()> { + *self.file_size.lock().unwrap() = file.len().unwrap(); + Ok(()) + + } -} + fn should_rotate(&self) -> bool { + *self.file_size.lock().unwrap() > self.rotation_size + } + fn on_write(&self, buf: &[u8]) -> Result<()> { + *self.file_size.lock().unwrap() += buf.len() as u64; + Ok(()) + } + fn on_rotate(&self) -> Result<()> { + *self.file_size.lock().unwrap() = 0; + Ok(()) + } +} #[cfg(test)] mod tests { @@ -238,13 +266,14 @@ mod tests { use crate::storage::mem::MemStorage; use std::thread; - use std::time::Duration; - + use std::time::Duration; + #[test] fn test_default_logger() { - let s = MemStorage::default(); + let s =MemStorage::default(); + // let s = &'static s; let db_path = "test"; - let logger = Logger::new(None, LevelFilter::Debug, &s, db_path); + let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string()); // Ignore the error if the logger have been set let _ = log::set_logger(Box::leak(Box::new(logger))); log::set_max_level(LevelFilter::Debug); diff --git a/src/options.rs b/src/options.rs index 8e98e2d..8ae8e96 100644 --- a/src/options.rs +++ b/src/options.rs @@ -205,10 +205,10 @@ impl Options { } /// Initialize Options by limiting ranges of some flags, applying customized Logger and etc. - pub(crate) fn initialize>( + pub(crate) fn initialize+Clone+'static>( &mut self, db_name: String, - storage: &S, + storage: &S, ) { self.max_open_files = Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000); @@ -225,9 +225,9 @@ impl Options { } #[allow(unused_must_use)] - fn apply_logger(&mut self, storage: &S, db_path: &str) { + fn apply_logger(&mut self, storage: &S, db_path: &str) { let user_logger = std::mem::replace(&mut self.logger, None); - let logger = Logger::new(user_logger, self.logger_level, storage, db_path); + let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path.to_string()); let static_logger: &'static dyn Log = Box::leak(Box::new(logger)); log::set_logger(static_logger); log::set_max_level(self.logger_level); From 42c0a2de9ec8ea506460c85fb8368fcb1c4ffe4d Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 7 May 2020 14:48:21 +0800 Subject: [PATCH 27/35] update upstream --- src/version/version_set.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/version/version_set.rs b/src/version/version_set.rs index d9d0e14..fd4fc28 100644 --- a/src/version/version_set.rs +++ b/src/version/version_set.rs @@ -1032,22 +1032,8 @@ impl DerivedIterFactory for FileIterFactory { } else { let file_number = decode_fixed_64(value); let file_size = decode_fixed_64(&value[std::mem::size_of::()..]); -<<<<<<< HEAD -<<<<<<< HEAD self.table_cache .new_iter(self.icmp.clone(), self.options, file_number, file_size) -======= - self.table_cache.new_iter( - self.icmp.clone(), - self.options, - file_number, - file_size, - ) ->>>>>>> cargo fmt -======= - self.table_cache - .new_iter(self.icmp.clone(), self.options, file_number, file_size) ->>>>>>> cargo fmt again } } } From 36c3fb7ec641e64fd2250bd7daaabac2502165d7 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 7 May 2020 15:05:25 +0800 Subject: [PATCH 28/35] add simple log rotation --- src/db/iterator.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 3c9cfab..649a7a4 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,16 +62,10 @@ pub struct DBIterator { saved_value: Slice, } -<<<<<<< HEAD -<<<<<<< HEAD + impl, S: Storage + Clone> Iterator for DBIterator { -======= -impl, S: Storage + Clone> Iterator for DBIterator { ->>>>>>> fix conflict changes -======= -impl, S: Storage + Clone> Iterator for DBIterator { ->>>>>>> remove unnecessary information + type Key = Slice; type Value = Slice; fn valid(&self) -> bool { @@ -351,10 +345,6 @@ impl DBIteratorCore { } } -<<<<<<< HEAD - -======= ->>>>>>> remove unnecessary information impl< C: Comparator, M: Iterator, From c2aa6d01ca516d4ef86c1e338e82078ca621fe3c Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 7 May 2020 15:10:39 +0800 Subject: [PATCH 29/35] merge --- src/mem/skiplist.rs | 4 ---- src/sstable/block.rs | 4 ---- src/sstable/mod.rs | 6 ------ 3 files changed, 14 deletions(-) diff --git a/src/mem/skiplist.rs b/src/mem/skiplist.rs index c1fab8a..bc4678e 100644 --- a/src/mem/skiplist.rs +++ b/src/mem/skiplist.rs @@ -266,10 +266,6 @@ pub struct SkiplistIterator { } impl Iterator for SkiplistIterator { -<<<<<<< HEAD - -======= ->>>>>>> remove unnecessary information type Key = Slice; type Value = Slice; /// Returns true whether the iterator is positioned at a valid node diff --git a/src/sstable/block.rs b/src/sstable/block.rs index f35bece..e6f0f17 100644 --- a/src/sstable/block.rs +++ b/src/sstable/block.rs @@ -218,10 +218,6 @@ impl BlockIterator { } impl Iterator for BlockIterator { -<<<<<<< HEAD - -======= ->>>>>>> fix conflict changes type Key = Slice; type Value = Slice; #[inline] diff --git a/src/sstable/mod.rs b/src/sstable/mod.rs index 3d49a4d..ddbd494 100644 --- a/src/sstable/mod.rs +++ b/src/sstable/mod.rs @@ -661,17 +661,11 @@ mod tests { } impl Iterator for EntryIterator { -<<<<<<< HEAD type Key = Slice; type Value = Slice; -======= - type Key = Slice; - type Value = Slice; - ->>>>>>> remove unnecessary information fn valid(&self) -> bool { self.current < self.data.len() } From 746d23bbeab6a978775d0ed65ce13b090d51d8d8 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 7 May 2020 15:11:12 +0800 Subject: [PATCH 30/35] cargo fmt --- src/db/filename.rs | 1 - src/db/iterator.rs | 3 -- src/iterator.rs | 4 -- src/logger.rs | 77 ++++++++++++++++++------------------- src/options.rs | 13 +++++-- src/sstable/mod.rs | 2 - src/version/version_edit.rs | 4 +- 7 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/db/filename.rs b/src/db/filename.rs index 2df5839..cd0c5da 100644 --- a/src/db/filename.rs +++ b/src/db/filename.rs @@ -207,5 +207,4 @@ mod tests { assert_eq!(result, expect); } } - } diff --git a/src/db/iterator.rs b/src/db/iterator.rs index 649a7a4..0962e5a 100644 --- a/src/db/iterator.rs +++ b/src/db/iterator.rs @@ -62,10 +62,7 @@ pub struct DBIterator { saved_value: Slice, } - - impl, S: Storage + Clone> Iterator for DBIterator { - type Key = Slice; type Value = Slice; fn valid(&self) -> bool { diff --git a/src/iterator.rs b/src/iterator.rs index c472de1..6cb0447 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -90,10 +90,7 @@ pub trait DerivedIterFactory { fn derive(&self, value: &[u8]) -> Result; } - impl, F: DerivedIterFactory> ConcatenateIterator { - - pub fn new(origin: I, factory: F) -> Self { Self { origin, @@ -191,7 +188,6 @@ impl, F: DerivedIterFactory> Concatenate } } - impl, F: DerivedIterFactory> Iterator for ConcatenateIterator { diff --git a/src/logger.rs b/src/logger.rs index 49899b9..3949ca7 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -24,13 +24,12 @@ use std::sync::Mutex; /// /// See `slog` at https://github.com/slog-rs/slog /// See `log` at https://github.com/rust-lang/log -/// +/// -fn create_file(storage:&S,dp_path:&str,timestamp:i64) -> Result { - let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); - storage.rename(dp_path, new_path.as_str())?; - storage.create(dp_path) - +fn create_file(storage: &S, dp_path: &str, timestamp: i64) -> Result { + let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); + storage.rename(dp_path, new_path.as_str())?; + storage.create(dp_path) } pub struct Logger { @@ -45,10 +44,10 @@ impl Logger { /// If `inner` is `None` /// - In dev mode, use a std output /// - In release mode, use a storage specific file with name `LOG` - pub fn new( + pub fn new( inner: Option, level: LevelFilter, - storage:S, + storage: S, db_path: String, ) -> Self { let inner = match inner { @@ -62,12 +61,13 @@ impl Logger { } else { // Use a file `Log` to record all logs // TODO: add file rotation - let file = create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); - let file_fn = move|path:String| {create_file(&storage, - path.as_str(),Local::now().timestamp())}; - let drain =FileBasedDrain::new(file,db_path.clone(), - file_fn) - .add_rotator(RotatedFileBySize::new(0)); + let file = + create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); + let file_fn = move |path: String| { + create_file(&storage, path.as_str(), Local::now().timestamp()) + }; + let drain = FileBasedDrain::new(file, db_path.clone(), file_fn) + .add_rotator(RotatedFileBySize::new(0)); let drain = slog_async::Async::new(drain).build().fuse(); slog::Logger::root(drain, o!()) } @@ -128,26 +128,27 @@ fn log_to_slog_level(level: log::Level) -> Level { } } -struct FileBasedDrain { +struct FileBasedDrain { inner: Mutex, rotators: Vec>, - dp_path:String, - new_file:BoxResult> + dp_path: String, + new_file: Box Result>, } -impl FileBasedDrain { - fn new(f:F,path:String,new_file: H) -> Self - where H:'static+Send+Fn(String)->Result - { +impl FileBasedDrain { + fn new(f: F, path: String, new_file: H) -> Self + where + H: 'static + Send + Fn(String) -> Result, + { FileBasedDrain { dp_path: path.clone(), inner: Mutex::new(f), rotators: vec![], - new_file:Box::new(new_file) + new_file: Box::new(new_file), } } - fn add_rotator(mut self, rotator: R) -> Self { + fn add_rotator(mut self, rotator: R) -> Self { if rotator.is_enabled() { self.rotators.push(Box::new(rotator)); } @@ -157,7 +158,7 @@ impl FileBasedDrain { self } - fn flush(&self) ->Result<()>{ + fn flush(&self) -> Result<()> { self.inner.lock().unwrap().flush()?; let new_file = (self.new_file)(self.dp_path.clone()).unwrap(); @@ -167,11 +168,10 @@ impl FileBasedDrain { rotator.on_rotate()?; } return Ok(()); - } } -impl Drain for FileBasedDrain { +impl Drain for FileBasedDrain { type Ok = (); type Err = slog::Never; @@ -186,13 +186,13 @@ impl Drain for FileBasedDrain { record.msg(), values ); - for rotator in self.rotators.iter() { - if rotator.should_rotate() { - self.flush().unwrap(); - return Ok(()); - } - } - + for rotator in self.rotators.iter() { + if rotator.should_rotate() { + self.flush().unwrap(); + return Ok(()); + } + } + for rotator in self.rotators.iter() { rotator.on_write(by.as_bytes()).unwrap(); } @@ -203,8 +203,6 @@ impl Drain for FileBasedDrain { } } - - trait Rotator: Send { /// Check if the option is enabled in configuration. /// Return true if the `rotator` is valid. @@ -239,10 +237,9 @@ impl Rotator for RotatedFileBySize { fn is_enabled(&self) -> bool { self.rotation_size != 0 } - fn prepare(&self, file: &dyn File) -> Result<()> { + fn prepare(&self, file: &dyn File) -> Result<()> { *self.file_size.lock().unwrap() = file.len().unwrap(); Ok(()) - } fn should_rotate(&self) -> bool { @@ -266,11 +263,11 @@ mod tests { use crate::storage::mem::MemStorage; use std::thread; - use std::time::Duration; - + use std::time::Duration; + #[test] fn test_default_logger() { - let s =MemStorage::default(); + let s = MemStorage::default(); // let s = &'static s; let db_path = "test"; let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string()); diff --git a/src/options.rs b/src/options.rs index 8ae8e96..800c40b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -205,10 +205,10 @@ impl Options { } /// Initialize Options by limiting ranges of some flags, applying customized Logger and etc. - pub(crate) fn initialize+Clone+'static>( + pub(crate) fn initialize + Clone + 'static>( &mut self, db_name: String, - storage: &S, + storage: &S, ) { self.max_open_files = Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000); @@ -225,9 +225,14 @@ impl Options { } #[allow(unused_must_use)] - fn apply_logger(&mut self, storage: &S, db_path: &str) { + fn apply_logger(&mut self, storage: &S, db_path: &str) { let user_logger = std::mem::replace(&mut self.logger, None); - let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path.to_string()); + let logger = Logger::new( + user_logger, + self.logger_level, + storage.clone(), + db_path.to_string(), + ); let static_logger: &'static dyn Log = Box::leak(Box::new(logger)); log::set_logger(static_logger); log::set_max_level(self.logger_level); diff --git a/src/sstable/mod.rs b/src/sstable/mod.rs index ddbd494..45e541e 100644 --- a/src/sstable/mod.rs +++ b/src/sstable/mod.rs @@ -661,11 +661,9 @@ mod tests { } impl Iterator for EntryIterator { - type Key = Slice; type Value = Slice; - fn valid(&self) -> bool { self.current < self.data.len() } diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index 27e7df9..efc1cfa 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -491,14 +491,13 @@ mod tests { edit.set_log_number(log_num); assert_eq!(edit.log_number.unwrap(), log_num); - } #[test] fn test_set_prev_log_number() { let mut edit = VersionEdit::new(7); - let prev_log_num =u64::max_value(); + let prev_log_num = u64::max_value(); let prev_log_num = u64::max_value(); edit.set_prev_log_number(prev_log_num); @@ -519,6 +518,5 @@ mod tests { let last_sequence = u64::max_value(); edit.set_last_sequence(last_sequence); assert_eq!(edit.last_sequence.unwrap(), last_sequence); - } } From 1d8211060679dde9aa5993ff669c834fed835a69 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 7 May 2020 16:08:20 +0800 Subject: [PATCH 31/35] update --- src/version/version_edit.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/version/version_edit.rs b/src/version/version_edit.rs index efc1cfa..a7e4452 100644 --- a/src/version/version_edit.rs +++ b/src/version/version_edit.rs @@ -496,9 +496,6 @@ mod tests { #[test] fn test_set_prev_log_number() { let mut edit = VersionEdit::new(7); - - let prev_log_num = u64::max_value(); - let prev_log_num = u64::max_value(); edit.set_prev_log_number(prev_log_num); assert_eq!(edit.prev_log_number.unwrap(), prev_log_num); From daf1437e367e74bd087d0ffe297a857fec1e2880 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 21 May 2020 10:28:58 +0800 Subject: [PATCH 32/35] add test for rotate --- src/db/mod.rs | 2 +- src/logger.rs | 155 ++++++++++++++++++++++++++++++------------------- src/options.rs | 15 ++--- 3 files changed, 101 insertions(+), 71 deletions(-) diff --git a/src/db/mod.rs b/src/db/mod.rs index 7104f72..9f8024f 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -177,7 +177,7 @@ impl DB for WickDB { impl WickDB { /// Create a new WickDB pub fn open_db(mut options: Options, db_name: &'static str, storage: S) -> Result { - options.initialize(db_name.to_owned(), &storage); + options.initialize(db_name, &storage); debug!("Open db: '{}'", db_name); let mut db = DBImpl::new(options, db_name, storage); let (mut edit, should_save_manifest) = db.recover()?; diff --git a/src/logger.rs b/src/logger.rs index 3949ca7..ccbc59c 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -15,21 +15,23 @@ use crate::db::filename::{generate_filename, FileType}; use crate::error::Result; use crate::storage::{File, Storage}; + use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; use chrono::prelude::*; use std::sync::Mutex; + /// A `slog` based logger which can be used with `log` crate /// /// See `slog` at https://github.com/slog-rs/slog /// See `log` at https://github.com/rust-lang/log /// -fn create_file(storage: &S, dp_path: &str, timestamp: i64) -> Result { - let new_path = generate_filename(dp_path, FileType::OldInfoLog, timestamp as u64); - storage.rename(dp_path, new_path.as_str())?; - storage.create(dp_path) +pub fn create_file(storage:&S,db_path:&str,timestamp:i64) -> Result { + let new_path = generate_filename(db_path, FileType::Log, timestamp as u64); + storage.create(new_path) + } pub struct Logger { @@ -47,8 +49,8 @@ impl Logger { pub fn new( inner: Option, level: LevelFilter, - storage: S, - db_path: String, + storage:S, + db_path: &'static str, ) -> Self { let inner = match inner { Some(l) => l, @@ -61,13 +63,13 @@ impl Logger { } else { // Use a file `Log` to record all logs // TODO: add file rotation - let file = - create_file(&storage, db_path.as_str(), Local::now().timestamp()).unwrap(); - let file_fn = move |path: String| { - create_file(&storage, path.as_str(), Local::now().timestamp()) - }; - let drain = FileBasedDrain::new(file, db_path.clone(), file_fn) - .add_rotator(RotatedFileBySize::new(0)); + //db_path 是generate_filename + let file = create_file(&storage, db_path,Local::now().timestamp()).unwrap(); + let file_fn = move |path: String| {create_file(&storage, + path.as_str(),Local::now().timestamp())}; + let drain =FileBasedDrain::new(file,db_path, + file_fn) + .add_rotator(RotatedFileBySize::new(1)); let drain = slog_async::Async::new(drain).build().fuse(); slog::Logger::root(drain, o!()) } @@ -131,47 +133,53 @@ fn log_to_slog_level(level: log::Level) -> Level { struct FileBasedDrain { inner: Mutex, rotators: Vec>, - dp_path: String, - new_file: Box Result>, + db_path:String, + new_file:BoxResult> } -impl FileBasedDrain { - fn new(f: F, path: String, new_file: H) -> Self - where - H: 'static + Send + Fn(String) -> Result, - { +impl FileBasedDrain { + fn new(f:F,path:&str,new_file: H) -> Self + where H:'static+Send+Fn(String)->Result + { FileBasedDrain { - dp_path: path.clone(), + db_path: path.to_string(), inner: Mutex::new(f), rotators: vec![], new_file: Box::new(new_file), } } - fn add_rotator(mut self, rotator: R) -> Self { + + fn add_rotator(mut self, rotator: R) -> Self { if rotator.is_enabled() { self.rotators.push(Box::new(rotator)); } - for rotator in (&self).rotators.iter() { + for rotator in (&self).rotators.iter() { rotator.prepare(&*self.inner.lock().unwrap()).unwrap(); } self } - fn flush(&self) -> Result<()> { - self.inner.lock().unwrap().flush()?; - let new_file = (self.new_file)(self.dp_path.clone()).unwrap(); - - let mut old_file = self.inner.lock().unwrap(); - std::mem::replace(&mut *old_file, new_file); + fn flush(&self) -> Result<()>{ + // use crate::storage::file::FileStorage; + // let storage = FileStorage::default(); for rotator in self.rotators.iter() { - rotator.on_rotate()?; - } - return Ok(()); + if rotator.should_rotate() { + // let _ = storage.rename("log/000000.log","log/000000.log"); + let new_file = (self.new_file)(self.db_path.clone()).unwrap(); + let mut old_file = self.inner.lock().unwrap(); + *old_file =new_file; + + for rotator in self.rotators.iter() { + rotator.on_rotate(); + } + return Ok(()); + } + } + self.inner.lock().unwrap().flush() } } - -impl Drain for FileBasedDrain { +impl Drain for FileBasedDrain { type Ok = (); type Err = slog::Never; @@ -186,19 +194,17 @@ impl Drain for FileBasedDrain { record.msg(), values ); - for rotator in self.rotators.iter() { - if rotator.should_rotate() { - self.flush().unwrap(); - return Ok(()); - } - } + - for rotator in self.rotators.iter() { - rotator.on_write(by.as_bytes()).unwrap(); + for rotator in self.rotators.iter() { + rotator.on_write(by.as_bytes()).unwrap(); } - // Ignore errors here - let _ = self.inner.lock().unwrap().write(by.as_bytes()); + + let _f = self.flush().unwrap(); + //Ignore errors here + let _ = self.inner.lock().unwrap().write(by.as_bytes()); + Ok(()) } } @@ -216,7 +222,7 @@ trait Rotator: Send { fn on_write(&self, buf: &[u8]) -> Result<()>; // Call by operator, update rotators' state while the operator execute a rotation. - fn on_rotate(&self) -> Result<()>; + fn on_rotate(&self) ; } struct RotatedFileBySize { @@ -250,9 +256,8 @@ impl Rotator for RotatedFileBySize { Ok(()) } - fn on_rotate(&self) -> Result<()> { + fn on_rotate(&self) { *self.file_size.lock().unwrap() = 0; - Ok(()) } } @@ -261,21 +266,51 @@ mod tests { use super::*; use crate::storage::mem::MemStorage; - + use crate::storage::file::FileStorage; + use slog::info; + use std::fs; use std::thread; - use std::time::Duration; + use std::time::Duration; + use std::path::Path; + fn file_exists(file: impl AsRef,storage:FileStorage) -> bool { + storage.exists(file) + } + // #[test] + // fn test_default_logger() { + // let s =MemStorage::default(); + // // let s = &'static s; + // let db_path = "test"; + // let logger = Logger::new(None, LevelFilter::Debug, s, db_path); + // // Ignore the error if the logger have been set + // let _ = log::set_logger(Box::leak(Box::new(logger))); + // log::set_max_level(LevelFilter::Debug); + // self::info!(,"Hello World"); + // // Wait for the async logger print the result + // thread::sleep(Duration::from_millis(100)); + // } + #[test] - fn test_default_logger() { - let s = MemStorage::default(); - // let s = &'static s; - let db_path = "test"; - let logger = Logger::new(None, LevelFilter::Debug, s, db_path.to_string()); - // Ignore the error if the logger have been set - let _ = log::set_logger(Box::leak(Box::new(logger))); - log::set_max_level(LevelFilter::Debug); - info!("Hello World"); - // Wait for the async logger print the result - thread::sleep(Duration::from_millis(100)); + fn test_rotate_by_size() { + let db_path = "log"; + + let storage = FileStorage::default(); + let _= storage.mkdir_all(db_path); + let storage2 = storage.clone(); + let file= create_file(&storage,db_path, 0).unwrap(); + let new_path = generate_filename(db_path, FileType::Log, 1 ); + + + + let file_fn = move |path: String| {create_file(&storage, + path.as_str(), 1)}; + + let drain =FileBasedDrain::new(file,db_path, file_fn) + .add_rotator(RotatedFileBySize::new(1)); + let drain = slog_async::Async::new(drain).build().fuse(); + let _log = slog::Logger::root(drain, o!()); + self::info!(_log,"Test log file rotated by size"); + + assert!(file_exists(new_path,FileStorage::default())); } } diff --git a/src/options.rs b/src/options.rs index 800c40b..c3554ac 100644 --- a/src/options.rs +++ b/src/options.rs @@ -207,15 +207,15 @@ impl Options { /// Initialize Options by limiting ranges of some flags, applying customized Logger and etc. pub(crate) fn initialize + Clone + 'static>( &mut self, - db_name: String, - storage: &S, + db_name: &'static str, + storage: &S, ) { self.max_open_files = Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000); self.write_buffer_size = Self::clip_range(self.write_buffer_size, 64 << 10, 1 << 30); self.max_file_size = Self::clip_range(self.max_file_size, 1 << 20, 1 << 30); self.block_size = Self::clip_range(self.block_size, 1 << 10, 4 << 20); - self.apply_logger(storage, &db_name); + self.apply_logger(storage, db_name); if self.block_cache.is_none() { self.block_cache = Some(Arc::new(LRUCache::new(8 << 20, None))) } @@ -225,14 +225,9 @@ impl Options { } #[allow(unused_must_use)] - fn apply_logger(&mut self, storage: &S, db_path: &str) { + fn apply_logger(&mut self, storage: &S, db_path: &'static str) { let user_logger = std::mem::replace(&mut self.logger, None); - let logger = Logger::new( - user_logger, - self.logger_level, - storage.clone(), - db_path.to_string(), - ); + let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path); let static_logger: &'static dyn Log = Box::leak(Box::new(logger)); log::set_logger(static_logger); log::set_max_level(self.logger_level); From 7110a01378a2aca0ebc2a170c12f72088a347049 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Tue, 26 May 2020 08:40:46 +0800 Subject: [PATCH 33/35] complete rotate test --- src/logger.rs | 176 +++++++++++++++++++++++++++---------------------- src/options.rs | 4 +- 2 files changed, 99 insertions(+), 81 deletions(-) diff --git a/src/logger.rs b/src/logger.rs index ccbc59c..eca7b7c 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -15,7 +15,6 @@ use crate::db::filename::{generate_filename, FileType}; use crate::error::Result; use crate::storage::{File, Storage}; - use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; @@ -28,10 +27,9 @@ use std::sync::Mutex; /// See `log` at https://github.com/rust-lang/log /// -pub fn create_file(storage:&S,db_path:&str,timestamp:i64) -> Result { - let new_path = generate_filename(db_path, FileType::Log, timestamp as u64); - storage.create(new_path) - +pub fn create_file(storage: &S, db_path: &str, timestamp: i64) -> Result { + let log_path = generate_filename(db_path, FileType::Log, timestamp as u64); + storage.create(log_path) } pub struct Logger { @@ -49,7 +47,7 @@ impl Logger { pub fn new( inner: Option, level: LevelFilter, - storage:S, + storage: S, db_path: &'static str, ) -> Self { let inner = match inner { @@ -62,14 +60,12 @@ impl Logger { slog::Logger::root(drain, o!()) } else { // Use a file `Log` to record all logs - // TODO: add file rotation - //db_path 是generate_filename - let file = create_file(&storage, db_path,Local::now().timestamp()).unwrap(); - let file_fn = move |path: String| {create_file(&storage, - path.as_str(),Local::now().timestamp())}; - let drain =FileBasedDrain::new(file,db_path, - file_fn) - .add_rotator(RotatedFileBySize::new(1)); + let file = create_file(&storage, db_path, Local::now().timestamp()).unwrap(); + let file_fn = move |path: String| { + create_file(&storage, path.as_str(), Local::now().timestamp()) + }; + let drain = FileBasedDrain::new(file, db_path, file_fn) + .add_rotator(RotatedFileBySize::new(1)); let drain = slog_async::Async::new(drain).build().fuse(); slog::Logger::root(drain, o!()) } @@ -133,14 +129,15 @@ fn log_to_slog_level(level: log::Level) -> Level { struct FileBasedDrain { inner: Mutex, rotators: Vec>, - db_path:String, - new_file:BoxResult> + db_path: String, + new_file: Box Result>, } -impl FileBasedDrain { - fn new(f:F,path:&str,new_file: H) -> Self - where H:'static+Send+Fn(String)->Result - { +impl FileBasedDrain { + fn new(f: F, path: &str, new_file: H) -> Self + where + H: 'static + Send + Fn(String) -> Result, + { FileBasedDrain { db_path: path.to_string(), inner: Mutex::new(f), @@ -149,37 +146,36 @@ impl FileBasedDrain { } } - - fn add_rotator(mut self, rotator: R) -> Self { + fn add_rotator(mut self, rotator: R) -> Self { if rotator.is_enabled() { self.rotators.push(Box::new(rotator)); } - for rotator in (&self).rotators.iter() { + for rotator in self.rotators.iter() { rotator.prepare(&*self.inner.lock().unwrap()).unwrap(); } self } - fn flush(&self) -> Result<()>{ - // use crate::storage::file::FileStorage; - // let storage = FileStorage::default(); + fn flush(&self) -> Result<()> { for rotator in self.rotators.iter() { - if rotator.should_rotate() { - // let _ = storage.rename("log/000000.log","log/000000.log"); + if rotator.should_rotate() { let new_file = (self.new_file)(self.db_path.clone()).unwrap(); + let mut old_file = self.inner.lock().unwrap(); - *old_file =new_file; - + *old_file = new_file; + for rotator in self.rotators.iter() { rotator.on_rotate(); } + return Ok(()); - } } + } + self.inner.lock().unwrap().flush() } } -impl Drain for FileBasedDrain { +impl Drain for FileBasedDrain { type Ok = (); type Err = slog::Never; @@ -194,17 +190,16 @@ impl Drain for FileBasedDrain { record.msg(), values ); - - for rotator in self.rotators.iter() { - rotator.on_write(by.as_bytes()).unwrap(); + for rotator in self.rotators.iter() { + rotator.on_write(by.as_bytes()).unwrap(); } - - let _f = self.flush().unwrap(); + + self.flush().unwrap(); //Ignore errors here let _ = self.inner.lock().unwrap().write(by.as_bytes()); - + Ok(()) } } @@ -222,7 +217,7 @@ trait Rotator: Send { fn on_write(&self, buf: &[u8]) -> Result<()>; // Call by operator, update rotators' state while the operator execute a rotation. - fn on_rotate(&self) ; + fn on_rotate(&self); } struct RotatedFileBySize { @@ -256,7 +251,7 @@ impl Rotator for RotatedFileBySize { Ok(()) } - fn on_rotate(&self) { + fn on_rotate(&self) { *self.file_size.lock().unwrap() = 0; } } @@ -265,52 +260,75 @@ impl Rotator for RotatedFileBySize { mod tests { use super::*; - use crate::storage::mem::MemStorage; use crate::storage::file::FileStorage; - use slog::info; - use std::fs; - use std::thread; - use std::time::Duration; + use crate::storage::mem::MemStorage; use std::path::Path; + use std::thread; + use std::time::Duration; - fn file_exists(file: impl AsRef,storage:FileStorage) -> bool { + fn file_exists(file: impl AsRef, storage: impl Storage) -> bool { storage.exists(file) } - // #[test] - // fn test_default_logger() { - // let s =MemStorage::default(); - // // let s = &'static s; - // let db_path = "test"; - // let logger = Logger::new(None, LevelFilter::Debug, s, db_path); - // // Ignore the error if the logger have been set - // let _ = log::set_logger(Box::leak(Box::new(logger))); - // log::set_max_level(LevelFilter::Debug); - // self::info!(,"Hello World"); - // // Wait for the async logger print the result - // thread::sleep(Duration::from_millis(100)); - // } - + #[test] - fn test_rotate_by_size() { + fn test_default_logger() { + let s = MemStorage::default(); + // let s = &'static s; + let db_path = "test"; + let logger = Logger::new(None, LevelFilter::Debug, s, db_path); + // Ignore the error if the logger have been set + let _ = log::set_logger(Box::leak(Box::new(logger))); + log::set_max_level(LevelFilter::Debug); + log::info!("Hello World"); + // Wait for the async logger print the result + thread::sleep(Duration::from_millis(100)); + } + + #[test] + fn test_rotate_by_size() { let db_path = "log"; - + let storage = FileStorage::default(); - let _= storage.mkdir_all(db_path); - let storage2 = storage.clone(); - let file= create_file(&storage,db_path, 0).unwrap(); - let new_path = generate_filename(db_path, FileType::Log, 1 ); - - - - let file_fn = move |path: String| {create_file(&storage, - path.as_str(), 1)}; - - let drain =FileBasedDrain::new(file,db_path, file_fn) - .add_rotator(RotatedFileBySize::new(1)); - let drain = slog_async::Async::new(drain).build().fuse(); - let _log = slog::Logger::root(drain, o!()); - self::info!(_log,"Test log file rotated by size"); - - assert!(file_exists(new_path,FileStorage::default())); + + let _ = storage.mkdir_all(db_path); + let file = create_file(&storage, db_path, 0).unwrap(); + let new_path = generate_filename(db_path, FileType::Log, 1); + + { + let file_fn = move |path: String| create_file(&storage, path.as_str(), 1); + + let drain = + FileBasedDrain::new(file, db_path, file_fn).add_rotator(RotatedFileBySize::new(1)); + let drain = slog_async::Async::new(drain).build().fuse(); + let _log = slog::Logger::root(drain, o!()); + slog::info!(_log, "Test log file rotated by size"); + } + assert_eq!(true, file_exists(new_path, FileStorage::default())); + } + + #[test] + fn test_not_rotate_by_size() { + let db_path = "norotate"; + + let storage = FileStorage::default(); + + let _ = storage.mkdir_all(db_path); + let file = create_file(&storage, db_path, 0).unwrap(); + let new_path = generate_filename(db_path, FileType::Log, 1); + + { + let file_fn = move |path: String| create_file(&storage, path.as_str(), 1); + + let drain = FileBasedDrain::new(file, db_path, file_fn) + .add_rotator(RotatedFileBySize::new(100)); + let drain = slog_async::Async::new(drain).build().fuse(); + let _log = slog::Logger::root(drain, o!()); + slog::info!(_log, "Test log file rotated by size"); + } + assert_eq!( + true, + file_exists("norotate/000000.log", FileStorage::default()) + ); + assert_eq!(false, file_exists(new_path, FileStorage::default())); } } diff --git a/src/options.rs b/src/options.rs index c3554ac..5abdd9b 100644 --- a/src/options.rs +++ b/src/options.rs @@ -208,7 +208,7 @@ impl Options { pub(crate) fn initialize + Clone + 'static>( &mut self, db_name: &'static str, - storage: &S, + storage: &S, ) { self.max_open_files = Self::clip_range(self.max_open_files, 64 + self.non_table_cache_files, 50000); @@ -225,7 +225,7 @@ impl Options { } #[allow(unused_must_use)] - fn apply_logger(&mut self, storage: &S, db_path: &'static str) { + fn apply_logger(&mut self, storage: &S, db_path: &'static str) { let user_logger = std::mem::replace(&mut self.logger, None); let logger = Logger::new(user_logger, self.logger_level, storage.clone(), db_path); let static_logger: &'static dyn Log = Box::leak(Box::new(logger)); From f37634ecd377dff12b8db59e8f1b47e9cb1f6fec Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Thu, 11 Jun 2020 14:50:23 +0800 Subject: [PATCH 34/35] using memStorage instead of FileStorage --- src/logger.rs | 37 +++++++++++++++++-------------------- src/storage/mem.rs | 1 + 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/logger.rs b/src/logger.rs index eca7b7c..9e871a4 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -19,6 +19,7 @@ use log::{LevelFilter, Log, Metadata, Record}; use slog::{o, Drain, Level}; use chrono::prelude::*; +use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Mutex; /// A `slog` based logger which can be used with `log` crate @@ -215,21 +216,23 @@ trait Rotator: Send { /// Return if the file need to be rotated. fn should_rotate(&self) -> bool; + /// Call by operator, update rotators' state while the operator try to write some data. fn on_write(&self, buf: &[u8]) -> Result<()>; + // Call by operator, update rotators' state while the operator execute a rotation. fn on_rotate(&self); } struct RotatedFileBySize { rotation_size: u64, - file_size: Mutex, + file_size: AtomicU64, } impl RotatedFileBySize { fn new(rotation_size: u64) -> Self { RotatedFileBySize { rotation_size, - file_size: Mutex::new(0), + file_size: AtomicU64::new(0), } } } @@ -239,20 +242,21 @@ impl Rotator for RotatedFileBySize { self.rotation_size != 0 } fn prepare(&self, file: &dyn File) -> Result<()> { - *self.file_size.lock().unwrap() = file.len().unwrap(); + self.file_size.store(file.len().unwrap(), Ordering::Relaxed); Ok(()) } fn should_rotate(&self) -> bool { - *self.file_size.lock().unwrap() > self.rotation_size + self.file_size.load(Ordering::Relaxed) > self.rotation_size } fn on_write(&self, buf: &[u8]) -> Result<()> { - *self.file_size.lock().unwrap() += buf.len() as u64; + let size = self.file_size.load(Ordering::Relaxed) + buf.len() as u64; + self.file_size.store(size, Ordering::Relaxed); Ok(()) } fn on_rotate(&self) { - *self.file_size.lock().unwrap() = 0; + self.file_size.store(0, Ordering::Relaxed) } } @@ -266,10 +270,6 @@ mod tests { use std::thread; use std::time::Duration; - fn file_exists(file: impl AsRef, storage: impl Storage) -> bool { - storage.exists(file) - } - #[test] fn test_default_logger() { let s = MemStorage::default(); @@ -288,8 +288,8 @@ mod tests { fn test_rotate_by_size() { let db_path = "log"; - let storage = FileStorage::default(); - + let storage = MemStorage::default(); + let stor2 = storage.clone(); let _ = storage.mkdir_all(db_path); let file = create_file(&storage, db_path, 0).unwrap(); let new_path = generate_filename(db_path, FileType::Log, 1); @@ -303,15 +303,15 @@ mod tests { let _log = slog::Logger::root(drain, o!()); slog::info!(_log, "Test log file rotated by size"); } - assert_eq!(true, file_exists(new_path, FileStorage::default())); + assert_eq!(true, stor2.exists(new_path)); } #[test] fn test_not_rotate_by_size() { let db_path = "norotate"; - let storage = FileStorage::default(); - + let storage = MemStorage::default(); + let stor2 = storage.clone(); let _ = storage.mkdir_all(db_path); let file = create_file(&storage, db_path, 0).unwrap(); let new_path = generate_filename(db_path, FileType::Log, 1); @@ -325,10 +325,7 @@ mod tests { let _log = slog::Logger::root(drain, o!()); slog::info!(_log, "Test log file rotated by size"); } - assert_eq!( - true, - file_exists("norotate/000000.log", FileStorage::default()) - ); - assert_eq!(false, file_exists(new_path, FileStorage::default())); + assert_eq!(true, stor2.exists("norotate/000000.log")); + assert_eq!(false, stor2.exists(new_path)); } } diff --git a/src/storage/mem.rs b/src/storage/mem.rs index 88af4ac..13acd17 100644 --- a/src/storage/mem.rs +++ b/src/storage/mem.rs @@ -690,6 +690,7 @@ mod tests { let store = MemStorage::default(); // Test `create` let mut f = store.create("test1").unwrap(); + assert!(store.exists("test1")); f.write(b"hello world").unwrap(); From 5d27d2c19bc4c268f1ad71ae5705c5682ae6aef4 Mon Sep 17 00:00:00 2001 From: AliceLanniste <1399789151@qq.com> Date: Tue, 23 Jun 2020 16:57:05 +0800 Subject: [PATCH 35/35] delete unncessary import --- src/logger.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/logger.rs b/src/logger.rs index 9e871a4..4c1f817 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -264,9 +264,7 @@ impl Rotator for RotatedFileBySize { mod tests { use super::*; - use crate::storage::file::FileStorage; use crate::storage::mem::MemStorage; - use std::path::Path; use std::thread; use std::time::Duration;