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
32#include "iceberg/file_format.h"
34#include "iceberg/result.h"
37#include "iceberg/type.h"
38
39namespace iceberg {
40
41enum class ManifestStatus {
42 kExisting = 0,
43 kAdded = 1,
44 kDeleted = 2,
45};
46
49 int32_t status) noexcept {
50 switch (status) {
51 case 0:
52 return ManifestStatus::kExisting;
53 case 1:
54 return ManifestStatus::kAdded;
55 case 2:
56 return ManifestStatus::kDeleted;
57 default:
58 return InvalidArgument("Invalid manifest status: {}", status);
59 }
60}
61
63struct ICEBERG_EXPORT DataFile {
65 enum class Content {
66 kData = 0,
67 kPositionDeletes = 1,
68 kEqualityDeletes = 2,
69 };
70
74 Content content = Content::kData;
77 std::string file_path;
80 FileFormatType file_format = FileFormatType::kParquet;
87 int64_t record_count = 0;
90 int64_t file_size_in_bytes = 0;
97 std::map<int32_t, int64_t> column_sizes;
102 std::map<int32_t, int64_t> value_counts;
107 std::map<int32_t, int64_t> null_value_counts;
112 std::map<int32_t, int64_t> nan_value_counts;
119 std::map<int32_t, std::vector<uint8_t>> lower_bounds;
126 std::map<int32_t, std::vector<uint8_t>> upper_bounds;
129 std::vector<uint8_t> key_metadata;
134 std::vector<int64_t> split_offsets;
140 std::vector<int32_t> equality_ids;
149 std::optional<int32_t> sort_order_id;
156 std::optional<int64_t> first_row_id;
164 std::optional<std::string> referenced_data_file;
172 std::optional<int64_t> content_offset;
176 std::optional<int64_t> content_size_in_bytes;
177
179
183 std::optional<int32_t> partition_spec_id;
184
188 std::optional<int64_t> data_sequence_number;
189
190 static constexpr int32_t kContentFieldId = 134;
191 inline static const SchemaField kContent = SchemaField::MakeOptional(
192 kContentFieldId, "content", int32(),
193 "Contents of the file: 0=data, 1=position deletes, 2=equality deletes");
194
195 static constexpr int32_t kFilePathFieldId = 100;
196 inline static const SchemaField kFilePath = SchemaField::MakeRequired(
197 kFilePathFieldId, "file_path", string(), "Location URI with FS scheme");
198
199 static constexpr int32_t kFileFormatFieldId = 101;
200 inline static const SchemaField kFileFormat =
201 SchemaField::MakeRequired(kFileFormatFieldId, "file_format", string(),
202 "File format name: avro, orc, or parquet");
203
204 static constexpr int32_t kSpecIdFieldId = 141;
205 inline static const SchemaField kSpecId =
206 SchemaField::MakeOptional(kSpecIdFieldId, "spec_id", int32(), "Partition spec ID");
207
208 static constexpr int32_t kPartitionFieldId = 102;
209 inline static const std::string kPartitionField = "partition";
210 inline static const std::string kPartitionDoc =
211 "Partition data tuple, schema based on the partition spec";
212
213 static constexpr int32_t kRecordCountFieldId = 103;
214 inline static const SchemaField kRecordCount = SchemaField::MakeRequired(
215 kRecordCountFieldId, "record_count", int64(), "Number of records in the file");
216
217 static constexpr int32_t kFileSizeFieldId = 104;
218 inline static const SchemaField kFileSize = SchemaField::MakeRequired(
219 kFileSizeFieldId, "file_size_in_bytes", int64(), "Total file size in bytes");
220
221 static constexpr int32_t kColumnSizesFieldId = 108;
222 inline static const SchemaField kColumnSizes = SchemaField::MakeOptional(
223 kColumnSizesFieldId, "column_sizes",
224 map(SchemaField::MakeRequired(117, std::string(MapType::kKeyName), int32()),
225 SchemaField::MakeRequired(118, std::string(MapType::kValueName), int64())),
226 "Map of column id to total size on disk");
227
228 static constexpr int32_t kValueCountsFieldId = 109;
229 inline static const SchemaField kValueCounts = SchemaField::MakeOptional(
230 kValueCountsFieldId, "value_counts",
231 map(SchemaField::MakeRequired(119, std::string(MapType::kKeyName), int32()),
232 SchemaField::MakeRequired(120, std::string(MapType::kValueName), int64())),
233 "Map of column id to total count, including null and NaN");
234
235 static constexpr int32_t kNullValueCountsFieldId = 110;
236 inline static const SchemaField kNullValueCounts = SchemaField::MakeOptional(
237 kNullValueCountsFieldId, "null_value_counts",
238 map(SchemaField::MakeRequired(121, std::string(MapType::kKeyName), int32()),
239 SchemaField::MakeRequired(122, std::string(MapType::kValueName), int64())),
240 "Map of column id to null value count");
241
242 static constexpr int32_t kNanValueCountsFieldId = 137;
243 inline static const SchemaField kNanValueCounts = SchemaField::MakeOptional(
244 kNanValueCountsFieldId, "nan_value_counts",
245 map(SchemaField::MakeRequired(138, std::string(MapType::kKeyName), int32()),
246 SchemaField::MakeRequired(139, std::string(MapType::kValueName), int64())),
247 "Map of column id to number of NaN values in the column");
248
249 static constexpr int32_t kLowerBoundsFieldId = 125;
250 inline static const SchemaField kLowerBounds = SchemaField::MakeOptional(
251 kLowerBoundsFieldId, "lower_bounds",
252 map(SchemaField::MakeRequired(126, std::string(MapType::kKeyName), int32()),
253 SchemaField::MakeRequired(127, std::string(MapType::kValueName), binary())),
254 "Map of column id to lower bound");
255
256 static constexpr int32_t kUpperBoundsFieldId = 128;
257 inline static const SchemaField kUpperBounds = SchemaField::MakeOptional(
258 kUpperBoundsFieldId, "upper_bounds",
259 map(SchemaField::MakeRequired(129, std::string(MapType::kKeyName), int32()),
260 SchemaField::MakeRequired(130, std::string(MapType::kValueName), binary())),
261 "Map of column id to upper bound");
262
263 static constexpr int32_t kKeyMetadataFieldId = 131;
264 inline static const SchemaField kKeyMetadata = SchemaField::MakeOptional(
265 kKeyMetadataFieldId, "key_metadata", binary(), "Encryption key metadata blob");
266
267 static constexpr int32_t kSplitOffsetsFieldId = 132;
268 inline static const SchemaField kSplitOffsets = SchemaField::MakeOptional(
269 kSplitOffsetsFieldId, "split_offsets",
270 list(SchemaField::MakeRequired(133, std::string(ListType::kElementName), int64())),
271 "Splittable offsets");
272
273 static constexpr int32_t kEqualityIdsFieldId = 135;
274 inline static const SchemaField kEqualityIds = SchemaField::MakeOptional(
275 kEqualityIdsFieldId, "equality_ids",
276 list(SchemaField::MakeRequired(136, std::string(ListType::kElementName), int32())),
277 "Equality comparison field IDs");
278
279 static constexpr int32_t kSortOrderIdFieldId = 140;
280 inline static const SchemaField kSortOrderId = SchemaField::MakeOptional(
281 kSortOrderIdFieldId, "sort_order_id", int32(), "Sort order ID");
282
283 static constexpr int32_t kFirstRowIdFieldId = 142;
284 inline static const SchemaField kFirstRowId =
285 SchemaField::MakeOptional(kFirstRowIdFieldId, "first_row_id", int64(),
286 "Starting row ID to assign to new rows");
287
288 static constexpr int32_t kReferencedDataFileFieldId = 143;
289 inline static const SchemaField kReferencedDataFile = SchemaField::MakeOptional(
290 kReferencedDataFileFieldId, "referenced_data_file", string(),
291 "Fully qualified location (URI with FS scheme) of a data file that all deletes "
292 "reference");
293
294 static constexpr int32_t kContentOffsetFieldId = 144;
295 inline static const SchemaField kContentOffset =
296 SchemaField::MakeOptional(kContentOffsetFieldId, "content_offset", int64(),
297 "The offset in the file where the content starts");
298
299 static constexpr int32_t kContentSizeFieldId = 145;
300 inline static const SchemaField kContentSize =
301 SchemaField::MakeOptional(kContentSizeFieldId, "content_size_in_bytes", int64(),
302 "The length of referenced content stored in the file");
303
304 bool operator==(const DataFile& other) const = default;
305
307 static std::shared_ptr<StructType> Type(std::shared_ptr<StructType> partition_type);
308
310 bool IsDeletionVector() const {
311 return content == Content::kPositionDeletes && file_format == FileFormatType::kPuffin;
312 }
313};
314
317
319struct ICEBERG_EXPORT ManifestEntry {
323 ManifestStatus status = ManifestStatus::kAdded;
327 std::optional<int64_t> snapshot_id;
340 std::optional<int64_t> sequence_number;
353 std::optional<int64_t> file_sequence_number;
356 std::shared_ptr<DataFile> data_file;
357
358 static constexpr int32_t kStatusFieldId = 0;
359 inline static const SchemaField kStatus =
360 SchemaField::MakeRequired(kStatusFieldId, "status", int32());
361
362 static constexpr int32_t kSnapshotIdFieldId = 1;
363 inline static const SchemaField kSnapshotId =
364 SchemaField::MakeOptional(kSnapshotIdFieldId, "snapshot_id", int64());
365
366 static constexpr int32_t kDataFileFieldId = 2;
367 inline static const std::string kDataFileField = "data_file";
368
369 static constexpr int32_t kSequenceNumberFieldId = 3;
370 inline static const SchemaField kSequenceNumber =
371 SchemaField::MakeOptional(kSequenceNumberFieldId, "sequence_number", int64());
372
373 static constexpr int32_t kFileSequenceNumberFieldId = 4;
374 inline static const SchemaField kFileSequenceNumber = SchemaField::MakeOptional(
375 kFileSequenceNumberFieldId, "file_sequence_number", int64());
376
378 constexpr bool IsAlive() const {
379 return status == ManifestStatus::kAdded || status == ManifestStatus::kExisting;
380 }
381
382 ManifestEntry AsAdded() const {
383 ManifestEntry copy = *this;
384 copy.status = ManifestStatus::kAdded;
385 if (copy.data_file != nullptr && copy.data_file->first_row_id.has_value()) {
386 copy.data_file = std::make_unique<DataFile>(*copy.data_file);
387 copy.data_file->first_row_id = std::nullopt;
388 }
389 return copy;
390 }
391
392 ManifestEntry AsExisting() const {
393 ManifestEntry copy = *this;
394 copy.status = ManifestStatus::kExisting;
395 return copy;
396 }
397
398 ManifestEntry AsDeleted() const {
399 ManifestEntry copy = *this;
400 copy.status = ManifestStatus::kDeleted;
401 return copy;
402 }
403
404 bool operator==(const ManifestEntry& other) const;
405
406 static std::shared_ptr<StructType> TypeFromPartitionType(
407 std::shared_ptr<StructType> partition_type);
408 static std::shared_ptr<StructType> TypeFromDataFileType(
409 std::shared_ptr<StructType> datafile_type);
410};
411
413ICEBERG_EXPORT constexpr std::string_view ToString(DataFile::Content type) noexcept {
414 switch (type) {
415 case DataFile::Content::kData:
416 return "data";
417 case DataFile::Content::kPositionDeletes:
418 return "position_deletes";
419 case DataFile::Content::kEqualityDeletes:
420 return "equality_deletes";
421 }
423}
424
427 int32_t content) noexcept {
428 switch (content) {
429 case 0:
430 return DataFile::Content::kData;
431 case 1:
432 return DataFile::Content::kPositionDeletes;
433 case 2:
434 return DataFile::Content::kEqualityDeletes;
435 default:
436 return InvalidArgument("Invalid data file content: {}", content);
437 }
438}
439
440} // 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
Definition expected.h:1199
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:34
@ kData
The manifest content is data.
ICEBERG_EXPORT std::string_view ToString(Expression::Operation op)
Returns a string representation of an expression operation.
void unreachable() noexcept
Marks a branch the program can never take.
Definition unreachable.h:35
ICEBERG_EXPORT constexpr Result< ManifestStatus > ManifestStatusFromInt(int32_t status) noexcept
Get the relative manifest status type from int.
Definition manifest_entry.h:48
ICEBERG_EXPORT constexpr Result< DataFile::Content > DataFileContentFromInt(int32_t content) noexcept
Get the relative data file content type from int.
Definition manifest_entry.h:426
Define Result, Status, and error helpers.
DataFile carries data file path, partition tuple, metrics, ...
Definition manifest_entry.h:63
std::optional< int64_t > content_offset
Definition manifest_entry.h:172
std::map< int32_t, std::vector< uint8_t > > lower_bounds
Definition manifest_entry.h:119
std::optional< int64_t > content_size_in_bytes
Definition manifest_entry.h:176
std::optional< int64_t > first_row_id
Definition manifest_entry.h:156
PartitionValues partition
Definition manifest_entry.h:84
std::vector< int32_t > equality_ids
Definition manifest_entry.h:140
Content
Content of a data file.
Definition manifest_entry.h:65
std::map< int32_t, int64_t > column_sizes
Definition manifest_entry.h:97
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:107
std::optional< int32_t > partition_spec_id
Partition spec id for this data file.
Definition manifest_entry.h:183
std::optional< std::string > referenced_data_file
Definition manifest_entry.h:164
std::vector< uint8_t > key_metadata
Definition manifest_entry.h:129
std::map< int32_t, std::vector< uint8_t > > upper_bounds
Definition manifest_entry.h:126
std::map< int32_t, int64_t > nan_value_counts
Definition manifest_entry.h:112
std::vector< int64_t > split_offsets
Definition manifest_entry.h:134
std::optional< int32_t > sort_order_id
Definition manifest_entry.h:149
bool IsDeletionVector() const
Check if this data file is a deletion vector.
Definition manifest_entry.h:310
std::optional< int64_t > data_sequence_number
Data sequence number for this data file.
Definition manifest_entry.h:188
std::string file_path
Definition manifest_entry.h:77
std::map< int32_t, int64_t > value_counts
Definition manifest_entry.h:102
A manifest is an immutable Avro file that lists data files or delete files, along with each file's pa...
Definition manifest_entry.h:319
std::optional< int64_t > snapshot_id
Definition manifest_entry.h:327
std::optional< int64_t > file_sequence_number
Definition manifest_entry.h:353
std::optional< int64_t > sequence_number
Definition manifest_entry.h:340
constexpr bool IsAlive() const
Check if this manifest entry is deleted.
Definition manifest_entry.h:378
std::shared_ptr< DataFile > data_file
Definition manifest_entry.h:356
ManifestStatus status
Definition manifest_entry.h:323
Portable stand-in for std::unreachable.