Skip to main content

reifydb_transaction/single/
read.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::mem;
5
6use reifydb_core::interface::store::{SingleVersionContains, SingleVersionGet, SingleVersionRow};
7use reifydb_runtime::sync::rwlock::{RwLock, RwLockReadGuard};
8use reifydb_type::{Result, util::hex};
9
10use super::*;
11use crate::error::TransactionError;
12
13pub struct KeyReadLock {
14	pub(super) _guard: RwLockReadGuard<'static, ()>,
15	pub(super) _arc: Arc<RwLock<()>>,
16}
17
18impl KeyReadLock {
19	pub(super) fn new(arc: Arc<RwLock<()>>) -> Self {
20		let guard = arc.read();
21
22		// SAFETY: We're extending the guard's lifetime to 'static.
23
24		let guard = unsafe { mem::transmute::<RwLockReadGuard<'_, ()>, RwLockReadGuard<'static, ()>>(guard) };
25
26		Self {
27			_arc: arc,
28			_guard: guard,
29		}
30	}
31}
32
33pub struct SingleReadTransaction<'a> {
34	pub(super) inner: &'a SingleTransactionInner,
35	pub(super) keys: Vec<EncodedKey>,
36	pub(super) _key_locks: Vec<KeyReadLock>,
37}
38
39impl<'a> SingleReadTransaction<'a> {
40	#[inline]
41	fn check_key_allowed(&self, key: &EncodedKey) -> Result<()> {
42		if self.keys.iter().any(|k| k == key) {
43			Ok(())
44		} else {
45			Err(TransactionError::KeyOutOfScope {
46				key: hex::encode(key),
47			}
48			.into())
49		}
50	}
51
52	pub fn get(&mut self, key: &EncodedKey) -> Result<Option<SingleVersionRow>> {
53		self.check_key_allowed(key)?;
54		let store = self.inner.store.read().clone();
55		SingleVersionGet::get(&store, key)
56	}
57
58	pub fn contains_key(&mut self, key: &EncodedKey) -> Result<bool> {
59		self.check_key_allowed(key)?;
60		let store = self.inner.store.read().clone();
61		SingleVersionContains::contains(&store, key)
62	}
63}