Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/paimon/src/common/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ impl CatalogOptions {
/// Comma-separated file types eligible for local caching.
pub const LOCAL_CACHE_WHITELIST: &'static str = "local-cache.whitelist";

/// Comma-separated file extensions excluded from local caching (empty by default).
pub const LOCAL_CACHE_EXCLUDE_EXTENSIONS: &'static str = "local-cache.exclude-extensions";

/// Maximum process-local cache size for parsed file-format metadata.
pub const FILE_FORMAT_METADATA_CACHE_MAX_SIZE: &'static str =
"file-format.metadata-cache.max-size";
Expand Down
40 changes: 39 additions & 1 deletion crates/paimon/src/io/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub(crate) struct LocalCache {
block_size: u64,
whitelist: HashSet<FileType>,
file_size_capacity: usize,
excluded_extensions: HashSet<String>,
// Bound queued and active background fills.
fill_slots: Arc<tokio::sync::Semaphore>,
// Generated lookup reads can outlive the executor. Keep temporary disk
Expand Down Expand Up @@ -84,6 +85,7 @@ impl LocalCache {
block_size,
whitelist: FileType::parse_whitelist(whitelist),
file_size_capacity: DEFAULT_FILE_SIZE_CAPACITY,
excluded_extensions: HashSet::new(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with_file_block_cache has no way to pass exclusions, so an external cache (also what the C binding uses) always caches BLOB files even when local-cache.exclude-extensions is set. Is that intended, or should it take the exclusions too?

fill_slots: Arc::new(tokio::sync::Semaphore::new(8)),
_temporary_directory: None,
})
Expand Down Expand Up @@ -134,6 +136,7 @@ impl LocalCache {
block_size: config.block_size,
whitelist: config.whitelist,
file_size_capacity,
excluded_extensions: config.excluded_extensions,
fill_slots: Arc::new(tokio::sync::Semaphore::new(8)),
_temporary_directory: None,
})
Expand All @@ -152,6 +155,7 @@ impl LocalCache {
let mut cache = Self::new_with_ratio(
LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: String::new(),
max_size,
Expand Down Expand Up @@ -188,10 +192,28 @@ impl LocalCache {
BlockKey::with_namespace(&self.namespace, path, self.block_size, block_index)
}

pub(super) fn is_cacheable(&self, path: &str) -> bool {
/// Extension exclusions must not disable invalidation of existing shared blocks.
pub(super) fn is_whitelisted(&self, path: &str) -> bool {
!FileType::is_mutable(path) && self.whitelist.contains(&FileType::classify(path))
}

pub(super) fn is_cacheable(&self, path: &str) -> bool {
if !self.is_whitelisted(path) {
return false;
}
if self.excluded_extensions.is_empty() {
return true;
}
let name = path.rsplit('/').next().unwrap_or(path);
!std::path::Path::new(name)
.extension()
.and_then(|extension| extension.to_str())
.is_some_and(|extension| {
self.excluded_extensions
.contains(&extension.to_ascii_lowercase())
})
}

async fn get_block(
&self,
key: &BlockKey,
Expand Down Expand Up @@ -450,6 +472,7 @@ pub(crate) async fn create_local_cache_with_namespace_async(
#[derive(Debug)]
pub(crate) struct LocalCacheConfig {
shared: bool,
excluded_extensions: HashSet<String>,
dir: Option<PathBuf>,
namespace: String,
max_size: Option<u64>,
Expand Down Expand Up @@ -533,6 +556,15 @@ impl LocalCacheConfig {
max_size,
block_size,
whitelist: FileType::parse_whitelist(whitelist),
excluded_extensions: options
.get(CatalogOptions::LOCAL_CACHE_EXCLUDE_EXTENSIONS)
.map(String::as_str)
.unwrap_or_default()
.split(',')
.map(|extension| extension.trim().trim_start_matches('.'))
.filter(|extension| !extension.is_empty())
.map(str::to_ascii_lowercase)
.collect(),
}))
}
}
Expand Down Expand Up @@ -712,6 +744,7 @@ mod tests {
let directory = tempfile::tempdir().unwrap();
let cache = LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -774,6 +807,7 @@ mod tests {
let directory = tempfile::tempdir().unwrap();
let config = || LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand All @@ -797,6 +831,7 @@ mod tests {
let directory = tempfile::tempdir().unwrap();
let config = || LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand All @@ -821,6 +856,7 @@ mod tests {
let directory = tempfile::tempdir().unwrap();
let cache = LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -851,6 +887,7 @@ mod tests {

LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand All @@ -872,6 +909,7 @@ mod tests {
let directory = tempfile::tempdir().unwrap();
let cache = LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: Some(8),
Expand Down
17 changes: 17 additions & 0 deletions crates/paimon/src/io/cache/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ mod tests {
Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".into(),
max_size: None,
Expand Down Expand Up @@ -472,6 +473,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".into(),
max_size: Some(16 * 1024 * 1024),
Expand Down Expand Up @@ -567,6 +569,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -603,6 +606,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".to_string(),
max_size: Some(16),
Expand Down Expand Up @@ -657,6 +661,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".into(),
max_size: Some(128 * 1024 * 1024),
Expand Down Expand Up @@ -729,6 +734,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".into(),
max_size: Some(4096),
Expand Down Expand Up @@ -785,6 +791,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".into(),
max_size: Some(4096),
Expand Down Expand Up @@ -841,6 +848,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".into(),
max_size: Some(4096),
Expand Down Expand Up @@ -882,6 +890,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -913,6 +922,7 @@ mod tests {
});
let config = || LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -961,6 +971,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -1011,6 +1022,7 @@ mod tests {
let cache_a = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand All @@ -1022,6 +1034,7 @@ mod tests {
let cache_b = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -1074,6 +1087,7 @@ mod tests {
let blocked_path = "s3://bucket/table/snapshot/snapshot-3";
let config = || LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -1221,6 +1235,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand Down Expand Up @@ -1256,6 +1271,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: Some(directory.path().to_path_buf()),
namespace: "test".to_string(),
max_size: None,
Expand All @@ -1278,6 +1294,7 @@ mod tests {
let cache = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: false,
excluded_extensions: Default::default(),
dir: None,
namespace: "test".to_string(),
max_size: None,
Expand Down
1 change: 1 addition & 0 deletions crates/paimon/src/io/cache/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@ mod tests {
let local = Arc::new(
LocalCache::new(LocalCacheConfig {
shared: true,
excluded_extensions: Default::default(),
dir: Some(root.clone()),
namespace: "catalog".into(),
max_size: Some(4096),
Expand Down
6 changes: 4 additions & 2 deletions crates/paimon/src/io/file_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ impl FileIO {
cache: self
.cache
.as_ref()
.filter(|cache| cache.is_cacheable(path))
.filter(|cache| cache.is_whitelisted(path))
.cloned(),
})
}
Expand Down Expand Up @@ -875,7 +875,9 @@ impl FileIO {
.invalidate_row_sidecar_size(cache_path);
}
if let (Some(cache), Some(cache_path)) = (
self.cache.as_ref().filter(|cache| cache.is_cacheable(path)),
self.cache
.as_ref()
.filter(|cache| cache.is_whitelisted(path)),
cache_path,
) {
cache.invalidate_path(&cache_path).await?;
Expand Down
Loading
Loading