|
1 | | -use crate::{Cas, Error, Store, StoreManager}; |
| 1 | +use crate::{Cas, Error, Store, StoreManager, SwapError}; |
2 | 2 | use lru::LruCache; |
3 | 3 | use spin_core::async_trait; |
4 | 4 | use std::{ |
@@ -92,10 +92,10 @@ impl<T: StoreManager> StoreManager for CachingStoreManager<T> { |
92 | 92 | async fn get(&self, name: &str) -> Result<Arc<dyn Store>, Error> { |
93 | 93 | Ok(Arc::new(CachingStore { |
94 | 94 | inner: self.inner.get(name).await?, |
95 | | - state: AsyncMutex::new(CachingStoreState { |
| 95 | + state: Arc::new(AsyncMutex::new(CachingStoreState { |
96 | 96 | cache: LruCache::new(self.capacity), |
97 | 97 | previous_task: None, |
98 | | - }), |
| 98 | + })), |
99 | 99 | })) |
100 | 100 | } |
101 | 101 |
|
@@ -143,7 +143,7 @@ impl CachingStoreState { |
143 | 143 |
|
144 | 144 | struct CachingStore { |
145 | 145 | inner: Arc<dyn Store>, |
146 | | - state: AsyncMutex<CachingStoreState>, |
| 146 | + state: Arc<AsyncMutex<CachingStoreState>>, |
147 | 147 | } |
148 | 148 |
|
149 | 149 | #[async_trait] |
@@ -242,49 +242,118 @@ impl Store for CachingStore { |
242 | 242 | &self, |
243 | 243 | keys: Vec<String>, |
244 | 244 | ) -> anyhow::Result<Vec<(String, Option<Vec<u8>>)>, Error> { |
245 | | - // // Retrieve the specified value from the cache, lazily populating the cache as necessary. |
246 | | - // let mut state = self.state.lock().await; |
247 | | - // |
248 | | - // let mut keys_and_values: Vec<Option<(String, Vec<u8>)>> = Vec::new(); |
249 | | - // let mut keys_not_found: Vec<String> = Vec::new(); |
250 | | - // for key in keys { |
251 | | - // match state.cache.get(key.as_str()).cloned() { |
252 | | - // Some(value) => keys_and_values.push(Some((key, value))), |
253 | | - // None => keys_not_found.push(key), |
254 | | - // } |
255 | | - // } |
256 | | - // |
257 | | - // // guarantee the guest will read its own writes even if entries have been popped off the end of the LRU |
258 | | - // // cache prior to their corresponding writes reaching the backing store. |
259 | | - // state.flush().await?; |
260 | | - // |
261 | | - // let value = self.inner.get(key).await?; |
262 | | - // |
263 | | - // state.cache.put(key.to_owned(), value.clone()); |
264 | | - // |
265 | | - // Ok(value) |
266 | | - // |
| 245 | + let mut state = self.state.lock().await; |
| 246 | + let mut found: Vec<(String, Option<Vec<u8>>)> = Vec::new(); |
| 247 | + let mut not_found: Vec<String> = Vec::new(); |
| 248 | + for key in keys { |
| 249 | + match state.cache.get(key.as_str()) { |
| 250 | + Some(Some(value)) => found.push((key, Some(value.clone()))), |
| 251 | + _ => not_found.push(key), |
| 252 | + } |
| 253 | + } |
| 254 | + |
| 255 | + let keys_and_values = self.inner.get_many(not_found).await?; |
| 256 | + for (key, value) in keys_and_values { |
| 257 | + found.push((key.clone(), value.clone())); |
| 258 | + state.cache.put(key, value); |
| 259 | + } |
267 | 260 |
|
268 | | - todo!() |
| 261 | + Ok(found) |
269 | 262 | } |
270 | 263 |
|
271 | 264 | async fn set_many(&self, key_values: Vec<(String, Vec<u8>)>) -> anyhow::Result<(), Error> { |
272 | | - todo!() |
| 265 | + let mut state = self.state.lock().await; |
| 266 | + |
| 267 | + for (key, value) in key_values.clone() { |
| 268 | + state.cache.put(key, Some(value)); |
| 269 | + } |
| 270 | + |
| 271 | + self.inner.set_many(key_values).await |
273 | 272 | } |
274 | 273 |
|
275 | 274 | async fn delete_many(&self, keys: Vec<String>) -> anyhow::Result<(), Error> { |
276 | | - todo!() |
| 275 | + let mut state = self.state.lock().await; |
| 276 | + |
| 277 | + for key in keys.clone() { |
| 278 | + state.cache.put(key, None); |
| 279 | + } |
| 280 | + |
| 281 | + self.inner.delete_many(keys).await |
277 | 282 | } |
278 | 283 |
|
279 | 284 | async fn increment(&self, key: String, delta: i64) -> anyhow::Result<i64, Error> { |
280 | | - todo!() |
| 285 | + let mut state = self.state.lock().await; |
| 286 | + let counter = self.inner.increment(key.clone(), delta).await?; |
| 287 | + state |
| 288 | + .cache |
| 289 | + .put(key, Some(i64::to_le_bytes(counter).to_vec())); |
| 290 | + Ok(counter) |
281 | 291 | } |
282 | 292 |
|
283 | 293 | async fn new_compare_and_swap( |
284 | 294 | &self, |
285 | 295 | bucket_rep: u32, |
286 | 296 | key: &str, |
287 | 297 | ) -> anyhow::Result<Arc<dyn Cas>, Error> { |
288 | | - todo!() |
| 298 | + let inner = self.inner.new_compare_and_swap(bucket_rep, key).await?; |
| 299 | + Ok(Arc::new(CompareAndSwap { |
| 300 | + bucket_rep, |
| 301 | + state: self.state.clone(), |
| 302 | + key: key.to_string(), |
| 303 | + inner_cas: inner, |
| 304 | + })) |
| 305 | + } |
| 306 | +} |
| 307 | + |
| 308 | +struct CompareAndSwap { |
| 309 | + bucket_rep: u32, |
| 310 | + key: String, |
| 311 | + state: Arc<AsyncMutex<CachingStoreState>>, |
| 312 | + inner_cas: Arc<dyn Cas>, |
| 313 | +} |
| 314 | + |
| 315 | +#[async_trait] |
| 316 | +impl Cas for CompareAndSwap { |
| 317 | + async fn current(&self) -> anyhow::Result<Option<Vec<u8>>, Error> { |
| 318 | + let mut state = self.state.lock().await; |
| 319 | + state.flush().await?; |
| 320 | + let res = self.inner_cas.current().await; |
| 321 | + match res.clone() { |
| 322 | + Ok(value) => { |
| 323 | + state.cache.put(self.key.clone(), value.clone()); |
| 324 | + state.flush().await?; |
| 325 | + Ok(value) |
| 326 | + } |
| 327 | + Err(err) => Err(err), |
| 328 | + }?; |
| 329 | + res |
| 330 | + } |
| 331 | + |
| 332 | + async fn swap(&self, value: Vec<u8>) -> anyhow::Result<(), SwapError> { |
| 333 | + let mut state = self.state.lock().await; |
| 334 | + state |
| 335 | + .flush() |
| 336 | + .await |
| 337 | + .map_err(|_e| SwapError::Other("failed flushing".to_string()))?; |
| 338 | + let res = self.inner_cas.swap(value.clone()).await; |
| 339 | + match res { |
| 340 | + Ok(()) => { |
| 341 | + state.cache.put(self.key.clone(), Some(value)); |
| 342 | + state |
| 343 | + .flush() |
| 344 | + .await |
| 345 | + .map_err(|_e| SwapError::Other("failed flushing".to_string()))?; |
| 346 | + Ok(()) |
| 347 | + } |
| 348 | + Err(err) => Err(err), |
| 349 | + } |
| 350 | + } |
| 351 | + |
| 352 | + async fn bucket_rep(&self) -> u32 { |
| 353 | + self.bucket_rep |
| 354 | + } |
| 355 | + |
| 356 | + async fn key(&self) -> String { |
| 357 | + self.key.clone() |
289 | 358 | } |
290 | 359 | } |
0 commit comments