From fa0032da386b37555cba520b0c94980c36dfe8f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BC=8A=E6=AC=A7?= Date: Wed, 28 Aug 2024 17:59:38 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20incorrect=20segment=20do?= =?UTF-8?q?wnload=20range.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/database_driver_native/src/bucket.rs | 56 +++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/packages/database_driver_native/src/bucket.rs b/packages/database_driver_native/src/bucket.rs index 7153ddc..d67c16d 100644 --- a/packages/database_driver_native/src/bucket.rs +++ b/packages/database_driver_native/src/bucket.rs @@ -3,6 +3,8 @@ use bytes::Bytes; use chrono::{DateTime, Utc}; use std::{ collections::HashMap, + fs::File, + io::{Read, Seek, SeekFrom}, ops::RangeInclusive, os::windows::fs::MetadataExt, path::PathBuf, @@ -16,7 +18,7 @@ use tairitsu_database_types::providers::bucket::*; #[derive(Clone)] pub struct ProxyBucket { path: PathBuf, - cache: Cache, + cache: Cache<(String, (usize, usize)), Bytes>, multipart_cache: Arc>>>, } @@ -34,7 +36,6 @@ impl BucketStore for ProxyBucket { value.as_ref(), ) .map_err(|err| anyhow!("Failed to write to file '{}': {}", key, err))?; - self.cache.insert(key, value).await; Ok(()) } @@ -46,26 +47,42 @@ impl BucketStore for ProxyBucket { ) -> Result> { check_key(&key)?; - let data = if let Some(data) = self.cache.get(&key).await { - data + if let Some(range) = range { + let (start, end) = (*range.start(), *range.end()); + println!("start: {}, end: {}", start, end); + + if let Some(data) = self.cache.get(&(key.clone(), (start, end))).await { + return Ok(Some(data)); + } else { + let mut file = File::open({ + let mut path = self.path.to_path_buf(); + path.push(key.clone()); + path + }) + .map_err(|err| anyhow!("Failed to open file '{}': {}", key, err))?; + file.seek(SeekFrom::Start(start as u64)) + .map_err(|err| anyhow!("Failed to seek in file '{}': {}", key, err))?; + + let mut data = vec![0; (end - start) as usize]; + file.read_exact(&mut data) + .map_err(|err| anyhow!("Failed to read from file '{}': {}", key, err))?; + + let data = Bytes::from(data); + self.cache + .insert((key.clone(), (start, end)), data.clone()) + .await; + return Ok(Some(data)); + } } else { let data = std::fs::read({ let mut path = self.path.to_path_buf(); path.push(key.clone()); path }) - .map_err(|err| anyhow!("Failed to read from file '{}': {}", key, err))?; - let data = Bytes::from(data); - self.cache.insert(key.clone(), data.clone()).await; + .map_err(|err| anyhow!("Failed to read file '{}': {}", key, err))?; - data - }; - - Ok(Some(if let Some(range) = range { - data.slice(range.clone()) - } else { - data.clone() - })) + Ok(Some(Bytes::from(data))) + } } async fn get_metadata(&self, key: String) -> Result { @@ -96,7 +113,14 @@ impl BucketStore for ProxyBucket { async fn delete(&self, key: String) -> Result<()> { check_key(&key)?; - self.cache.remove(&key).await; + for (item_key_raw, _) in self.cache.iter() { + let item_key_raw = (*item_key_raw).clone(); + let item_key = item_key_raw.0.clone(); + + if item_key == key { + self.cache.remove(&item_key_raw).await; + } + } if let Err(err) = std::fs::remove_file({ let mut path = self.path.to_path_buf();