This is an automated email from the ASF dual-hosted git repository.

tisonkun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 3fd4ead4a feat(services/swift): support list with start_after (#7810)
3fd4ead4a is described below

commit 3fd4ead4a378db1659275d1062723daaa56cfebd
Author: Ed McClanahan <[email protected]>
AuthorDate: Sun Jun 21 07:09:02 2026 -0700

    feat(services/swift): support list with start_after (#7810)
    
    OpenStack Swift's container listing supports a `marker` query parameter
    (an exclusive start-after), and the Swift lister already pages through it
    via `ctx.token`. Only the initial seed and the capability flag were
    missing, so `list_with_start_after` was unsupported and a user-supplied
    `start_after` was silently ignored.
    
    Seed the first page's marker from `OpList::start_after()` (made absolute
    like the S3 lister does), thread it through `SwiftLister`, and advertise
    `list_with_start_after` in the native capability. Subsequent pages keep
    using the continuation marker carried in `ctx.token`.
    
    Signed-off-by: Edward McClanahan <[email protected]>
---
 core/services/swift/src/backend.rs |  2 ++
 core/services/swift/src/lister.rs  | 22 +++++++++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/core/services/swift/src/backend.rs 
b/core/services/swift/src/backend.rs
index d4ca70b85..fdeb7ebae 100644
--- a/core/services/swift/src/backend.rs
+++ b/core/services/swift/src/backend.rs
@@ -205,6 +205,7 @@ impl Builder for SwiftBuilder {
 
                     list: true,
                     list_with_recursive: true,
+                    list_with_start_after: true,
 
                     presign: has_temp_url_key,
                     presign_stat: has_temp_url_key,
@@ -325,6 +326,7 @@ impl Service for SwiftBackend {
                 path.to_string(),
                 args.recursive(),
                 args.limit(),
+                args.start_after().map(String::from),
             );
 
             Ok(oio::PageLister::new(l))
diff --git a/core/services/swift/src/lister.rs 
b/core/services/swift/src/lister.rs
index e213c029f..01f7057c5 100644
--- a/core/services/swift/src/lister.rs
+++ b/core/services/swift/src/lister.rs
@@ -30,6 +30,7 @@ pub struct SwiftLister {
     path: String,
     delimiter: &'static str,
     limit: Option<usize>,
+    abs_start_after: Option<String>,
 }
 
 impl SwiftLister {
@@ -39,29 +40,36 @@ impl SwiftLister {
         path: String,
         recursive: bool,
         limit: Option<usize>,
+        start_after: Option<String>,
     ) -> Self {
         let delimiter = if recursive { "" } else { "/" };
+        // Swift listing names are absolute (root-prefixed) and the lister 
pages
+        // by `marker`, so the start-after must be made absolute as well.
+        let abs_start_after =
+            start_after.map(|start_after| build_abs_path(&core.root, 
&start_after));
         Self {
             core,
             ctx,
             path,
             delimiter,
             limit,
+            abs_start_after,
         }
     }
 }
 
 impl oio::PageList for SwiftLister {
     async fn next_page(&self, ctx: &mut oio::PageContext) -> Result<()> {
+        // `start_after` applies to the first page only; subsequent pages
+        // continue from the previous page's last entry carried in `ctx.token`.
+        let marker = if ctx.token.is_empty() {
+            self.abs_start_after.as_deref().unwrap_or("")
+        } else {
+            ctx.token.as_str()
+        };
         let response = self
             .core
-            .swift_list(
-                &self.ctx,
-                &self.path,
-                self.delimiter,
-                self.limit,
-                &ctx.token,
-            )
+            .swift_list(&self.ctx, &self.path, self.delimiter, self.limit, 
marker)
             .await?;
 
         let status_code = response.status();

Reply via email to