use logfile::Logfile;
use logfile_config::LogfileConfig;
use logfile_directory::LogfileDirectory;
use logfile_id::LogfileID;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
#[derive(Debug, Clone)]
pub struct LogfileMap {
directory: LogfileDirectory,
config: LogfileConfig,
logfiles: Arc<RwLock<HashMap<String, Arc<Logfile>>>>,
}
impl LogfileMap {
pub fn open(directory: LogfileDirectory, config: LogfileConfig) -> Result<LogfileMap, ::Error> {
let mut logfile_map = HashMap::<String, Arc<Logfile>>::new();
info!("Opening logfile database at {:?}", directory.path);
for logfile in directory.list_logfiles()? {
if let Some(logfile) = directory.load_logfile(&logfile, &config)? {
logfile_map.insert(logfile.get_id().get_string(), logfile);
}
}
Ok(LogfileMap {
directory,
config,
logfiles: Arc::new(RwLock::new(logfile_map)),
})
}
pub fn lookup(self: &LogfileMap, logfile_id: &LogfileID) -> Option<Arc<Logfile>> {
let logfiles_locked = match self.logfiles.read() {
Ok(l) => l,
Err(_) => fatal!("lock is poisoned"),
};
logfiles_locked.get(&logfile_id.get_string()).cloned()
}
pub fn lookup_or_create(
self: &LogfileMap,
logfile_id: &LogfileID,
) -> Result<Arc<Logfile>, ::Error> {
if let Some(logfile) = self.lookup(&logfile_id) {
return Ok(logfile);
}
let mut logfiles_locked = match self.logfiles.write() {
Ok(l) => l,
Err(_) => fatal!("lock is poisoned"),
};
if let Some(logfile) = logfiles_locked.get(&logfile_id.get_string()) {
return Ok(logfile.clone());
}
let logfile = self.directory.create_logfile(logfile_id, &self.config)?;
logfiles_locked.insert(logfile_id.get_string(), logfile.clone());
Ok(logfile)
}
pub fn set_storage_quota_for(&mut self, logfile_id: &LogfileID, quota: ::quota::StorageQuota) {
self.config.set_storage_quota_for(&logfile_id, quota);
let mut logfiles_locked = match self.logfiles.write() {
Ok(l) => l,
Err(_) => fatal!("lock is poisoned"),
};
logfiles_locked.remove(&logfile_id.get_string());
}
}