Skip to content

Commit

Permalink
fix(services/memory): blocking_scan right range (#5062)
Browse files Browse the repository at this point in the history
* fix(serivces/memory) blocking scan right range

* cargo fmt

* cargo clippy
  • Loading branch information
meteorgan authored Aug 27, 2024
1 parent ed79a63 commit 41fe460
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
2 changes: 1 addition & 1 deletion core/src/raw/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub fn normalize_path(path: &str) -> String {
/// - Add leading `/` if not starts with: `abc/` => `/abc/`
/// - Add trailing `/` if not ends with: `/abc` => `/abc/`
///
/// Finally, we will got path like `/path/to/root/`.
/// Finally, we will get path like `/path/to/root/`.
pub fn normalize_root(v: &str) -> String {
let mut v = v
.split('/')
Expand Down
48 changes: 35 additions & 13 deletions core/src/services/memory/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,26 +125,27 @@ impl typed_kv::Adapter for Adapter {

fn blocking_scan(&self, path: &str) -> Result<Vec<String>> {
let inner = self.inner.lock().unwrap();
let keys: Vec<_> = if path.is_empty() {
inner.keys().cloned().collect()
} else {
let right_range = if let Some(path) = path.strip_suffix('/') {
format!("{}0", path)
} else {
format!("{}{}", path, std::char::MAX)
};
inner
.range(path.to_string()..right_range)
.map(|(k, _)| k.to_string())
.collect()
};

if path.is_empty() {
return Ok(inner.keys().cloned().collect());
}

let mut keys = Vec::new();
for (key, _) in inner.range(path.to_string()..) {
if !key.starts_with(path) {
break;
}
keys.push(key.to_string());
}
Ok(keys)
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::raw::adapters::typed_kv::{Adapter, Value};
use crate::services::memory::backend;

#[test]
fn test_accessor_metadata_name() {
Expand All @@ -154,4 +155,25 @@ mod tests {
let b2 = MemoryBuilder::default().build().unwrap();
assert_ne!(b1.info().name(), b2.info().name())
}

#[test]
fn test_blocking_scan() {
let adapter = backend::Adapter {
inner: Arc::new(Mutex::new(BTreeMap::default())),
};

adapter.blocking_set("aaa/bbb/", Value::new_dir()).unwrap();
adapter.blocking_set("aab/bbb/", Value::new_dir()).unwrap();
adapter.blocking_set("aab/ccc/", Value::new_dir()).unwrap();
adapter
.blocking_set(&format!("aab{}aaa/", std::char::MAX), Value::new_dir())
.unwrap();
adapter.blocking_set("aac/bbb/", Value::new_dir()).unwrap();

let data = adapter.blocking_scan("aab").unwrap();
assert_eq!(data.len(), 3);
for path in data {
assert!(path.starts_with("aab"));
}
}
}

0 comments on commit 41fe460

Please sign in to comment.