Copilot commented on code in PR #875:
URL: https://github.com/apache/iceberg-cpp/pull/875#discussion_r4401703432


##########
src/iceberg/file_io.h:
##########
@@ -154,6 +157,33 @@ class ICEBERG_EXPORT FileIO {
   virtual Result<std::string> ReadFile(const std::string& file_location,
                                        std::optional<size_t> length);
 
+  /// \brief Create an input handle backed by the metadata content cache when 
enabled.
+  ///
+  /// This is intended for immutable Iceberg manifest lists and manifests. 
Data files
+  /// and table metadata JSON should use NewInputFile or ReadFile directly.
+  Result<std::unique_ptr<InputFile>> NewCachedInputFile(
+      std::string file_location, std::optional<size_t> length = std::nullopt);

Review Comment:
   The PR description states the cache is for “metadata JSON, manifest lists, 
and manifests”, but this new API comment says “table metadata JSON should use 
NewInputFile or ReadFile directly.” Please align the documentation with the 
intended behavior: either update this comment to include metadata JSON as 
supported for caching, or adjust the PR description if metadata JSON caching is 
intentionally excluded.



##########
src/iceberg/file_io.cc:
##########
@@ -69,21 +221,91 @@ Result<std::string> FileIO::ReadFile(const std::string& 
file_location,
     ICEBERG_ASSIGN_OR_RAISE(input_file, NewInputFile(file_location));
     ICEBERG_ASSIGN_OR_RAISE(read_size, input_file->Size());
   }
-  if (read_size < 0) {
-    return Invalid("Invalid negative file size {} for {}", read_size, 
file_location);
+  return ReadInputFile(*input_file, read_size, file_location);
+}
+
+Result<std::unique_ptr<InputFile>> FileIO::NewCachedInputFile(
+    std::string file_location, std::optional<size_t> length) {
+  std::unique_ptr<InputFile> input_file;
+  if (length.has_value()) {
+    ICEBERG_ASSIGN_OR_RAISE(input_file, NewInputFile(file_location, *length));
+  } else {
+    ICEBERG_ASSIGN_OR_RAISE(input_file, NewInputFile(file_location));
   }
 
-  auto size = static_cast<size_t>(read_size);
-  std::string content(size, '\0');
-  ICEBERG_ASSIGN_OR_RAISE(auto stream, input_file->Open());
-  Status read_status = {};
-  if (size > 0) {
-    auto bytes = std::as_writable_bytes(std::span(content.data(), 
content.size()));
-    read_status = stream->ReadFully(/*position=*/0, bytes);
+  auto cache = GetMetadataCache();
+  if (cache == nullptr || !cache->options().enabled) {
+    return input_file;
   }
-  ICEBERG_RETURN_UNEXPECTED(
-      FinishWithCloseStatus(std::move(read_status), stream->Close()));
-  return content;
+
+  if (auto cached = cache->GetIfPresent(input_file->location())) {
+    return std::make_unique<CachedInputFile>(std::move(input_file), 
std::move(cache),
+                                             
static_cast<int64_t>(cached->size()));

Review Comment:
   `cached->size()` is a `size_t` that is narrowed to `int64_t` without bounds 
checking. If a cached entry size exceeds `int64_t` max, this conversion is 
implementation-defined and can wrap negative, which then propagates into 
`CachedInputFile` sizing and can lead to incorrect behavior (including 
huge/negative sizes). Consider guarding `cached->size()` against 
`std::numeric_limits<int64_t>::max()` and either (a) return an error, or (b) 
bypass caching and return the underlying `input_file` in that case.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to