Skip to content

Commit 23f5cf9

Browse files
committed
Avoid extra name lookup
This commit avoids an extra name lookup but using the name of an inode as its key in the directory. This will be slightly complicated by rotating files depending on how I do them but it is a win in terms of code simplification now. Signed-off-by: Brian L. Troutwine <[email protected]>
1 parent 4fa0e24 commit 23f5cf9

File tree

2 files changed

+24
-42
lines changed

2 files changed

+24
-42
lines changed

lading/src/bin/logrotate_fs.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ impl Filesystem for LogrotateFS {
189189
) {
190190
let tick = self.get_current_tick();
191191

192+
// NOTE this call to State::read is almost surely allocating. It'd be
193+
// pretty slick if we could get the buffer directly from the OS to pass
194+
// down for writing but we can't. I suppose we could send up the raw
195+
// blocks and then chain them together as needed but absent a compelling
196+
// reason to do that the simplicity of this API is nice.
192197
if let Some(data) = self
193198
.state
194199
.read(ino as usize, offset as usize, size as usize, tick)
@@ -234,16 +239,12 @@ impl Filesystem for LogrotateFS {
234239

235240
// reaming children
236241
if let Some(child_inodes) = self.state.readdir(ino as usize) {
237-
for child_ino in child_inodes {
238-
if let Some(name) = self.state.get_name(*child_ino) {
239-
let file_type = self
240-
.state
241-
.get_file_type(*child_ino)
242-
.expect("inode must have file type");
243-
entries.push((*child_ino as u64, file_type, name.to_string()));
244-
} else {
245-
error!("child inode has no name");
246-
}
242+
for (child_name, child_ino) in child_inodes {
243+
let file_type = self
244+
.state
245+
.get_file_type(*child_ino)
246+
.expect("inode must have file type");
247+
entries.push((*child_ino as u64, file_type, child_name.clone()));
247248
}
248249
} else {
249250
reply.error(ENOENT);

lading/src/generator/file_gen/model.rs

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
//use lading_payload::block;
44

5-
use std::collections::{HashMap, HashSet};
5+
use std::collections::HashMap;
66

77
use bytes::Bytes;
88
use lading_payload::block;
@@ -89,7 +89,7 @@ impl File {
8989
/// instances or `File` instances. Root directory will not have a `parent`.
9090
#[derive(Debug)]
9191
pub struct Directory {
92-
children: HashSet<Inode>,
92+
children: HashMap<String, Inode>,
9393
parent: Option<Inode>,
9494
}
9595

@@ -172,10 +172,10 @@ impl State {
172172
let mut nodes = HashMap::new();
173173

174174
let mut root_dir = Directory {
175-
children: HashSet::new(),
175+
children: HashMap::new(),
176176
parent: None,
177177
};
178-
root_dir.children.insert(logs_inode);
178+
root_dir.children.insert("logs".to_string(), logs_inode);
179179
nodes.insert(
180180
root_inode,
181181
Node::Directory {
@@ -185,10 +185,12 @@ impl State {
185185
);
186186

187187
let mut logs_dir = Directory {
188-
children: HashSet::new(),
188+
children: HashMap::new(),
189189
parent: Some(root_inode),
190190
};
191-
logs_dir.children.insert(foo_log_inode);
191+
logs_dir
192+
.children
193+
.insert("foo.log".to_string(), foo_log_inode);
192194
nodes.insert(
193195
logs_inode,
194196
Node::Directory {
@@ -252,20 +254,10 @@ impl State {
252254
self.advance_time(now);
253255

254256
if let Some(Node::Directory { dir, .. }) = self.nodes.get(&parent_inode) {
255-
for child_inode in &dir.children {
256-
let child_node = &self
257-
.nodes
258-
.get(child_inode)
259-
.expect("catastrophic programming error");
260-
let child_name = match child_node {
261-
Node::Directory { name, .. } | Node::File { name, .. } => name,
262-
};
263-
if child_name == name {
264-
return Some(*child_inode);
265-
}
266-
}
257+
dir.children.get(name).copied()
258+
} else {
259+
None
267260
}
268-
None
269261
}
270262

271263
/// Look up the attributes for an `Inode`.
@@ -342,25 +334,14 @@ impl State {
342334
///
343335
/// Function does not advance time in the model.
344336
#[tracing::instrument(skip(self))]
345-
pub fn readdir(&self, inode: Inode) -> Option<&HashSet<Inode>> {
337+
pub fn readdir(&self, inode: Inode) -> Option<&HashMap<String, Inode>> {
346338
if let Some(Node::Directory { dir, .. }) = self.nodes.get(&inode) {
347339
Some(&dir.children)
348340
} else {
349341
None
350342
}
351343
}
352344

353-
/// Get the name of an inode if it exists
354-
#[tracing::instrument(skip(self))]
355-
pub fn get_name(&self, inode: Inode) -> Option<&str> {
356-
self.nodes
357-
.get(&inode)
358-
.map(|node| match node {
359-
Node::Directory { name, .. } | Node::File { name, .. } => name,
360-
})
361-
.map(String::as_str)
362-
}
363-
364345
/// Get the fuser file type of an inode if it exists
365346
#[tracing::instrument(skip(self))]
366347
pub fn get_file_type(&self, inode: Inode) -> Option<fuser::FileType> {
@@ -396,7 +377,7 @@ impl State {
396377
let subdirectory_count = dir
397378
.children
398379
.iter()
399-
.filter(|child_inode| {
380+
.filter(|(_, child_inode)| {
400381
matches!(self.nodes.get(child_inode), Some(Node::Directory { .. }))
401382
})
402383
.count();

0 commit comments

Comments
 (0)