mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-21 03:46:37 +00:00
fix: listobjects v2 pagination (#1607)
This commit is contained in:
@@ -2784,8 +2784,10 @@ mod test {
|
||||
let disk_info = disk.disk_info(&disk_info_opts).await.unwrap();
|
||||
|
||||
// Basic checks on disk info
|
||||
assert!(!disk_info.fs_type.is_empty());
|
||||
assert!(disk_info.total > 0);
|
||||
assert!(disk_info.free <= disk_info.total);
|
||||
assert!(!disk_info.mount_path.is_empty());
|
||||
assert!(!disk_info.endpoint.is_empty());
|
||||
|
||||
// Clean up the test directory
|
||||
let _ = fs::remove_dir_all(&test_dir).await;
|
||||
|
||||
@@ -256,19 +256,21 @@ impl ECStore {
|
||||
max_keys: i32,
|
||||
incl_deleted: bool,
|
||||
) -> Result<ListObjectsInfo> {
|
||||
let effective_max_keys = if max_keys <= 0 { 0 } else { max_keys_plus_one(max_keys, true) };
|
||||
let opts = ListPathOptions {
|
||||
bucket: bucket.to_owned(),
|
||||
prefix: prefix.to_owned(),
|
||||
separator: delimiter.clone(),
|
||||
limit: max_keys_plus_one(max_keys, marker.is_some()),
|
||||
// Always request max_keys + 1 to detect if there are more results
|
||||
limit: effective_max_keys,
|
||||
marker,
|
||||
incl_deleted,
|
||||
ask_disks: "strict".to_owned(), //TODO: from config
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// use get
|
||||
if !opts.prefix.is_empty() && opts.limit == 1 && opts.marker.is_none() {
|
||||
// Optimization: use get for single object lookup with exact prefix
|
||||
if !opts.prefix.is_empty() && max_keys == 1 && opts.marker.is_none() {
|
||||
match self
|
||||
.get_object_info(
|
||||
&opts.bucket,
|
||||
@@ -322,14 +324,16 @@ impl ECStore {
|
||||
)
|
||||
.await;
|
||||
|
||||
let is_truncated = {
|
||||
if max_keys > 0 && get_objects.len() > max_keys as usize {
|
||||
get_objects.truncate(max_keys as usize);
|
||||
true
|
||||
} else {
|
||||
list_result.err.is_none() && !get_objects.is_empty()
|
||||
}
|
||||
};
|
||||
// Determine if there are more results: we requested max_keys + 1, so if we got more
|
||||
// than max_keys, there are more results available
|
||||
let mut is_truncated = false;
|
||||
if max_keys <= 0 {
|
||||
get_objects.clear();
|
||||
} else if get_objects.len() > max_keys as usize {
|
||||
is_truncated = true;
|
||||
// Truncate to max_keys if we have more results
|
||||
get_objects.truncate(max_keys as usize);
|
||||
}
|
||||
|
||||
let next_marker = {
|
||||
if is_truncated {
|
||||
@@ -397,12 +401,13 @@ impl ECStore {
|
||||
None
|
||||
};
|
||||
|
||||
// if marker set, limit +1
|
||||
let effective_max_keys = if max_keys <= 0 { 0 } else { max_keys_plus_one(max_keys, true) };
|
||||
// Always request max_keys + 1 to detect if there are more results
|
||||
let opts = ListPathOptions {
|
||||
bucket: bucket.to_owned(),
|
||||
prefix: prefix.to_owned(),
|
||||
separator: delimiter.clone(),
|
||||
limit: max_keys_plus_one(max_keys, marker.is_some()),
|
||||
limit: effective_max_keys,
|
||||
marker,
|
||||
incl_deleted: true,
|
||||
ask_disks: "strict".to_owned(),
|
||||
@@ -428,13 +433,6 @@ impl ECStore {
|
||||
result.forward_past(opts.marker);
|
||||
}
|
||||
|
||||
// Check if list_path returned entries equal to limit, which indicates more objects exist
|
||||
// This is more accurate than checking get_objects.len() because get_objects may be filtered
|
||||
// (e.g., directories filtered out), so its length may be less than the actual entries count
|
||||
// We need to check this before calling from_meta_cache_entries_sorted_versions which consumes entries
|
||||
let entries_count = list_result.entries.as_ref().map(|e| e.entries().len()).unwrap_or(0);
|
||||
let limit = opts.limit;
|
||||
|
||||
let mut get_objects = ObjectInfo::from_meta_cache_entries_sorted_versions(
|
||||
&list_result.entries.unwrap_or_default(),
|
||||
bucket,
|
||||
@@ -444,18 +442,16 @@ impl ECStore {
|
||||
)
|
||||
.await;
|
||||
|
||||
let is_truncated = {
|
||||
if max_keys > 0 && get_objects.len() > max_keys as usize {
|
||||
get_objects.truncate(max_keys as usize);
|
||||
true
|
||||
} else if entries_count >= limit as usize {
|
||||
// If entries count equals limit, there are more objects
|
||||
true
|
||||
} else {
|
||||
// Otherwise, check if there are any objects and no error
|
||||
list_result.err.is_none() && !get_objects.is_empty()
|
||||
}
|
||||
};
|
||||
// Determine if there are more results: we requested max_keys + 1, so if we got more
|
||||
// than max_keys, there are more results available
|
||||
let mut is_truncated = false;
|
||||
if max_keys <= 0 {
|
||||
get_objects.clear();
|
||||
} else if get_objects.len() > max_keys as usize {
|
||||
is_truncated = true;
|
||||
// Truncate to max_keys if we have more results
|
||||
get_objects.truncate(max_keys as usize);
|
||||
}
|
||||
|
||||
let (next_marker, next_version_idmarker) = {
|
||||
if is_truncated {
|
||||
|
||||
Reference in New Issue
Block a user