Repository: duckdb/duckdb
File: extension/parquet/parquet_file_metadata_cache.cpp (C++)

Code before:
namespace duckdb {

ParquetFileMetadataCache::ParquetFileMetadataCache(unique_ptr<duckdb_parquet::FileMetaData> file_metadata,
                                                   CachingFileHandle &handle,
                                                   unique_ptr<GeoParquetFileMetadata> geo_metadata,
                                                   unique_ptr<FileCryptoMetaData> crypto_metadata, idx_t footer_size)
    : metadata(std::move(file_metadata)), geo_metadata(std::move(geo_metadata)),
      crypto_metadata(std::move(crypto_metadata)), footer_size(footer_size), validate(handle.Validate()),
      last_modified(handle.GetLastModifiedTime()), version_tag(handle.GetVersionTag()) {
}

string ParquetFileMetadataCache::ObjectType() {
	return "parquet_metadata";
}

string ParquetFileMetadataCache::GetObjectType() {
	return ObjectType();
}

idx_t ParquetFileMetadataCache::GetRoughCacheMemory() const {
	// Base memory consumption
	idx_t memory = sizeof(*this);

	if (metadata) {
		// Base overhead
		memory += 1024;
		// Estimate ~1KB per row group + column stats
		memory += metadata->row_groups.size() * 1024;
		// Column schema information
		memory += metadata->schema.size() * 256;
	}
	if (geo_metadata) {
		memory += 512;
	}

	if (crypto_metadata) {
		memory += 256;
	}

	memory += footer_size;
	memory += version_tag.size();

	return memory;
}

bool ParquetFileMetadataCache::IsValid(CachingFileHandle &new_handle) const {
	return ExternalFileCache::IsValid(validate, version_tag, last_modified, new_handle.GetVersionTag(),
	                                  new_handle.GetLastModifiedTime());
}

ParquetCacheValidity ParquetFileMetadataCache::IsValid(const OpenFileInfo &info) const {

Review comment (suggestion):
This should be a more accurate estimate:
```C++
const auto num_cols = metadata->schema.size();
memory += sizeof(FileMetaData);
memory += num_cols * sizeof(SchemaElement);
memory += metadata->row_groups.size() * (sizeof(RowGroup) + num_cols * sizeof(ColumnChunk);
```

Code after:
#include "duckdb/storage/caching_file_system.hpp"

namespace duckdb {

ParquetFileMetadataCache::ParquetFileMetadataCache(unique_ptr<duckdb_parquet::FileMetaData> file_metadata,
                                                   CachingFileHandle &handle,
                                                   unique_ptr<GeoParquetFileMetadata> geo_metadata,
                                                   unique_ptr<FileCryptoMetaData> crypto_metadata, idx_t footer_size)
    : metadata(std::move(file_metadata)), geo_metadata(std::move(geo_metadata)),
      crypto_metadata(std::move(crypto_metadata)), footer_size(footer_size), validate(handle.Validate()),
      last_modified(handle.GetLastModifiedTime()), version_tag(handle.GetVersionTag()) {
}

string ParquetFileMetadataCache::ObjectType() {
	return "parquet_metadata";
}

string ParquetFileMetadataCache::GetObjectType() {
	return ObjectType();
}

optional_idx ParquetFileMetadataCache::GetEstimatedCacheMemory() const {
	// Base memory consumption
	idx_t memory = sizeof(*this);

	if (metadata) {
		const auto num_cols = metadata->schema.size();
		memory += sizeof(duckdb_parquet::FileMetaData);
		memory += num_cols * sizeof(duckdb_parquet::SchemaElement);
		memory += metadata->row_groups.size() * sizeof(duckdb_parquet::RowGroup) +
		          num_cols * sizeof(duckdb_parquet::ColumnChunk);
	}
	if (geo_metadata) {
		memory +=
		    sizeof(GeoParquetFileMetadata) + geo_metadata->GetColumnMeta().size() * sizeof(GeoParquetColumnMetadata);
	}
	if (crypto_metadata) {
		memory += sizeof(FileCryptoMetaData);
	}

	memory += footer_size;
	memory += version_tag.size();

	return memory;
}

bool ParquetFileMetadataCache::IsValid(CachingFileHandle &new_handle) const {
	return ExternalFileCache::IsValid(validate, version_tag, last_modified, new_handle.GetVersionTag(),
	                                  new_handle.GetLastModifiedTime());
}