This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-rust.git
The following commit(s) were added to refs/heads/main by this push:
new da5cc19a9 feat(table): add Table::with_runtime that keeps the manifest
cache (#3406)
da5cc19a9 is described below
commit da5cc19a9f7c9e8ea14dc40d4a82974cd26def42
Author: NoahKusaba <[email protected]>
AuthorDate: Tue Oct 20 03:46:45 2026 +0000
feat(table): add Table::with_runtime that keeps the manifest cache (#3406)
* feat(table): add Table::with_runtime that keeps the manifest cache
A table gets its runtime only when it is built, and rebuilding it through
Table::builder() starts with an empty ObjectCache. An engine that caches a
Table and wants its scans to run on the runtime executing the query has no
way to switch runtimes without losing the cached manifests and manifest
lists.
* docs(table): tighten Table::with_runtime docs
Co-authored-by: Copilot App <[email protected]>
---------
Co-authored-by: Kevin Liu <[email protected]>
Co-authored-by: Copilot App <[email protected]>
---
crates/iceberg/public-api.txt | 1 +
crates/iceberg/src/table.rs | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/crates/iceberg/public-api.txt b/crates/iceberg/public-api.txt
index b86e48c77..9d65474ad 100644
--- a/crates/iceberg/public-api.txt
+++ b/crates/iceberg/public-api.txt
@@ -3404,6 +3404,7 @@ pub fn iceberg::table::Table::metadata_ref(&self) ->
iceberg::spec::TableMetadat
pub fn iceberg::table::Table::reader_builder(&self) ->
iceberg::arrow::ArrowReaderBuilder
pub fn iceberg::table::Table::readonly(&self) -> bool
pub fn iceberg::table::Table::scan(&self) ->
iceberg::scan::TableScanBuilder<'_>
+pub fn iceberg::table::Table::with_runtime(self, runtime: iceberg::Runtime) ->
Self
impl core::clone::Clone for iceberg::table::Table
pub fn iceberg::table::Table::clone(&self) -> iceberg::table::Table
impl core::fmt::Debug for iceberg::table::Table
diff --git a/crates/iceberg/src/table.rs b/crates/iceberg/src/table.rs
index 78c2dff05..f33c246eb 100644
--- a/crates/iceberg/src/table.rs
+++ b/crates/iceberg/src/table.rs
@@ -219,6 +219,15 @@ impl Table {
self
}
+ /// Returns this table bound to `runtime`, sharing its manifest cache.
+ ///
+ /// Tasks such as scan planning and reads are spawned on `runtime`. A
table rebuilt
+ /// through [`Table::builder`] starts with an empty cache.
+ pub fn with_runtime(mut self, runtime: Runtime) -> Self {
+ self.runtime = runtime;
+ self
+ }
+
/// Returns a TableBuilder to build a table
pub fn builder() -> TableBuilder {
TableBuilder::new()
@@ -497,6 +506,31 @@ mod tests {
assert_eq!(table.identifier.name(), "table");
}
+ #[tokio::test]
+ async fn test_table_with_runtime_moves_work_and_keeps_object_cache() {
+ let old = tokio::runtime::Builder::new_current_thread()
+ .build()
+ .unwrap();
+ let table = Table::builder()
+ .metadata(load_test_metadata("TableMetadataV2Valid.json"))
+ .identifier(TableIdent::from_strs(["ns", "table"]).unwrap())
+ .file_io(FileIO::new_with_memory())
+ .runtime(Runtime::new(&old))
+ .build()
+ .unwrap();
+ // With the old runtime shut down, the spawn below succeeds only if
+ // `rebound` uses the new one.
+ old.shutdown_background();
+
+ let rebound =
table.clone().with_runtime(Runtime::try_current().unwrap());
+
+ assert!(Arc::ptr_eq(&table.object_cache(), &rebound.object_cache()));
+ assert_eq!(
+ rebound.runtime().io().spawn(async { 42 }).await.unwrap(),
+ 42
+ );
+ }
+
fn make_kms() -> Arc<dyn KeyManagementClient> {
let kms = MemoryKeyManagementClient::new();
kms.add_master_key("master-1").unwrap();