2021-09-24 11:53:11 +02:00
|
|
|
pub mod error;
|
2021-10-04 18:31:05 +02:00
|
|
|
pub mod index_store;
|
2021-09-28 22:22:59 +02:00
|
|
|
pub mod uuid_store;
|
2021-09-24 11:53:11 +02:00
|
|
|
|
|
|
|
use std::path::Path;
|
|
|
|
|
2021-09-28 22:22:59 +02:00
|
|
|
use error::{IndexResolverError, Result};
|
2021-09-24 11:53:11 +02:00
|
|
|
use index_store::{IndexStore, MapIndexStore};
|
2021-09-28 22:22:59 +02:00
|
|
|
use uuid::Uuid;
|
|
|
|
use uuid_store::{HeedUuidStore, UuidStore};
|
2021-09-24 11:53:11 +02:00
|
|
|
|
2021-09-28 22:22:59 +02:00
|
|
|
use crate::{
|
|
|
|
index::{update_handler::UpdateHandler, Index},
|
|
|
|
options::IndexerOpts,
|
|
|
|
};
|
2021-09-24 11:53:11 +02:00
|
|
|
|
|
|
|
pub type HardStateIndexResolver = IndexResolver<HeedUuidStore, MapIndexStore>;
|
|
|
|
|
2021-09-28 22:22:59 +02:00
|
|
|
pub fn create_index_resolver(
|
|
|
|
path: impl AsRef<Path>,
|
|
|
|
index_size: usize,
|
|
|
|
indexer_opts: &IndexerOpts,
|
|
|
|
) -> anyhow::Result<HardStateIndexResolver> {
|
2021-09-24 11:53:11 +02:00
|
|
|
let uuid_store = HeedUuidStore::new(&path)?;
|
|
|
|
let index_store = MapIndexStore::new(&path, index_size, indexer_opts)?;
|
|
|
|
Ok(IndexResolver::new(uuid_store, index_store))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct IndexResolver<U, I> {
|
|
|
|
index_uuid_store: U,
|
|
|
|
index_store: I,
|
|
|
|
}
|
|
|
|
|
2021-09-28 11:59:55 +02:00
|
|
|
impl IndexResolver<HeedUuidStore, MapIndexStore> {
|
|
|
|
pub fn load_dump(
|
|
|
|
src: impl AsRef<Path>,
|
|
|
|
dst: impl AsRef<Path>,
|
|
|
|
index_db_size: usize,
|
|
|
|
indexer_opts: &IndexerOpts,
|
2021-09-28 22:22:59 +02:00
|
|
|
) -> anyhow::Result<()> {
|
2021-09-28 11:59:55 +02:00
|
|
|
HeedUuidStore::load_dump(&src, &dst)?;
|
|
|
|
|
|
|
|
let indexes_path = src.as_ref().join("indexes");
|
|
|
|
let indexes = indexes_path.read_dir()?;
|
|
|
|
|
2021-09-28 20:20:13 +02:00
|
|
|
let update_handler = UpdateHandler::new(indexer_opts)?;
|
2021-09-28 11:59:55 +02:00
|
|
|
for index in indexes {
|
|
|
|
let index = index?;
|
|
|
|
Index::load_dump(&index.path(), &dst, index_db_size, &update_handler)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-28 22:22:59 +02:00
|
|
|
impl<U, I> IndexResolver<U, I>
|
|
|
|
where
|
|
|
|
U: UuidStore,
|
|
|
|
I: IndexStore,
|
2021-09-24 11:53:11 +02:00
|
|
|
{
|
2021-09-28 22:22:59 +02:00
|
|
|
pub fn new(index_uuid_store: U, index_store: I) -> Self {
|
2021-09-24 11:53:11 +02:00
|
|
|
Self {
|
|
|
|
index_uuid_store,
|
|
|
|
index_store,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-28 11:59:55 +02:00
|
|
|
pub async fn dump(&self, path: impl AsRef<Path>) -> Result<Vec<Index>> {
|
|
|
|
let uuids = self.index_uuid_store.dump(path.as_ref().to_owned()).await?;
|
|
|
|
let mut indexes = Vec::new();
|
|
|
|
for uuid in uuids {
|
|
|
|
indexes.push(self.get_index_by_uuid(uuid).await?);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(indexes)
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 12:05:22 +02:00
|
|
|
pub async fn get_uuids_size(&self) -> Result<u64> {
|
|
|
|
Ok(self.index_uuid_store.get_size().await?)
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-27 16:48:03 +02:00
|
|
|
pub async fn snapshot(&self, path: impl AsRef<Path>) -> Result<Vec<Index>> {
|
2021-09-28 22:22:59 +02:00
|
|
|
let uuids = self
|
|
|
|
.index_uuid_store
|
|
|
|
.snapshot(path.as_ref().to_owned())
|
|
|
|
.await?;
|
2021-09-27 16:48:03 +02:00
|
|
|
let mut indexes = Vec::new();
|
|
|
|
for uuid in uuids {
|
|
|
|
indexes.push(self.get_index_by_uuid(uuid).await?);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(indexes)
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
|
2021-09-28 18:10:09 +02:00
|
|
|
pub async fn create_index(&self, uid: String, primary_key: Option<String>) -> Result<Index> {
|
|
|
|
if !is_index_uid_valid(&uid) {
|
|
|
|
return Err(IndexResolverError::BadlyFormatted(uid));
|
|
|
|
}
|
2021-09-24 11:53:11 +02:00
|
|
|
let uuid = Uuid::new_v4();
|
|
|
|
let index = self.index_store.create(uuid, primary_key).await?;
|
|
|
|
self.index_uuid_store.insert(uid, uuid).await?;
|
2021-09-28 18:10:09 +02:00
|
|
|
Ok(index)
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn list(&self) -> Result<Vec<(String, Index)>> {
|
|
|
|
let uuids = self.index_uuid_store.list().await?;
|
|
|
|
let mut indexes = Vec::new();
|
|
|
|
for (name, uuid) in uuids {
|
|
|
|
match self.index_store.get(uuid).await? {
|
2021-09-28 22:22:59 +02:00
|
|
|
Some(index) => indexes.push((name, index)),
|
2021-09-24 11:53:11 +02:00
|
|
|
None => {
|
|
|
|
// we found an unexisting index, we remove it from the uuid store
|
|
|
|
let _ = self.index_uuid_store.delete(name).await;
|
2021-09-28 22:22:59 +02:00
|
|
|
}
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(indexes)
|
|
|
|
}
|
|
|
|
|
2021-09-28 18:10:09 +02:00
|
|
|
pub async fn delete_index(&self, uid: String) -> Result<Uuid> {
|
2021-09-24 11:53:11 +02:00
|
|
|
match self.index_uuid_store.delete(uid.clone()).await? {
|
|
|
|
Some(uuid) => {
|
|
|
|
let _ = self.index_store.delete(uuid).await;
|
2021-09-28 18:10:09 +02:00
|
|
|
Ok(uuid)
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
None => Err(IndexResolverError::UnexistingIndex(uid)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_index_by_uuid(&self, uuid: Uuid) -> Result<Index> {
|
|
|
|
// TODO: Handle this error better.
|
2021-09-28 22:22:59 +02:00
|
|
|
self.index_store
|
|
|
|
.get(uuid)
|
|
|
|
.await?
|
|
|
|
.ok_or_else(|| IndexResolverError::UnexistingIndex(String::new()))
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_index(&self, uid: String) -> Result<Index> {
|
|
|
|
match self.index_uuid_store.get_uuid(uid).await? {
|
|
|
|
(name, Some(uuid)) => {
|
|
|
|
match self.index_store.get(uuid).await? {
|
|
|
|
Some(index) => Ok(index),
|
|
|
|
None => {
|
|
|
|
// For some reason we got a uuid to an unexisting index, we return an error,
|
2021-09-29 12:02:27 +02:00
|
|
|
// and remove the uuid from the uuid store.
|
2021-09-24 11:53:11 +02:00
|
|
|
let _ = self.index_uuid_store.delete(name.clone()).await;
|
|
|
|
Err(IndexResolverError::UnexistingIndex(name))
|
2021-09-28 22:22:59 +02:00
|
|
|
}
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
}
|
2021-09-28 22:22:59 +02:00
|
|
|
(name, _) => Err(IndexResolverError::UnexistingIndex(name)),
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn get_uuid(&self, uid: String) -> Result<Uuid> {
|
|
|
|
match self.index_uuid_store.get_uuid(uid).await? {
|
|
|
|
(_, Some(uuid)) => Ok(uuid),
|
2021-09-28 22:22:59 +02:00
|
|
|
(name, _) => Err(IndexResolverError::UnexistingIndex(name)),
|
2021-09-24 11:53:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-09-28 18:10:09 +02:00
|
|
|
|
|
|
|
fn is_index_uid_valid(uid: &str) -> bool {
|
|
|
|
uid.chars()
|
|
|
|
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
|
|
|
}
|