reifydb_transaction/single/svl/
read.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use diagnostic::transaction::key_out_of_scope;
5use parking_lot::{RwLock as ParkingRwLock, RwLockReadGuard as ParkingRwLockReadGuard};
6use reifydb_core::interface::SingleVersionQueryTransaction;
7use reifydb_store_transaction::{SingleVersionContains, SingleVersionGet};
8use reifydb_type::{diagnostic, error, util::hex};
9use self_cell::self_cell;
10
11use super::*;
12
13type ReadGuard<'a> = ParkingRwLockReadGuard<'a, ()>;
14
15// Safe self-referential struct that owns both the Arc and the guard borrowing from it
16self_cell! {
17	pub struct KeyReadLock {
18		owner: Arc<ParkingRwLock<()>>,
19		#[covariant]
20		dependent: ReadGuard,
21	}
22}
23
24pub struct SvlQueryTransaction<'a> {
25	pub(super) inner: &'a TransactionSvlInner,
26	pub(super) keys: Vec<EncodedKey>,
27	pub(super) _key_locks: Vec<KeyReadLock>,
28}
29
30impl<'a> SvlQueryTransaction<'a> {
31	#[inline]
32	fn check_key_allowed(&self, key: &EncodedKey) -> crate::Result<()> {
33		if self.keys.iter().any(|k| k == key) {
34			Ok(())
35		} else {
36			Err(error!(key_out_of_scope(hex::encode(&key))))
37		}
38	}
39}
40
41impl SingleVersionQueryTransaction for SvlQueryTransaction<'_> {
42	fn get(&mut self, key: &EncodedKey) -> crate::Result<Option<SingleVersionValues>> {
43		self.check_key_allowed(key)?;
44		let store = self.inner.store.read().unwrap();
45		store.get(key)
46	}
47
48	fn contains_key(&mut self, key: &EncodedKey) -> crate::Result<bool> {
49		self.check_key_allowed(key)?;
50		let store = self.inner.store.read().unwrap();
51		store.contains(key)
52	}
53}