use crate::*;
use std::convert::*;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::Arc;
pub struct RepositoryCache {
pub repository: Repository,
commits: SharedHashMap<Commit, Arc<Commit>>,
trees: SharedHashMap<Tree, Arc<Tree> >,
}
impl RepositoryCache {
pub fn new(repository: Repository) -> Self {
Self {
repository,
commits: Default::default(),
trees: Default::default(),
}
}
pub fn commit(&self, hash: &commit::Hash) -> io::Result<Arc<Commit>> {
if let Some(commit) = self.commits.get_clone(hash) {
return Ok(commit);
}
let commit = Arc::new(Commit::read(&self.repository, hash)?);
let mut bucket = self.commits.bucket_for(hash).lock().unwrap();
if let Some(commit) = bucket.get(hash) {
Ok(commit.clone())
} else {
bucket.insert(hash.clone(), commit.clone());
Ok(commit)
}
}
pub fn tree(&self, hash: &tree::Hash) -> io::Result<Arc<Tree>> {
if let Some(tree) = self.trees.get_clone(hash) {
return Ok(tree);
}
let tree = Arc::new(Tree::read(&self.repository, hash)?);
let mut bucket = self.trees.bucket_for(hash).lock().unwrap();
if let Some(tree) = bucket.get(hash) {
Ok(tree.clone())
} else {
bucket.insert(hash.clone(), tree.clone());
Ok(tree)
}
}
}
impl From<Repository> for RepositoryCache {
fn from(repository: Repository) -> Self {
Self::new(repository)
}
}
pub trait TryIntoSharedRepositoryCache {
fn try_into_src(self) -> io::Result<Arc<RepositoryCache>>;
}
impl TryIntoSharedRepositoryCache for PathBuf { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(&self)?))) } }
impl TryIntoSharedRepositoryCache for &PathBuf { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(self)?))) } }
impl TryIntoSharedRepositoryCache for &Path { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(self)?))) } }
impl TryIntoSharedRepositoryCache for String { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(&self)?))) } }
impl TryIntoSharedRepositoryCache for &String { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(self)?))) } }
impl TryIntoSharedRepositoryCache for &str { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(Repository::from_path(self)?))) } }
impl TryIntoSharedRepositoryCache for Repository { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(RepositoryCache::new(self))) } }
impl TryIntoSharedRepositoryCache for RepositoryCache { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(Arc::new(self)) } }
impl TryIntoSharedRepositoryCache for Arc<RepositoryCache> { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(self) } }
impl TryIntoSharedRepositoryCache for &Arc<RepositoryCache> { fn try_into_src(self) -> io::Result<Arc<RepositoryCache>> { Ok(self.clone()) } }