diff --git a/src/index_controller/local_index_controller/index_store.rs b/src/index_controller/local_index_controller/index_store.rs index 138fe57fc..7303a7849 100644 --- a/src/index_controller/local_index_controller/index_store.rs +++ b/src/index_controller/local_index_controller/index_store.rs @@ -2,6 +2,7 @@ use std::fs::{create_dir_all, remove_dir_all}; use std::path::{Path, PathBuf}; use std::sync::Arc; +use anyhow::bail; use chrono::{DateTime, Utc}; use dashmap::{DashMap, mapref::entry::Entry}; use heed::{Env, EnvOpenOptions, Database, types::{Str, SerdeJson, ByteSlice}, RoTxn, RwTxn}; @@ -141,7 +142,7 @@ impl IndexStore { Some(res) => Ok(res), None => { let uuid = Uuid::new_v4(); - let result = self.create_index(&mut txn, uuid, name, update_size, index_size)?; + let result = self.create_index_txn(&mut txn, uuid, name, update_size, index_size)?; // If we fail to commit the transaction, we must delete the database from the // file-system. if let Err(e) = txn.commit() { @@ -164,7 +165,7 @@ impl IndexStore { self.uuid_to_index.remove(&uuid); } - fn create_index( &self, + fn create_index_txn( &self, txn: &mut RwTxn, uuid: Uuid, name: impl AsRef, @@ -191,6 +192,30 @@ impl IndexStore { Ok((index, update_store)) } + /// Same a get or create, but returns an error if the index already exists. + pub fn create_index( + &self, + name: impl AsRef, + update_size: u64, + index_size: u64, + ) -> anyhow::Result<(Arc, Arc)> { + let uuid = Uuid::new_v4(); + let mut txn = self.env.write_txn()?; + + if self.name_to_uuid_db.get(&txn, name.as_ref())?.is_some() { + bail!("cannot create index {:?}: an index with this name already exists.") + } + + let result = self.create_index_txn(&mut txn, uuid, name, update_size, index_size)?; + // If we fail to commit the transaction, we must delete the database from the + // file-system. + if let Err(e) = txn.commit() { + self.clean_db(uuid); + return Err(e)?; + } + Ok(result) + } + /// Returns each index associated with it's metadata; pub fn list_indexes(&self) -> anyhow::Result> { let txn = self.env.read_txn()?; @@ -362,8 +387,8 @@ mod test { let index_size = 4096 * 100; let uuid = Uuid::new_v4(); let mut txn = store.env.write_txn().unwrap(); - store.create_index(&mut txn, uuid, name, update_size, index_size).unwrap(); - let uuid = store.name_to_uuid_meta.get(&txn, &name).unwrap(); + store.create_index_txn(&mut txn, uuid, name, update_size, index_size).unwrap(); + let uuid = store.name_to_uuid.get(&txn, &name).unwrap(); assert_eq!(store.uuid_to_index.len(), 1); assert!(uuid.is_some()); let uuid = Uuid::from_slice(uuid.unwrap()).unwrap(); diff --git a/src/index_controller/local_index_controller/mod.rs b/src/index_controller/local_index_controller/mod.rs index 6d6700639..ec70c4443 100644 --- a/src/index_controller/local_index_controller/mod.rs +++ b/src/index_controller/local_index_controller/mod.rs @@ -58,8 +58,9 @@ impl IndexController for LocalIndexController { Ok(pending.into()) } - fn create_index>(&self, _index_uid: S) -> anyhow::Result<()> { - todo!() + fn create_index>(&self, index_uid: S) -> anyhow::Result<()> { + self.indexes.create_index(index_uid, self.update_db_size, self.index_db_size)?; + Ok(()) } fn delete_index>(&self, _index_uid: S) -> anyhow::Result<()> {