implement update index

This commit is contained in:
mpostma 2021-03-12 14:48:43 +01:00
parent 77d5dd452f
commit c4846dafca
No known key found for this signature in database
GPG key ID: CBC8A7C1D7A28C3A
6 changed files with 75 additions and 15 deletions

View file

@ -17,7 +17,7 @@ use tokio::task::spawn_blocking;
use tokio::fs::remove_dir_all;
use uuid::Uuid;
use super::get_arc_ownership_blocking;
use super::{IndexSettings, get_arc_ownership_blocking};
use super::update_handler::UpdateHandler;
use crate::index::UpdateResult as UResult;
use crate::index::{Document, Index, SearchQuery, SearchResult, Settings};
@ -42,6 +42,10 @@ pub struct IndexMeta {
impl IndexMeta {
fn new(index: &Index) -> Result<Self> {
let txn = index.read_txn()?;
Self::new_txn(index, &txn)
}
fn new_txn(index: &Index, txn: &heed::RoTxn) -> Result<Self> {
let created_at = index.created_at(&txn)?;
let updated_at = index.updated_at(&txn)?;
let primary_key = index.primary_key(&txn)?.map(String::from);
@ -90,6 +94,11 @@ enum IndexMsg {
uuid: Uuid,
ret: oneshot::Sender<Result<Option<IndexMeta>>>,
},
UpdateIndex {
uuid: Uuid,
index_settings: IndexSettings,
ret: oneshot::Sender<Result<IndexMeta>>,
}
}
struct IndexActor<S> {
@ -109,6 +118,8 @@ pub enum IndexError {
UnexistingIndex,
#[error("Heed error: {0}")]
HeedError(#[from] heed::Error),
#[error("Existing primary key")]
ExistingPrimaryKey,
}
#[async_trait::async_trait]
@ -230,6 +241,9 @@ impl<S: IndexStore + Sync + Send> IndexActor<S> {
GetMeta { uuid, ret } => {
let _ = ret.send(self.handle_get_meta(uuid).await);
}
UpdateIndex { uuid, index_settings, ret } => {
let _ = ret.send(self.handle_update_index(uuid, index_settings).await);
}
}
}
@ -352,6 +366,33 @@ impl<S: IndexStore + Sync + Send> IndexActor<S> {
None => Ok(None),
}
}
async fn handle_update_index(&self, uuid: Uuid, index_settings: IndexSettings) -> Result<IndexMeta> {
let index = self.store
.get(uuid)
.await?
.ok_or(IndexError::UnexistingIndex)?;
spawn_blocking(move || {
match index_settings.primary_key {
Some(ref primary_key) => {
let mut txn = index.write_txn()?;
if index.primary_key(&txn)?.is_some() {
return Err(IndexError::ExistingPrimaryKey)
}
index.put_primary_key(&mut txn, primary_key)?;
let meta = IndexMeta::new_txn(&index, &txn)?;
txn.commit()?;
Ok(meta)
},
None => {
let meta = IndexMeta::new(&index)?;
Ok(meta)
},
}
}).await
.map_err(|e| IndexError::Error(e.into()))?
}
}
#[derive(Clone)]
@ -459,6 +500,17 @@ impl IndexActorHandle {
let _ = self.read_sender.send(msg).await;
Ok(receiver.await.expect("IndexActor has been killed")?)
}
pub async fn update_index(
&self,
uuid: Uuid,
index_settings: IndexSettings
) -> Result<IndexMeta> {
let (ret, receiver) = oneshot::channel();
let msg = IndexMsg::UpdateIndex { uuid, index_settings, ret };
let _ = self.read_sender.send(msg).await;
Ok(receiver.await.expect("IndexActor has been killed")?)
}
}
struct HeedIndexStore {

View file

@ -9,6 +9,7 @@ use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
use anyhow::bail;
use actix_web::web::{Bytes, Payload};
use futures::stream::StreamExt;
use milli::update::{IndexDocumentsMethod, UpdateFormat};
@ -237,8 +238,17 @@ impl IndexController {
Ok(document)
}
fn update_index(&self, uid: String, index_settings: IndexSettings) -> anyhow::Result<IndexMetadata> {
todo!()
pub async fn update_index(&self, uid: String, index_settings: IndexSettings) -> anyhow::Result<IndexMetadata> {
if index_settings.uid.is_some() {
bail!("Can't change the index uid.")
}
let uuid = self.uuid_resolver
.resolve(uid.clone())
.await?;
let meta = self.index_handle.update_index(uuid, index_settings).await?;
let meta = IndexMetadata { uid, meta };
Ok(meta)
}
pub async fn search(&self, uid: String, query: SearchQuery) -> anyhow::Result<SearchResult> {