Skip to content

Commit f3724a7

Browse files
committed
create IndexStorage enum rather than accessing the filesystem directly
1 parent 7654b8a commit f3724a7

File tree

7 files changed

+119
-33
lines changed

7 files changed

+119
-33
lines changed

src/bin/offline/extract.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::offline;
22
use crate::rla;
33

4+
use rla::index::IndexStorage;
45
use std::fs;
56
use std::io::{self, Write};
67
use std::path::Path;
@@ -31,7 +32,7 @@ fn load_lines<'a>(ci: &dyn rla::ci::CiPlatform, log: &'a [u8]) -> Vec<Line<'a>>
3132

3233
pub fn dir(
3334
ci: &dyn rla::ci::CiPlatform,
34-
index_file: &Path,
35+
index_file: &IndexStorage,
3536
src_dir: &Path,
3637
dst_dir: &Path,
3738
) -> rla::Result<()> {
@@ -91,7 +92,11 @@ pub fn dir(
9192
Ok(())
9293
}
9394

94-
pub fn one(ci: &dyn rla::ci::CiPlatform, index_file: &Path, log_file: &Path) -> rla::Result<()> {
95+
pub fn one(
96+
ci: &dyn rla::ci::CiPlatform,
97+
index_file: &IndexStorage,
98+
log_file: &Path,
99+
) -> rla::Result<()> {
95100
let config = rla::extract::Config::default();
96101
let index = rla::Index::load(index_file)?;
97102

src/bin/offline/learn.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::offline;
22
use crate::rla;
33

4-
use std::path::{Path, PathBuf};
4+
use rla::index::IndexStorage;
5+
use std::path::PathBuf;
56
use std::time::Duration;
67
use std::time::Instant;
78
use walkdir::{self, WalkDir};
89

910
pub fn learn(
1011
ci: &dyn rla::ci::CiPlatform,
11-
index_file: &Path,
12+
index_file: &IndexStorage,
1213
inputs: &[PathBuf],
1314
multiplier: u32,
1415
) -> rla::Result<()> {

src/bin/rla-offline.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extern crate rust_log_analyzer as rla;
1212
extern crate walkdir;
1313

1414
use clap::Parser;
15+
use rla::index::IndexStorage;
1516
use std::path::PathBuf;
1617

1718
mod offline;
@@ -53,7 +54,7 @@ enum Cli {
5354
long = "index-file",
5455
help = "The index file to read / write. An existing index file is updated."
5556
)]
56-
index_file: PathBuf,
57+
index_file: IndexStorage,
5758
#[arg(
5859
short = 'm',
5960
long = "multiplier",
@@ -79,7 +80,7 @@ enum Cli {
7980
long = "index-file",
8081
help = "The index file to read / write."
8182
)]
82-
index_file: PathBuf,
83+
index_file: IndexStorage,
8384
#[arg(
8485
short = 's',
8586
long = "source",
@@ -106,7 +107,7 @@ enum Cli {
106107
long = "index-file",
107108
help = "The index file to read / write."
108109
)]
109-
index_file: PathBuf,
110+
index_file: IndexStorage,
110111
#[arg(help = "The log file to analyze.")]
111112
log: PathBuf,
112113
},

src/bin/rla-server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ extern crate rust_log_analyzer as rla;
1515
extern crate serde_json;
1616

1717
use clap::Parser;
18+
use rla::index::IndexStorage;
1819
use std::process;
1920
use std::sync::Arc;
2021
use std::thread;
@@ -47,7 +48,7 @@ struct Cli {
4748
long = "index-file",
4849
help = "The index file to read / write. An existing index file is updated."
4950
)]
50-
index_file: std::path::PathBuf,
51+
index_file: IndexStorage,
5152
#[arg(
5253
long = "debug-post",
5354
help = "Post all comments to the given issue instead of the actual PR. Format: \"user/repo#id\""

src/bin/server/worker.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use super::{QueueItem, QueueItemKind};
33
use crate::rla;
44
use crate::rla::ci::{self, BuildCommit, CiPlatform};
55
use anyhow::bail;
6+
use rla::index::IndexStorage;
67
use std::collections::{HashSet, VecDeque};
78
use std::hash::Hash;
8-
use std::path::PathBuf;
99
use std::str;
1010

1111
pub struct Worker {
1212
debug_post: Option<(String, u32)>,
13-
index_file: PathBuf,
13+
index_file: IndexStorage,
1414
index: rla::Index,
1515
extract_config: rla::extract::Config,
1616
github: rla::github::Client,
@@ -26,7 +26,7 @@ pub struct Worker {
2626

2727
impl Worker {
2828
pub fn new(
29-
index_file: PathBuf,
29+
index_file: IndexStorage,
3030
debug_post: Option<String>,
3131
queue: crossbeam::channel::Receiver<QueueItem>,
3232
ci: Box<dyn CiPlatform + Send>,

src/index/mod.rs

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
use super::Result;
2-
use atomicwrites;
3-
use bincode;
4-
use fnv;
5-
use std;
6-
use std::fs;
7-
use std::path::Path;
82
use std::slice;
93

4+
mod storage;
105
mod table;
116

7+
pub use self::storage::IndexStorage;
8+
129
pub trait IndexData {
1310
fn sanitized(&self) -> &[u8];
1411
}
@@ -45,37 +42,50 @@ impl Index {
4542
.into_iter()
4643
}
4744

48-
pub fn save(&self, path: &Path) -> Result<()> {
49-
debug!("Saving index to '{}'...", path.display());
50-
let file = atomicwrites::AtomicFile::new(path, atomicwrites::AllowOverwrite);
51-
file.write(|f| bincode::serialize_into(f, self))?;
45+
pub fn save(&self, storage: &IndexStorage) -> Result<()> {
46+
debug!("Saving index to '{storage}'...");
47+
storage.write(self)?;
5248
debug!("Index saved.");
5349
Ok(())
5450
}
5551

56-
pub fn load(path: &Path) -> Result<Index> {
57-
Index::load_or_create_internal(path, false)
52+
pub fn load(storage: &IndexStorage) -> Result<Index> {
53+
Index::load_or_create_internal(storage, false)
5854
}
5955

60-
pub fn load_or_create(path: &Path) -> Result<Index> {
61-
Index::load_or_create_internal(path, true)
56+
pub fn load_or_create(storage: &IndexStorage) -> Result<Index> {
57+
Index::load_or_create_internal(storage, true)
6258
}
6359

64-
fn load_or_create_internal(path: &Path, create: bool) -> Result<Index> {
65-
let index;
66-
67-
if path.exists() || !create {
68-
info!("Loading index...");
69-
index = bincode::deserialize_from(fs::File::open(path)?)?;
60+
fn load_or_create_internal(storage: &IndexStorage, create: bool) -> Result<Index> {
61+
info!("Loading index...");
62+
let index = if let Some(index) = storage.read()? {
63+
index
7064
} else {
71-
info!("Initializing new index...");
72-
index = Index::default();
65+
if create {
66+
info!("Index missing, initializing new index...");
67+
Index::default()
68+
} else {
69+
anyhow::bail!("missing index, aborting");
70+
}
7371
};
7472

7573
info!("Index ready ({} keys).", index.internal.len());
7674

7775
Ok(index)
7876
}
77+
78+
fn deserialize(reader: &mut dyn std::io::Read) -> Result<Self> {
79+
Ok(bincode::deserialize_from(reader)?)
80+
}
81+
82+
fn serialize(
83+
&self,
84+
writer: &mut dyn std::io::Write,
85+
) -> std::result::Result<(), bincode::Error> {
86+
bincode::serialize_into(writer, self)?;
87+
Ok(())
88+
}
7989
}
8090

8191
pub fn encode<I: IndexData>(data: &I) -> Vec<u8> {

src/index/storage.rs

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use crate::{Index, Result};
2+
use atomicwrites::{AtomicFile, OverwriteBehavior};
3+
use std::fs::File;
4+
use std::path::PathBuf;
5+
use std::str::FromStr;
6+
7+
#[derive(Debug, Clone)]
8+
pub enum IndexStorage {
9+
FileSystem(FileSystemStorage),
10+
}
11+
12+
impl IndexStorage {
13+
pub fn new(path: &str) -> Result<Self> {
14+
Ok(IndexStorage::FileSystem(FileSystemStorage {
15+
path: path.into(),
16+
}))
17+
}
18+
19+
pub(super) fn read(&self) -> Result<Option<Index>> {
20+
match self {
21+
IndexStorage::FileSystem(fs) => fs.read(),
22+
}
23+
}
24+
25+
pub(super) fn write(&self, index: &Index) -> Result<()> {
26+
match self {
27+
IndexStorage::FileSystem(fs) => fs.write(index),
28+
}
29+
}
30+
}
31+
32+
impl FromStr for IndexStorage {
33+
type Err = anyhow::Error;
34+
35+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
36+
IndexStorage::new(s)
37+
}
38+
}
39+
40+
impl std::fmt::Display for IndexStorage {
41+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42+
match self {
43+
IndexStorage::FileSystem(fs) => write!(f, "{}", fs.path.display()),
44+
}
45+
}
46+
}
47+
48+
#[derive(Debug, Clone)]
49+
pub struct FileSystemStorage {
50+
path: PathBuf,
51+
}
52+
53+
impl FileSystemStorage {
54+
fn read(&self) -> Result<Option<Index>> {
55+
let mut file = match File::open(&self.path) {
56+
Ok(file) => file,
57+
Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
58+
Err(err) => return Err(err.into()),
59+
};
60+
Ok(Some(Index::deserialize(&mut file)?))
61+
}
62+
63+
fn write(&self, index: &Index) -> Result<()> {
64+
let file = AtomicFile::new(&self.path, OverwriteBehavior::AllowOverwrite);
65+
file.write(|inner| index.serialize(inner))?;
66+
Ok(())
67+
}
68+
}

0 commit comments

Comments
 (0)