tikv_client/kv/
key.rs

1// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2
3use std::fmt;
4use std::ops::Bound;
5use std::u8;
6
7#[allow(unused_imports)]
8#[cfg(test)]
9use proptest::arbitrary::any_with;
10#[allow(unused_imports)]
11#[cfg(test)]
12use proptest::collection::size_range;
13#[cfg(test)]
14use proptest_derive::Arbitrary;
15
16use super::HexRepr;
17use crate::kv::codec::BytesEncoder;
18use crate::kv::codec::{self};
19use crate::proto::kvrpcpb;
20
21const _PROPTEST_KEY_MAX: usize = 1024 * 2; // 2 KB
22
23/// The key part of a key/value pair.
24///
25/// In TiKV, keys are an ordered sequence of bytes. This has an advantage over choosing `String` as
26/// valid `UTF-8` is not required. This means that the user is permitted to store any data they wish,
27/// as long as it can be represented by bytes. (Which is to say, pretty much anything!)
28///
29/// This type wraps around an owned value, so it should be treated it like `String` or `Vec<u8>`.
30///
31/// # Examples
32/// ```rust
33/// use tikv_client::Key;
34///
35/// let static_str: &'static str = "TiKV";
36/// let from_static_str = Key::from(static_str.to_owned());
37///
38/// let string: String = String::from(static_str);
39/// let from_string = Key::from(string);
40/// assert_eq!(from_static_str, from_string);
41///
42/// let vec: Vec<u8> = static_str.as_bytes().to_vec();
43/// let from_vec = Key::from(vec);
44/// assert_eq!(from_static_str, from_vec);
45///
46/// let bytes = static_str.as_bytes().to_vec();
47/// let from_bytes = Key::from(bytes);
48/// assert_eq!(from_static_str, from_bytes);
49/// ```
50///
51/// While `.into()` is usually sufficient for obtaining the buffer itself, sometimes type inference
52/// isn't able to determine the correct type. Notably in the `assert_eq!()` and `==` cases. In
53/// these cases using the fully-qualified-syntax is useful:
54///
55/// # Examples
56/// ```rust
57/// use tikv_client::Key;
58///
59/// let buf = "TiKV".as_bytes().to_owned();
60/// let key = Key::from(buf.clone());
61/// assert_eq!(Into::<Vec<u8>>::into(key), buf);
62/// ```
63///
64/// Many functions which accept a `Key` accept an `Into<Key>`, which means all of the above types
65/// can be passed directly to those functions.
66#[derive(Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
67#[cfg_attr(test, derive(Arbitrary))]
68#[repr(transparent)]
69pub struct Key(
70    #[cfg_attr(
71        test,
72        proptest(strategy = "any_with::<Vec<u8>>((size_range(_PROPTEST_KEY_MAX), ()))")
73    )]
74    pub(super) Vec<u8>,
75);
76
77impl AsRef<Key> for kvrpcpb::Mutation {
78    fn as_ref(&self) -> &Key {
79        self.key.as_ref()
80    }
81}
82
83impl Key {
84    /// The empty key.
85    pub const EMPTY: Self = Key(Vec::new());
86
87    /// Return whether the key is empty.
88    #[inline]
89    pub fn is_empty(&self) -> bool {
90        self.0.is_empty()
91    }
92
93    /// Return whether the last byte of key is 0.
94    #[inline]
95    pub(super) fn zero_terminated(&self) -> bool {
96        self.0.last().map(|i| *i == 0).unwrap_or(false)
97    }
98
99    /// Push a zero to the end of the key.
100    ///
101    /// Extending a zero makes the new key the smallest key that is greater than than the original one, i.e. the succeeder.
102    #[inline]
103    pub(super) fn push_zero(&mut self) {
104        self.0.push(0)
105    }
106
107    /// Convert the key to a lower bound. The key is treated as inclusive.
108    #[inline]
109    pub(super) fn into_lower_bound(mut self) -> Bound<Key> {
110        if self.zero_terminated() {
111            self.0.pop().unwrap();
112            Bound::Excluded(self)
113        } else {
114            Bound::Included(self)
115        }
116    }
117
118    /// Convert the key to an upper bound. The key is treated as exclusive.
119    #[inline]
120    pub(super) fn into_upper_bound(mut self) -> Bound<Key> {
121        if self.zero_terminated() {
122            self.0.pop().unwrap();
123            Bound::Included(self)
124        } else {
125            Bound::Excluded(self)
126        }
127    }
128
129    /// Return the MVCC-encoded representation of the key.
130    #[inline]
131    #[must_use]
132    pub fn to_encoded(&self) -> Key {
133        let len = codec::max_encoded_bytes_size(self.0.len());
134        let mut encoded = Vec::with_capacity(len);
135        encoded.encode_bytes(&self.0, false).unwrap();
136        Key(encoded)
137    }
138
139    pub fn len(&self) -> usize {
140        self.0.len()
141    }
142}
143
144impl From<Vec<u8>> for Key {
145    fn from(v: Vec<u8>) -> Self {
146        Key(v)
147    }
148}
149
150impl From<String> for Key {
151    fn from(v: String) -> Key {
152        Key(v.into_bytes())
153    }
154}
155
156impl From<Key> for Vec<u8> {
157    fn from(key: Key) -> Self {
158        key.0
159    }
160}
161
162impl<'a> From<&'a Key> for &'a [u8] {
163    fn from(key: &'a Key) -> Self {
164        &key.0
165    }
166}
167
168impl<'a> From<&'a Vec<u8>> for &'a Key {
169    fn from(key: &'a Vec<u8>) -> Self {
170        unsafe { &*(key as *const Vec<u8> as *const Key) }
171    }
172}
173impl AsRef<Key> for Key {
174    fn as_ref(&self) -> &Key {
175        self
176    }
177}
178
179impl AsRef<Key> for Vec<u8> {
180    fn as_ref(&self) -> &Key {
181        unsafe { &*(self as *const Vec<u8> as *const Key) }
182    }
183}
184
185impl fmt::Debug for Key {
186    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187        write!(f, "Key({})", HexRepr(&self.0))
188    }
189}