1use crate::util::*;
4use crate::value::*;
5use crate::{Entry, Store, StoreError};
6use std::time::{Duration, Instant};
7
8impl Store {
9 pub fn set(
13 &mut self,
14 key: &[u8],
15 value: Vec<u8>,
16 expire: Option<Duration>,
17 nx: bool,
18 xx: bool,
19 ) -> bool {
20 let expire_at = expire.map(|d| Instant::now() + d);
22 let new_value = Value::Str(SmallBytes::from_vec(value));
23 let pending_insert = match self.live_entry_mut(key) {
24 Some(e) => {
28 if nx {
29 return false;
30 }
31 e.value = new_value;
32 e.expire_at_ns = expire_at.and_then(crate::pack_deadline);
33 None
34 }
35 None => {
37 if xx {
38 return false;
39 }
40 Some(Entry::new(new_value, expire_at))
41 }
42 };
43 match pending_insert {
44 None => self.reweigh_entry(key),
45 Some(entry) => {
46 self.insert_entry(SmallBytes::from_slice(key), entry);
47 }
48 }
49 true
50 }
51
52 pub fn get(&mut self, key: &[u8]) -> Result<Option<&[u8]>, StoreError> {
53 match self.live_entry(key) {
54 None => Ok(None),
55 Some(e) => match &e.value {
56 Value::Str(v) => Ok(Some(v.as_slice())),
57 _ => Err(StoreError::WrongType),
58 },
59 }
60 }
61
62 pub fn strlen(&mut self, key: &[u8]) -> Result<usize, StoreError> {
63 Ok(self.get(key)?.map_or(0, |v| v.len()))
64 }
65
66 pub fn append(&mut self, key: &[u8], data: &[u8]) -> Result<usize, StoreError> {
67 let outcome = match self.live_entry_mut(key) {
68 Some(e) => match &mut e.value {
69 Value::Str(v) => {
70 let mut owned = std::mem::take(v).into_vec();
72 owned.extend_from_slice(data);
73 let new_len = owned.len();
74 *v = SmallBytes::from_vec(owned);
75 AppendOutcome::Reweigh(new_len)
76 }
77 _ => return Err(StoreError::WrongType),
78 },
79 None => AppendOutcome::Insert,
80 };
81 match outcome {
82 AppendOutcome::Reweigh(new_len) => {
83 self.reweigh_entry(key);
84 Ok(new_len)
85 }
86 AppendOutcome::Insert => {
87 self.insert_entry(
88 SmallBytes::from_slice(key),
89 Entry::new(Value::Str(SmallBytes::from_slice(data)), None),
90 );
91 Ok(data.len())
92 }
93 }
94 }
95
96 pub fn incr_by(&mut self, key: &[u8], delta: i64) -> Result<i64, StoreError> {
98 let outcome = match self.live_entry_mut(key) {
99 Some(e) => match &mut e.value {
100 Value::Str(v) => {
101 let next = parse_i64(v.as_slice())
102 .ok_or(StoreError::NotInteger)?
103 .checked_add(delta)
104 .ok_or(StoreError::Overflow)?;
105 *v = SmallBytes::from_vec(next.to_string().into_bytes());
106 IncrOutcome::Reweigh(next)
107 }
108 _ => return Err(StoreError::WrongType),
109 },
110 None => IncrOutcome::Insert(delta),
112 };
113 match outcome {
114 IncrOutcome::Reweigh(next) => {
115 self.reweigh_entry(key);
116 Ok(next)
117 }
118 IncrOutcome::Insert(next) => {
119 self.insert_entry(
120 SmallBytes::from_slice(key),
121 Entry::new(
122 Value::Str(SmallBytes::from_vec(next.to_string().into_bytes())),
123 None,
124 ),
125 );
126 Ok(next)
127 }
128 }
129 }
130
131 pub fn getset(&mut self, key: &[u8], val: Vec<u8>) -> Result<Option<Vec<u8>>, StoreError> {
134 let old = match self.live_entry(key) {
135 Some(e) => match &e.value {
136 Value::Str(v) => Some(v.to_vec()),
137 _ => return Err(StoreError::WrongType),
138 },
139 None => None,
140 };
141 self.insert_entry(
142 SmallBytes::from_slice(key),
143 Entry::new(Value::Str(SmallBytes::from_vec(val)), None),
144 );
145 Ok(old)
146 }
147
148 pub fn getdel(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>, StoreError> {
150 let is_str = match self.live_entry(key) {
151 None => return Ok(None),
152 Some(e) => matches!(e.value, Value::Str(_)),
153 };
154 if !is_str {
155 return Err(StoreError::WrongType);
156 }
157 match self.remove_entry(key) {
158 Some(Entry {
159 value: Value::Str(v),
160 ..
161 }) => Ok(Some(v.into_vec())),
162 _ => Ok(None),
163 }
164 }
165
166 pub fn incr_by_float(&mut self, key: &[u8], delta: f64) -> Result<Vec<u8>, StoreError> {
168 let outcome = match self.live_entry_mut(key) {
169 Some(e) => match &mut e.value {
170 Value::Str(v) => {
171 let next = parse_f64(v.as_slice()).ok_or(StoreError::NotFloat)? + delta;
172 if !next.is_finite() {
173 return Err(StoreError::NotFloat);
174 }
175 let bytes = fmt_num(next);
176 *v = SmallBytes::from_slice(&bytes);
177 FloatOutcome::Reweigh(bytes)
178 }
179 _ => return Err(StoreError::WrongType),
180 },
181 None => {
182 if !delta.is_finite() {
184 return Err(StoreError::NotFloat);
185 }
186 FloatOutcome::Insert(fmt_num(delta))
187 }
188 };
189 match outcome {
190 FloatOutcome::Reweigh(bytes) => {
191 self.reweigh_entry(key);
192 Ok(bytes)
193 }
194 FloatOutcome::Insert(bytes) => {
195 self.insert_entry(
196 SmallBytes::from_slice(key),
197 Entry::new(Value::Str(SmallBytes::from_slice(&bytes)), None),
198 );
199 Ok(bytes)
200 }
201 }
202 }
203}
204
205enum AppendOutcome {
206 Reweigh(usize),
207 Insert,
208}
209
210enum IncrOutcome {
211 Reweigh(i64),
212 Insert(i64),
213}
214
215enum FloatOutcome {
216 Reweigh(Vec<u8>),
217 Insert(Vec<u8>),
218}