iceberg-cpp
Loading...
Searching...
No Matches
manifest_entry.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
23
24#include <cstdint>
25#include <map>
26#include <memory>
27#include <optional>
28#include <string>
29#include <vector>
30
31#include "iceberg/file_format.h"
33#include "iceberg/result.h"
36#include "iceberg/type.h"
37
38namespace iceberg {
39
40enum class ManifestStatus {
41 kExisting = 0,
42 kAdded = 1,
43 kDeleted = 2,
44};
45
48 int32_t status) noexcept {
49 switch (status) {
50 case 0:
51 return ManifestStatus::kExisting;
52 case 1:
53 return ManifestStatus::kAdded;
54 case 2:
55 return ManifestStatus::kDeleted;
56 default:
57 return InvalidArgument("Invalid manifest status: {}", status);
58 }
59}
60
62struct ICEBERG_EXPORT DataFile {
64 enum class Content {
65 kData = 0,
66 kPositionDeletes = 1,
67 kEqualityDeletes = 2,
68 };
69
73 Content content = Content::kData;
76 std::string file_path;
79 FileFormatType file_format = FileFormatType::kParquet;
86 int64_t record_count = 0;
89 int64_t file_size_in_bytes = 0;
96 std::map<int32_t, int64_t> column_sizes;
101 std::map<int32_t, int64_t> value_counts;
106 std::map<int32_t, int64_t> null_value_counts;
111 std::map<int32_t, int64_t> nan_value_counts;
118 std::map<int32_t, std::vector<uint8_t>> lower_bounds;
125 std::map<int32_t, std::vector<uint8_t>> upper_bounds;
128 std::vector<uint8_t> key_metadata;
133 std::vector<int64_t> split_offsets;
139 std::vector<int32_t> equality_ids;
148 std::optional<int32_t> sort_order_id;
155 std::optional<int64_t> first_row_id;
163 std::optional<std::string> referenced_data_file;
171 std::optional<int64_t> content_offset;
175 std::optional<int64_t> content_size_in_bytes;
176
178
182 std::optional<int32_t> partition_spec_id;
183
187 std::optional<int64_t> data_sequence_number;
188
189 static constexpr int32_t kContentFieldId = 134;
190 inline static const SchemaField kContent = SchemaField::MakeOptional(
191 kContentFieldId, "content", int32(),
192 "Contents of the file: 0=data, 1=position deletes, 2=equality deletes");
193
194 static constexpr int32_t kFilePathFieldId = 100;
195 inline static const SchemaField kFilePath = SchemaField::MakeRequired(
196 kFilePathFieldId, "file_path", string(), "Location URI with FS scheme");
197
198 static constexpr int32_t kFileFormatFieldId = 101;
199 inline static const SchemaField kFileFormat =
200 SchemaField::MakeRequired(kFileFormatFieldId, "file_format", string(),
201 "File format name: avro, orc, or parquet");
202
203 static constexpr int32_t kSpecIdFieldId = 141;
204 inline static const SchemaField kSpecId =
205 SchemaField::MakeOptional(kSpecIdFieldId, "spec_id", int32(), "Partition spec ID");
206
207 static constexpr int32_t kPartitionFieldId = 102;
208 inline static const std::string kPartitionField = "partition";
209 inline static const std::string kPartitionDoc =
210 "Partition data tuple, schema based on the partition spec";
211
212 static constexpr int32_t kRecordCountFieldId = 103;
213 inline static const SchemaField kRecordCount = SchemaField::MakeRequired(
214 kRecordCountFieldId, "record_count", int64(), "Number of records in the file");
215
216 static constexpr int32_t kFileSizeFieldId = 104;
217 inline static const SchemaField kFileSize = SchemaField::MakeRequired(
218 kFileSizeFieldId, "file_size_in_bytes", int64(), "Total file size in bytes");
219
220 static constexpr int32_t kColumnSizesFieldId = 108;
221 inline static const SchemaField kColumnSizes = SchemaField::MakeOptional(
222 kColumnSizesFieldId, "column_sizes",
223 map(SchemaField::MakeRequired(117, std::string(MapType::kKeyName), int32()),
224 SchemaField::MakeRequired(118, std::string(MapType::kValueName), int64())),
225 "Map of column id to total size on disk");
226
227 static constexpr int32_t kValueCountsFieldId = 109;
228 inline static const SchemaField kValueCounts = SchemaField::MakeOptional(
229 kValueCountsFieldId, "value_counts",
230 map(SchemaField::MakeRequired(119, std::string(MapType::kKeyName), int32()),
231 SchemaField::MakeRequired(120, std::string(MapType::kValueName), int64())),
232 "Map of column id to total count, including null and NaN");
233
234 static constexpr int32_t kNullValueCountsFieldId = 110;
235 inline static const SchemaField kNullValueCounts = SchemaField::MakeOptional(
236 kNullValueCountsFieldId, "null_value_counts",
237 map(SchemaField::MakeRequired(121, std::string(MapType::kKeyName), int32()),
238 SchemaField::MakeRequired(122, std::string(MapType::kValueName), int64())),
239 "Map of column id to null value count");
240
241 static constexpr int32_t kNanValueCountsFieldId = 137;
242 inline static const SchemaField kNanValueCounts = SchemaField::MakeOptional(
243 kNanValueCountsFieldId, "nan_value_counts",
244 map(SchemaField::MakeRequired(138, std::string(MapType::kKeyName), int32()),
245 SchemaField::MakeRequired(139, std::string(MapType::kValueName), int64())),
246 "Map of column id to number of NaN values in the column");
247
248 static constexpr int32_t kLowerBoundsFieldId = 125;
249 inline static const SchemaField kLowerBounds = SchemaField::MakeOptional(
250 kLowerBoundsFieldId, "lower_bounds",
251 map(SchemaField::MakeRequired(126, std::string(MapType::kKeyName), int32()),
252 SchemaField::MakeRequired(127, std::string(MapType::kValueName), binary())),
253 "Map of column id to lower bound");
254
255 static constexpr int32_t kUpperBoundsFieldId = 128;
256 inline static const SchemaField kUpperBounds = SchemaField::MakeOptional(
257 kUpperBoundsFieldId, "upper_bounds",
258 map(SchemaField::MakeRequired(129, std::string(MapType::kKeyName), int32()),
259 SchemaField::MakeRequired(130, std::string(MapType::kValueName), binary())),
260 "Map of column id to upper bound");
261
262 static constexpr int32_t kKeyMetadataFieldId = 131;
263 inline static const SchemaField kKeyMetadata = SchemaField::MakeOptional(
264 kKeyMetadataFieldId, "key_metadata", binary(), "Encryption key metadata blob");
265
266 static constexpr int32_t kSplitOffsetsFieldId = 132;
267 inline static const SchemaField kSplitOffsets = SchemaField::MakeOptional(
268 kSplitOffsetsFieldId, "split_offsets",
269 list(SchemaField::MakeRequired(133, std::string(ListType::kElementName), int64())),
270 "Splittable offsets");
271
272 static constexpr int32_t kEqualityIdsFieldId = 135;
273 inline static const SchemaField kEqualityIds = SchemaField::MakeOptional(
274 kEqualityIdsFieldId, "equality_ids",
275 list(SchemaField::MakeRequired(136, std::string(ListType::kElementName), int32())),
276 "Equality comparison field IDs");
277
278 static constexpr int32_t kSortOrderIdFieldId = 140;
279 inline static const SchemaField kSortOrderId = SchemaField::MakeOptional(
280 kSortOrderIdFieldId, "sort_order_id", int32(), "Sort order ID");
281
282 static constexpr int32_t kFirstRowIdFieldId = 142;
283 inline static const SchemaField kFirstRowId =
284 SchemaField::MakeOptional(kFirstRowIdFieldId, "first_row_id", int64(),
285 "Starting row ID to assign to new rows");
286
287 static constexpr int32_t kReferencedDataFileFieldId = 143;
288 inline static const SchemaField kReferencedDataFile = SchemaField::MakeOptional(
289 kReferencedDataFileFieldId, "referenced_data_file", string(),
290 "Fully qualified location (URI with FS scheme) of a data file that all deletes "
291 "reference");
292
293 static constexpr int32_t kContentOffsetFieldId = 144;
294 inline static const SchemaField kContentOffset =
295 SchemaField::MakeOptional(kContentOffsetFieldId, "content_offset", int64(),
296 "The offset in the file where the content starts");
297
298 static constexpr int32_t kContentSizeFieldId = 145;
299 inline static const SchemaField kContentSize =
300 SchemaField::MakeOptional(kContentSizeFieldId, "content_size_in_bytes", int64(),
301 "The length of referenced content stored in the file");
302
303 bool operator==(const DataFile& other) const = default;
304
306 static std::shared_ptr<StructType> Type(std::shared_ptr<StructType> partition_type);
307
309 bool IsDeletionVector() const {
310 return content == Content::kPositionDeletes && file_format == FileFormatType::kPuffin;
311 }
312};
313
316
318struct ICEBERG_EXPORT ManifestEntry {
322 ManifestStatus status = ManifestStatus::kAdded;
326 std::optional<int64_t> snapshot_id;
339 std::optional<int64_t> sequence_number;
352 std::optional<int64_t> file_sequence_number;
355 std::shared_ptr<DataFile> data_file;
356
357 static constexpr int32_t kStatusFieldId = 0;
358 inline static const SchemaField kStatus =
359 SchemaField::MakeRequired(kStatusFieldId, "status", int32());
360
361 static constexpr int32_t kSnapshotIdFieldId = 1;
362 inline static const SchemaField kSnapshotId =
363 SchemaField::MakeOptional(kSnapshotIdFieldId, "snapshot_id", int64());
364
365 static constexpr int32_t kDataFileFieldId = 2;
366 inline static const std::string kDataFileField = "data_file";
367
368 static constexpr int32_t kSequenceNumberFieldId = 3;
369 inline static const SchemaField kSequenceNumber =
370 SchemaField::MakeOptional(kSequenceNumberFieldId, "sequence_number", int64());
371
372 static constexpr int32_t kFileSequenceNumberFieldId = 4;
373 inline static const SchemaField kFileSequenceNumber = SchemaField::MakeOptional(
374 kFileSequenceNumberFieldId, "file_sequence_number", int64());
375
377 constexpr bool IsAlive() const {
378 return status == ManifestStatus::kAdded || status == ManifestStatus::kExisting;
379 }
380
381 ManifestEntry AsAdded() const {
382 ManifestEntry copy = *this;
383 copy.status = ManifestStatus::kAdded;
384 if (copy.data_file != nullptr && copy.data_file->first_row_id.has_value()) {
385 copy.data_file = std::make_unique<DataFile>(*copy.data_file);
386 copy.data_file->first_row_id = std::nullopt;
387 }
388 return copy;
389 }
390
391 ManifestEntry AsExisting() const {
392 ManifestEntry copy = *this;
393 copy.status = ManifestStatus::kExisting;
394 return copy;
395 }
396
397 ManifestEntry AsDeleted() const {
398 ManifestEntry copy = *this;
399 copy.status = ManifestStatus::kDeleted;
400 return copy;
401 }
402
403 bool operator==(const ManifestEntry& other) const;
404
405 static std::shared_ptr<StructType> TypeFromPartitionType(
406 std::shared_ptr<StructType> partition_type);
407 static std::shared_ptr<StructType> TypeFromDataFileType(
408 std::shared_ptr<StructType> datafile_type);
409};
410
412ICEBERG_EXPORT constexpr std::string_view ToString(DataFile::Content type) noexcept {
413 switch (type) {
414 case DataFile::Content::kData:
415 return "data";
416 case DataFile::Content::kPositionDeletes:
417 return "position_deletes";
418 case DataFile::Content::kEqualityDeletes:
419 return "equality_deletes";
420 }
421 std::unreachable();
422}
423
426 int32_t content) noexcept {
427 switch (content) {
428 case 0:
429 return DataFile::Content::kData;
430 case 1:
431 return DataFile::Content::kPositionDeletes;
432 case 2:
433 return DataFile::Content::kEqualityDeletes;
434 default:
435 return InvalidArgument("Invalid data file content: {}", content);
436 }
437}
438
439} // namespace iceberg
StructLike wrapper for a vector of literals that represent partition values.
Definition partition_values.h:36
A type combined with a name.
Definition schema_field.h:39
ICEBERG_EXPORT const std::shared_ptr< BinaryType > & binary()
Return a BinaryType instance.
ICEBERG_EXPORT std::shared_ptr< MapType > map(SchemaField key, SchemaField value)
Create a MapType with the given key and value fields.
ICEBERG_EXPORT std::shared_ptr< ListType > list(SchemaField element)
Create a ListType with the given element field.
ICEBERG_EXPORT const std::shared_ptr< IntType > & int32()
Return an IntType instance.
ICEBERG_EXPORT const std::shared_ptr< LongType > & int64()
Return a LongType instance.
Define symbol visibility macros for core Iceberg APIs.
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:33
@ kData
The manifest content is data.
ICEBERG_EXPORT std::string_view ToString(Expression::Operation op)
Returns a string representation of an expression operation.
std::expected< T, E > Result
Result alias.
Definition result.h:88
ICEBERG_EXPORT constexpr Result< ManifestStatus > ManifestStatusFromInt(int32_t status) noexcept
Get the relative manifest status type from int.
Definition manifest_entry.h:47
ICEBERG_EXPORT constexpr Result< DataFile::Content > DataFileContentFromInt(int32_t content) noexcept
Get the relative data file content type from int.
Definition manifest_entry.h:425
Define Result, Status, and error helpers.
DataFile carries data file path, partition tuple, metrics, ...
Definition manifest_entry.h:62
std::optional< int64_t > content_offset
Definition manifest_entry.h:171
std::map< int32_t, std::vector< uint8_t > > lower_bounds
Definition manifest_entry.h:118
std::optional< int64_t > content_size_in_bytes
Definition manifest_entry.h:175
std::optional< int64_t > first_row_id
Definition manifest_entry.h:155
PartitionValues partition
Definition manifest_entry.h:83
std::vector< int32_t > equality_ids
Definition manifest_entry.h:139
Content
Content of a data file.
Definition manifest_entry.h:64
std::map< int32_t, int64_t > column_sizes
Definition manifest_entry.h:96
static std::shared_ptr< StructType > Type(std::shared_ptr< StructType > partition_type)
Get the schema of the data file with the given partition type.
std::map< int32_t, int64_t > null_value_counts
Definition manifest_entry.h:106
std::optional< int32_t > partition_spec_id
Partition spec id for this data file.
Definition manifest_entry.h:182
std::optional< std::string > referenced_data_file
Definition manifest_entry.h:163
std::vector< uint8_t > key_metadata
Definition manifest_entry.h:128
std::map< int32_t, std::vector< uint8_t > > upper_bounds
Definition manifest_entry.h:125
std::map< int32_t, int64_t > nan_value_counts
Definition manifest_entry.h:111
std::vector< int64_t > split_offsets
Definition manifest_entry.h:133
std::optional< int32_t > sort_order_id
Definition manifest_entry.h:148
bool IsDeletionVector() const
Check if this data file is a deletion vector.
Definition manifest_entry.h:309
std::optional< int64_t > data_sequence_number
Data sequence number for this data file.
Definition manifest_entry.h:187
std::string file_path
Definition manifest_entry.h:76
std::map< int32_t, int64_t > value_counts
Definition manifest_entry.h:101
A manifest is an immutable Avro file that lists data files or delete files, along with each file's pa...
Definition manifest_entry.h:318
std::optional< int64_t > snapshot_id
Definition manifest_entry.h:326
std::optional< int64_t > file_sequence_number
Definition manifest_entry.h:352
std::optional< int64_t > sequence_number
Definition manifest_entry.h:339
constexpr bool IsAlive() const
Check if this manifest entry is deleted.
Definition manifest_entry.h:377
std::shared_ptr< DataFile > data_file
Definition manifest_entry.h:355
ManifestStatus status
Definition manifest_entry.h:322