|
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