-
Notifications
You must be signed in to change notification settings - Fork 274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feature] #1149: Restrict block number to 1 million per dir #2194
[feature] #1149: Restrict block number to 1 million per dir #2194
Conversation
Codecov Report
@@ Coverage Diff @@
## iroha2-dev #2194 +/- ##
==============================================
+ Coverage 63.83% 63.95% +0.11%
==============================================
Files 127 127
Lines 23592 23692 +100
==============================================
+ Hits 15060 15152 +92
- Misses 8532 8540 +8
Continue to review full report at Codecov.
|
92f2f30
to
ffa458f
Compare
@@ -463,15 +505,39 @@ async fn storage_files_base_indices<IO: DiskIO>( | |||
path: &Path, | |||
io: &IO, | |||
) -> Result<BTreeSet<NonZeroU64>> { | |||
let bases = io | |||
let dirs: Vec<(String, IO::Dir)> = io | |||
.read_dir(path.to_path_buf()) | |||
.await? | |||
.filter_map(|item| async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider rewriting like this:
let dirs: Vec<(String, IO::Dir)> = io
.read_dir(path.to_path_buf())
.await?
.filter(Result::ok)
.map(|item| async {
let dir_name = item.to_string_lossy().into_owned();
match io.read_dir(path.join(dir_name.clone())).await {
Ok(items_stream) => Some((dir_name, items_stream)),
Err(_) => None,
}
})
.collect()
.await;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think it looks prettier? I'm talking about using filter
and map
instead of filter_map
.
AFAIK we should use filter_map
when we will apply an operation to parameter regardless of its value. Here is not this situation, here we apply operation only on Ok
variant.
core/src/kura.rs
Outdated
.map(|f_os| { | ||
let f = f_os.to_str(); | ||
if f.is_some() && f.unwrap().starts_with(path_str) { | ||
let path_buf : PathBuf = f.unwrap().strip_prefix(path_str).unwrap().into(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strip_prefix()
docs shows, that you don't need to add /
sign before, it should work just fine without it. So you can remove path_srt
manipulation above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not why it's important. It's important that the / get's removed so that it doesn't get treated as a root directory. If you start with dir/dir1/file2 and remove dir you get /dir1/file2 which is not what we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's what I'm talking about. Look at this playground
4040754
to
721f807
Compare
…per directory Signed-off-by: Sam H. Smith <sam.henning.smith@protonmail.com>
721f807
to
e47e4ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good job! But can you, please, also place somewhere in the code documentation about new files structure?
.then(move |e| { | ||
let io = io.clone(); | ||
async move { io.open(e.into_os_string()).await } | ||
// async move { io.open(e.into_os_string()).await } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented code
@@ -463,15 +505,39 @@ async fn storage_files_base_indices<IO: DiskIO>( | |||
path: &Path, | |||
io: &IO, | |||
) -> Result<BTreeSet<NonZeroU64>> { | |||
let bases = io | |||
let dirs: Vec<(String, IO::Dir)> = io | |||
.read_dir(path.to_path_buf()) | |||
.await? | |||
.filter_map(|item| async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think it looks prettier? I'm talking about using filter
and map
instead of filter_map
.
AFAIK we should use filter_map
when we will apply an operation to parameter regardless of its value. Here is not this situation, here we apply operation only on Ok
variant.
fs::DirBuilder::new() | ||
.recursive(true) | ||
.create(&dir.path().join("0")) | ||
.await | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
create_dir_all()
? Should be fine here. But if you like this style, keep it
.map(move |e| dir_path.join(e.to_string())) | ||
let mut files = Vec::new(); | ||
for index in &base_indices { | ||
files.push(self.filename_to_path(&index.to_string())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about renaming filename_to_path()
function to block_index_to_path()
?
pub async fn get_block_path(&self, block_height: NonZeroU64) -> Result<PathBuf> { | ||
let filename = self.get_block_filename(block_height).await?; | ||
Ok(self.path.join(filename)) | ||
let file_string = self.get_block_filename(block_height).await?; | ||
Ok(self.filename_to_path(&file_string)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little confusing for me that get_block_filename()
does not return valid path and needs further processing... Maybe rename it to something else or refactor somehow?
Description of the Change
Take what was the previous file name, prepend with zeroes, then interpret that as dir + file name. So block files are ex 2/003, 0/032 et cetera.
Issue
#1149
Benefits
Most operating systems will freak out if there are too many files in a directory. This solves that.
Possible Drawbacks
We still iterate over all existing files to figure out which block file we want to edit/create. I think this needs to change in the long run. We should using a simple formula map from block number to block file number. That way you only touch the the file you want to operate on. That is a seperate issue from #1149 though, so the point is irrelevant for this PR.