foundationdb/
fdb_keys.rs

1// Copyright 2022 foundationdb-rs developers, https://github.com/Clikengo/foundationdb-rs/graphs/contributors
2// Copyright 2013-2018 Apple, Inc and the FoundationDB project authors.
3//
4// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
5// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
6// http://opensource.org/licenses/MIT>, at your option. This file may not be
7// copied, modified, or distributed except according to those terms.
8
9//! Definitions of FDBKeys, used in api version 700 and more.
10
11use crate::error;
12use crate::from_raw_fdb_slice;
13use crate::future::FdbFutureHandle;
14use crate::{FdbError, FdbResult};
15use foundationdb_sys as fdb_sys;
16use std::fmt;
17use std::ops::Deref;
18
19/// An slice of keys owned by a FoundationDB future
20pub struct FdbKeys {
21    _f: FdbFutureHandle,
22    keys: *const FdbKey,
23    len: i32,
24}
25unsafe impl Sync for FdbKeys {}
26unsafe impl Send for FdbKeys {}
27
28impl TryFrom<FdbFutureHandle> for FdbKeys {
29    type Error = FdbError;
30
31    fn try_from(f: FdbFutureHandle) -> FdbResult<Self> {
32        let mut keys = std::ptr::null();
33        let mut len = 0;
34
35        error::eval(unsafe { fdb_sys::fdb_future_get_key_array(f.as_ptr(), &mut keys, &mut len) })?;
36
37        Ok(FdbKeys {
38            _f: f,
39            keys: keys as *const FdbKey,
40            len,
41        })
42    }
43}
44
45impl Deref for FdbKeys {
46    type Target = [FdbKey];
47    fn deref(&self) -> &Self::Target {
48        assert_eq_size!(FdbKey, fdb_sys::FDBKey);
49        assert_eq_align!(FdbKey, u8);
50        from_raw_fdb_slice(self.keys, self.len as usize)
51    }
52}
53
54impl AsRef<[FdbKey]> for FdbKeys {
55    fn as_ref(&self) -> &[FdbKey] {
56        self.deref()
57    }
58}
59
60impl<'a> IntoIterator for &'a FdbKeys {
61    type Item = &'a FdbKey;
62    type IntoIter = std::slice::Iter<'a, FdbKey>;
63
64    fn into_iter(self) -> Self::IntoIter {
65        self.deref().iter()
66    }
67}
68
69/// An iterator of keyvalues owned by a foundationDB future
70pub struct FdbKeysIter {
71    f: std::rc::Rc<FdbFutureHandle>,
72    keys: *const FdbKey,
73    len: i32,
74    pos: i32,
75}
76
77impl Iterator for FdbKeysIter {
78    type Item = FdbRowKey;
79    fn next(&mut self) -> Option<Self::Item> {
80        #[allow(clippy::iter_nth_zero)]
81        self.nth(0)
82    }
83
84    fn size_hint(&self) -> (usize, Option<usize>) {
85        let rem = (self.len - self.pos) as usize;
86        (rem, Some(rem))
87    }
88
89    fn nth(&mut self, n: usize) -> Option<Self::Item> {
90        let pos = (self.pos as usize).checked_add(n);
91        match pos {
92            Some(pos) if pos < self.len as usize => {
93                // safe because pos < self.len
94                let row_key = unsafe { self.keys.add(pos) };
95                self.pos = pos as i32 + 1;
96
97                Some(FdbRowKey {
98                    _f: self.f.clone(),
99                    row_key,
100                })
101            }
102            _ => {
103                self.pos = self.len;
104                None
105            }
106        }
107    }
108}
109
110impl IntoIterator for FdbKeys {
111    type Item = FdbRowKey;
112    type IntoIter = FdbKeysIter;
113
114    fn into_iter(self) -> Self::IntoIter {
115        FdbKeysIter {
116            f: std::rc::Rc::new(self._f),
117            keys: self.keys,
118            len: self.len,
119            pos: 0,
120        }
121    }
122}
123/// A row key you can own
124///
125/// Until dropped, this might prevent multiple key/values from beeing freed.
126/// (i.e. the future that own the data is dropped once all data it provided is dropped)
127pub struct FdbRowKey {
128    _f: std::rc::Rc<FdbFutureHandle>,
129    row_key: *const FdbKey,
130}
131
132impl Deref for FdbRowKey {
133    type Target = FdbKey;
134    fn deref(&self) -> &Self::Target {
135        assert_eq_size!(FdbKey, fdb_sys::FDBKey);
136        assert_eq_align!(FdbKey, u8);
137        unsafe { &*(self.row_key) }
138    }
139}
140impl AsRef<FdbKey> for FdbRowKey {
141    fn as_ref(&self) -> &FdbKey {
142        self.deref()
143    }
144}
145impl PartialEq for FdbRowKey {
146    fn eq(&self, other: &Self) -> bool {
147        self.deref() == other.deref()
148    }
149}
150
151impl Eq for FdbRowKey {}
152impl fmt::Debug for FdbRowKey {
153    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154        self.deref().fmt(f)
155    }
156}
157
158#[repr(packed)]
159/// An FdbKey, owned by a FoundationDB Future
160pub struct FdbKey(fdb_sys::FDBKey);
161
162impl FdbKey {
163    /// retrieves the associated key
164    pub fn key(&self) -> &[u8] {
165        from_raw_fdb_slice(self.0.key, self.0.key_length as usize)
166    }
167}
168
169impl PartialEq for FdbKey {
170    fn eq(&self, other: &Self) -> bool {
171        self.key() == other.key()
172    }
173}
174
175impl Eq for FdbKey {}
176
177impl fmt::Debug for FdbKey {
178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179        write!(f, "({:?})", crate::tuple::Bytes::from(self.key()),)
180    }
181}