MCPcopy Create free account
hub / github.com/AI45Lab/Code / list_recursive_under

Method list_recursive_under

core/src/workspace/s3.rs:707–771  ·  view source on GitHub ↗

Recursive (no-delimiter) listing of objects under `base`, with a hard cap on the number of objects considered. Returns `(entries, truncated)` where `entries` holds `(relative_key, size_bytes)` tuples relative to `base`'s S3 prefix, and `truncated` is `true` when the cap was reached before the listing completed. The listing-prefix marker itself is filtered out. Used as the foundation for both [`W

(
        &self,
        base: &WorkspacePath,
        max_objects: usize,
    )

Source from the content-addressed store, hash-verified

705 /// [`WorkspaceSearch::grep`]. Always paginates through continuation
706 /// tokens to avoid silently dropping objects past the first page.
707 async fn list_recursive_under(
708 &self,
709 base: &WorkspacePath,
710 max_objects: usize,
711 ) -> Result<(Vec<(String, u64)>, bool)> {
712 let prefix = self.list_prefix_for(base);
713 let mut entries: Vec<(String, u64)> = Vec::new();
714 let mut continuation: Option<String> = None;
715 let mut truncated = false;
716
717 loop {
718 let mut req = self
719 .client
720 .list_objects_v2()
721 .bucket(&self.bucket)
722 .prefix(&prefix);
723 if let Some(t) = continuation.as_ref() {
724 req = req.continuation_token(t);
725 }
726 let start = std::time::Instant::now();
727 let send_result = req.send().await;
728 emit_s3_call_event(
729 "s3.list_objects_v2_recursive",
730 &self.bucket,
731 &prefix,
732 send_result
733 .as_ref()
734 .ok()
735 .map_or(0, |r| r.contents().len() as u64),
736 send_result.is_ok(),
737 start.elapsed(),
738 );
739 let resp = send_result.map_err(|e| classify_list_error(&self.bucket, &prefix, e))?;
740
741 for obj in resp.contents() {
742 if entries.len() >= max_objects {
743 truncated = true;
744 return Ok((entries, truncated));
745 }
746 let Some(key) = obj.key() else { continue };
747 if key == prefix {
748 continue;
749 }
750 let Some(rel) = key.strip_prefix(&prefix) else {
751 continue;
752 };
753 if rel.is_empty() {
754 continue;
755 }
756 let size = obj.size().unwrap_or(0).max(0) as u64;
757 entries.push((rel.to_string(), size));
758 }
759
760 if resp.is_truncated().unwrap_or(false) {
761 continuation = resp.next_continuation_token().map(|s| s.to_string());
762 if continuation.is_none() {
763 break;
764 }

Callers 2

globMethod · 0.80
grepMethod · 0.80

Calls 9

nowFunction · 0.85
emit_s3_call_eventFunction · 0.85
classify_list_errorFunction · 0.85
list_prefix_forMethod · 0.80
prefixMethod · 0.80
bucketMethod · 0.80
sendMethod · 0.45
lenMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected