use cache::Cache;
use std::collections::HashMap;
use priority_function::{PriorityFunction, DEFAULT_PRIORITY_FUNCTION};
use std::usize;
#[derive(Debug, PartialEq)]
pub enum CacheBuildError {
SizeLimitNotSet,
MinFileSizeIsLargerThanMaxFileSize
}
#[derive(Debug)]
pub struct CacheBuilder {
size_limit: Option<usize>,
priority_function: Option<PriorityFunction>,
min_file_size: Option<usize>,
max_file_size: Option<usize>
}
impl CacheBuilder {
pub fn new() -> CacheBuilder {
CacheBuilder {
size_limit: None,
priority_function: None,
min_file_size: None,
max_file_size: None
}
}
pub fn size_limit_bytes<'a>(&'a mut self, size_limit_bytes: usize) -> &mut Self {
self.size_limit = Some(size_limit_bytes);
self
}
pub fn priority_function<'a>(&'a mut self, priority_function: PriorityFunction) -> &mut Self {
self.priority_function = Some(priority_function);
self
}
pub fn min_file_size<'a>(&'a mut self, min_size: usize) -> &mut Self {
self.min_file_size = Some(min_size);
self
}
pub fn max_file_size<'a>(&'a mut self, max_size: usize) -> &mut Self {
self.max_file_size = Some(max_size);
self
}
pub fn build(&self) -> Result<Cache, CacheBuildError> {
let size_limit = match self.size_limit {
Some(s) => s,
None => return Err(CacheBuildError::SizeLimitNotSet)
};
let priority_function: PriorityFunction = match self.priority_function {
Some(p) => p,
None => DEFAULT_PRIORITY_FUNCTION
};
if let Some(min_file_size) = self.min_file_size {
if let Some(max_file_size) = self.max_file_size {
if min_file_size > max_file_size {
return Err(CacheBuildError::MinFileSizeIsLargerThanMaxFileSize)
}
}
}
let min_file_size: usize = match self.min_file_size {
Some(min) => min,
None => 0
};
let max_file_size: usize = match self.max_file_size {
Some(max) => max,
None => usize::MAX
};
Ok(
Cache {
size_limit,
min_file_size,
max_file_size,
priority_function,
file_map: HashMap::new(),
access_count_map: HashMap::new()
}
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_size_error(){
assert_eq!(CacheBuildError::SizeLimitNotSet, CacheBuilder::new().build().unwrap_err());
}
#[test]
fn min_greater_than_max() {
let e: CacheBuildError = CacheBuilder::new()
.size_limit_bytes(1024 * 1024 * 10)
.min_file_size(1024 * 1024 * 5)
.max_file_size(1024 * 1024 * 4)
.build()
.unwrap_err();
assert_eq!(CacheBuildError::MinFileSizeIsLargerThanMaxFileSize, e);
}
#[test]
fn can_build() {
let _: Cache = CacheBuilder::new()
.size_limit_bytes(1024 * 1024 * 20)
.priority_function(|access_count: usize, size: usize| {
access_count * size
})
.max_file_size(1024 * 1024 * 10)
.min_file_size(1024 * 10)
.build().unwrap();
}
}