Skip to main content

tuwunel_database/map/
contains.rs

1use std::{convert::AsRef, fmt::Debug, future::Future, io::Write, sync::Arc};
2
3use futures::FutureExt;
4use serde::Serialize;
5use tuwunel_core::{
6	Result,
7	arrayvec::ArrayVec,
8	err, implement,
9	utils::{future::TryExtExt, result::FlatOk},
10};
11
12use crate::{keyval::KeyBuf, ser};
13
14/// Returns true if the map contains the key.
15/// - key is serialized into allocated buffer
16/// - harder errors may not be reported
17#[inline]
18#[implement(super::Map)]
19pub fn contains<K>(
20	self: &Arc<Self>,
21	key: &K,
22) -> impl Future<Output = bool> + Send + '_ + use<'_, K>
23where
24	K: Serialize + ?Sized + Debug,
25{
26	let mut buf = KeyBuf::new();
27	self.bcontains(key, &mut buf)
28}
29
30/// Returns true if the map contains the key.
31/// - key is serialized into stack-buffer
32/// - harder errors will panic
33#[inline]
34#[implement(super::Map)]
35pub fn acontains<const MAX: usize, K>(
36	self: &Arc<Self>,
37	key: &K,
38) -> impl Future<Output = bool> + Send + '_ + use<'_, MAX, K>
39where
40	K: Serialize + ?Sized + Debug,
41{
42	let mut buf = ArrayVec::<u8, MAX>::new();
43	self.bcontains(key, &mut buf)
44}
45
46/// Returns true if the map contains the key.
47/// - key is serialized into provided buffer
48/// - harder errors will panic
49#[implement(super::Map)]
50#[tracing::instrument(skip(self, buf), fields(%self), level = "trace")]
51pub fn bcontains<K, B>(
52	self: &Arc<Self>,
53	key: &K,
54	buf: &mut B,
55) -> impl Future<Output = bool> + Send + '_ + use<'_, K, B>
56where
57	K: Serialize + ?Sized + Debug,
58	B: Write + AsRef<[u8]>,
59{
60	let key = ser::serialize(buf, key).expect("failed to serialize query key");
61	self.exists(key).is_ok()
62}
63
64/// Returns Ok if the map contains the key.
65/// - key is raw
66#[inline]
67#[implement(super::Map)]
68pub fn exists<'a, K>(
69	self: &'a Arc<Self>,
70	key: &K,
71) -> impl Future<Output = Result> + Send + 'a + use<'a, K>
72where
73	K: AsRef<[u8]> + ?Sized + Debug + 'a,
74{
75	self.get(key).map(|res| res.map(|_| ()))
76}
77
78/// Returns Ok if the map contains the key; NotFound otherwise. Harder errors
79/// may not always be reported properly.
80#[implement(super::Map)]
81#[tracing::instrument(skip(self, key), fields(%self), level = "trace")]
82pub fn exists_blocking<K>(&self, key: &K) -> Result
83where
84	K: AsRef<[u8]> + ?Sized + Debug,
85{
86	self.maybe_exists(key)
87		.then(|| self.get_blocking(key))
88		.flat_ok()
89		.map(|_| ())
90		.ok_or_else(|| err!(Request(NotFound("Not found in database"))))
91}
92
93/// Rocksdb limits this to kBlockCacheTier internally so this is not actually a
94/// blocking call; in case that changes we set this as well in our read_options.
95#[implement(super::Map)]
96pub(crate) fn maybe_exists<K>(&self, key: &K) -> bool
97where
98	K: AsRef<[u8]> + ?Sized,
99{
100	self.engine
101		.db
102		.key_may_exist_cf_opt(&self.cf(), key, &self.cache_read_options)
103}