Skip to content

Commit

Permalink
chore: fixup deletion - take deleted list into account in find all
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonThormeyer committed Oct 10, 2024
1 parent 717a5c6 commit 0745969
Showing 1 changed file with 39 additions and 25 deletions.
64 changes: 39 additions & 25 deletions keystore/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::entities::{EntityBase, ProteusIdentity, ProteusPrekey, ProteusSession, UniqueEntity};
use crate::entities::{EntityBase, EntityIdStringExt, ProteusIdentity, ProteusPrekey, ProteusSession, UniqueEntity};

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-build (mls-provider)

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-build (crypto)

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-build (keystore)

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-test (keystore)

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-test (mls-provider)

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / proteus-wasm-test

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / wasm-core-test

unresolved import `crate::entities::EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build-and-test-wasm

unresolved import `crate::entities::EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

unused import: `EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

unresolved imports `crate::entities::ProteusIdentity`, `crate::entities::ProteusPrekey`, `crate::entities::ProteusSession`, `crate::entities::UniqueEntity`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / doc

unused import: `EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / Benchmark with Bencher

unused import: `EntityIdStringExt`

Check failure on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / Benchmark with Bencher

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / proteus-test

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / e2e-interop-test

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / test

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / coverage

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build-android

unused import: `EntityIdStringExt`

Check warning on line 1 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build-swift

unused import: `EntityIdStringExt`
use crate::{
connection::{Connection, DatabaseConnection, FetchFromDatabase, KeystoreDatabaseConnection, TransactionWrapper},
entities::{
Expand Down Expand Up @@ -119,6 +119,10 @@ impl EntityId {
_ => Err(CryptoKeystoreError::NotImplemented),
}
}

fn matches_entity<E: crate::entities::Entity>(&self, e: &E) -> CryptoKeystoreResult<bool> {
Ok(EntityId::from_collection_name(E::COLLECTION_NAME, e.id_raw())? == *self)
}
}

async fn execute_save(tx: &TransactionWrapper<'_>, entity: &Entity) -> CryptoKeystoreResult<()> {
Expand Down Expand Up @@ -192,7 +196,7 @@ impl KeystoreTransaction {
}

pub(crate) async fn save<

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

method `save` is never used

Check failure on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / doc

method `save` is never used

Check failure on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / Benchmark with Bencher

method `save` is never used

Check failure on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / Benchmark with Bencher

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / proteus-test

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / e2e-interop-test

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / test

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / coverage

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build-android

method `save` is never used

Check warning on line 198 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / build-swift

method `save` is never used
E: crate::entities::Entity<ConnectionType=KeystoreDatabaseConnection> + Sync + EntityTransactionExt,
E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection> + Sync + EntityTransactionExt,
>(
&self,
entity: E,
Expand All @@ -207,7 +211,7 @@ impl KeystoreTransaction {
}

pub(crate) async fn save_mut<
E: crate::entities::Entity<ConnectionType=KeystoreDatabaseConnection> + EntityTransactionExt + Sync,
E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection> + EntityTransactionExt + Sync,
>(
&self,
mut entity: E,
Expand All @@ -224,7 +228,7 @@ impl KeystoreTransaction {
}

pub(crate) async fn remove<
E: crate::entities::Entity<ConnectionType=KeystoreDatabaseConnection> + EntityTransactionExt,
E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection> + EntityTransactionExt,
S: AsRef<[u8]>,
>(
&self,
Expand All @@ -243,21 +247,19 @@ impl KeystoreTransaction {
}

pub(crate) async fn child_groups<
E: crate::entities::Entity<ConnectionType=KeystoreDatabaseConnection>
+ crate::entities::PersistedMlsGroupExt
+ Sync,
E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection>
+ crate::entities::PersistedMlsGroupExt

Check failure on line 251 in keystore/src/transaction.rs

View workflow job for this annotation

GitHub Actions / hack

cannot find trait `PersistedMlsGroupExt` in module `crate::entities`
+ Sync,
>(
&self,
entity: E,
persisted_records: Vec<E>,
) -> CryptoKeystoreResult<Vec<E>> {
let mut conn = self.cache.borrow_conn().await?;
let cached_records = entity.child_groups(conn.deref_mut()).await?;
Ok(Self::merge_records(
cached_records,
persisted_records,
EntityFindParams::default(),
))
Ok(self
.merge_records(cached_records, persisted_records, EntityFindParams::default())
.await)
}

pub(crate) async fn cred_delete_by_credential(&self, cred: Vec<u8>) -> CryptoKeystoreResult<()> {
Expand All @@ -269,7 +271,7 @@ impl KeystoreTransaction {
deleted_list.push(cred);
Ok(())
}

pub(crate) async fn find<E>(&self, id: &[u8]) -> CryptoKeystoreResult<Option<Option<E>>>
where
E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection>,
Expand Down Expand Up @@ -306,7 +308,7 @@ impl KeystoreTransaction {
params: EntityFindParams,
) -> CryptoKeystoreResult<Vec<E>> {
let cached_records: Vec<E> = self.cache.find_all(params.clone()).await?;
Ok(Self::merge_records(cached_records, persisted_records, params))
Ok(self.merge_records(cached_records, persisted_records, params).await)
}

pub(crate) async fn find_many<E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection>>(
Expand All @@ -315,32 +317,45 @@ impl KeystoreTransaction {
ids: &[Vec<u8>],
) -> CryptoKeystoreResult<Vec<E>> {
let cached_records: Vec<E> = self.cache.find_many(ids).await?;
Ok(Self::merge_records(
cached_records,
persisted_records,
EntityFindParams::default(),
))
Ok(self
.merge_records(cached_records, persisted_records, EntityFindParams::default())
.await)
}

fn merge_records<E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection>>(
async fn merge_records<E: crate::entities::Entity<ConnectionType = KeystoreDatabaseConnection>>(
&self,
records_a: Vec<E>,
records_b: Vec<E>,
params: EntityFindParams,
) -> Vec<E> {
let merged = records_a
.into_iter()
.chain(records_b)
.unique_by(|e| e.merge_key());
let merged = records_a.into_iter().chain(records_b).unique_by(|e| e.merge_key());

// The alternative to giving up laziness here would be to use a dynamically
// typed iterator Box<dyn Iterator<Item = E>> assigned to `merged`. The below approach
// trades stack allocation instead of heap allocation for laziness.
//
// Also, we have to do this before filtering by deleted records since filter map does not
// return an iterator that is double ended.
let merged: Vec<E> = if params.reverse {
merged.rev().collect()
} else {
merged.collect()
};

let deleted_list = self.deleted.read().await;
let merged = if deleted_list.is_empty() || merged.is_empty() {
merged
} else {
merged
.into_iter()
.filter(|e| {
let id = EntityId::from_collection_name(E::COLLECTION_NAME, e.id_raw());
let Ok(id) = id else { return false };
!deleted_list.contains(&id)
})
.collect()
};

merged
.into_iter()
.skip(params.offset.unwrap_or(0) as usize)
Expand Down Expand Up @@ -393,7 +408,6 @@ macro_rules! commit_transaction {
}

impl KeystoreTransaction {

/// Persists all the operations in the database. It will effectively open a transaction
/// internally, perform all the buffered operations and commit.
///
Expand Down

0 comments on commit 0745969

Please sign in to comment.