Skip to content
Merged
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
93 changes: 45 additions & 48 deletions core/src/main/java/org/apache/iceberg/ContentFileParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
import org.apache.iceberg.util.JsonUtil;

class ContentFileParser {
public class ContentFileParser {
private static final String SPEC_ID = "spec-id";
private static final String CONTENT = "content";
private static final String FILE_PATH = "file-path";
Expand All @@ -48,17 +48,8 @@ class ContentFileParser {

private ContentFileParser() {}

private static boolean hasPartitionData(StructLike partitionData) {
return partitionData != null && partitionData.size() > 0;
}

static String toJson(ContentFile<?> contentFile, PartitionSpec spec) {
return JsonUtil.generate(
generator -> ContentFileParser.toJson(contentFile, spec, generator), false);
}

static void toJson(ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator generator)
throws IOException {
public static void unboundContentFileToJson(
ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator generator) throws IOException {
Preconditions.checkArgument(contentFile != null, "Invalid content file: null");
Preconditions.checkArgument(spec != null, "Invalid partition spec: null");
Preconditions.checkArgument(generator != null, "Invalid JSON generator: null");
Expand All @@ -67,14 +58,8 @@ static void toJson(ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator
"Invalid partition spec id from content file: expected = %s, actual = %s",
spec.specId(),
contentFile.specId());
Preconditions.checkArgument(
spec.isPartitioned() == hasPartitionData(contentFile.partition()),
"Invalid partition data from content file: expected = %s, actual = %s",
spec.isPartitioned() ? "partitioned" : "unpartitioned",
hasPartitionData(contentFile.partition()) ? "partitioned" : "unpartitioned");

generator.writeStartObject();

// ignore the ordinal position (ContentFile#pos) of the file in a manifest,
// as it isn't used and BaseFile constructor doesn't support it.

Expand Down Expand Up @@ -112,33 +97,14 @@ static void toJson(ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator
generator.writeEndObject();
}

static ContentFile<?> fromJson(JsonNode jsonNode, PartitionSpec spec) {
public static ContentFile<?> unboundContentFileFromJson(JsonNode jsonNode) {
Preconditions.checkArgument(jsonNode != null, "Invalid JSON node for content file: null");
Preconditions.checkArgument(
jsonNode.isObject(), "Invalid JSON node for content file: non-object (%s)", jsonNode);
Preconditions.checkArgument(spec != null, "Invalid partition spec: null");

int specId = JsonUtil.getInt(SPEC_ID, jsonNode);
FileContent fileContent = FileContent.valueOf(JsonUtil.getString(CONTENT, jsonNode));
String filePath = JsonUtil.getString(FILE_PATH, jsonNode);
FileFormat fileFormat = FileFormat.fromString(JsonUtil.getString(FILE_FORMAT, jsonNode));

PartitionData partitionData = null;
if (jsonNode.has(PARTITION)) {
partitionData = new PartitionData(spec.partitionType());
StructLike structLike =
(StructLike) SingleValueParser.fromJson(spec.partitionType(), jsonNode.get(PARTITION));
Preconditions.checkState(
partitionData.size() == structLike.size(),
"Invalid partition data size: expected = %s, actual = %s",
partitionData.size(),
structLike.size());
for (int pos = 0; pos < partitionData.size(); ++pos) {
Class<?> javaClass = spec.partitionType().fields().get(pos).type().typeId().javaClass();
partitionData.set(pos, structLike.get(pos, javaClass));
}
}

long fileSizeInBytes = JsonUtil.getLong(FILE_SIZE, jsonNode);
Metrics metrics = metricsFromJson(jsonNode);
ByteBuffer keyMetadata = JsonUtil.getByteBufferOrNull(KEY_METADATA, jsonNode);
Expand All @@ -151,7 +117,7 @@ static ContentFile<?> fromJson(JsonNode jsonNode, PartitionSpec spec) {
specId,
filePath,
fileFormat,
partitionData,
null,
fileSizeInBytes,
metrics,
keyMetadata,
Expand All @@ -163,7 +129,7 @@ static ContentFile<?> fromJson(JsonNode jsonNode, PartitionSpec spec) {
fileContent,
filePath,
fileFormat,
partitionData,
null,
fileSizeInBytes,
metrics,
equalityFieldIds,
Expand All @@ -173,8 +139,17 @@ static ContentFile<?> fromJson(JsonNode jsonNode, PartitionSpec spec) {
}
}

static void unboundContentFileToJson(
ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator generator) throws IOException {
private static boolean hasPartitionData(StructLike partitionData) {
return partitionData != null && partitionData.size() > 0;
}

static String toJson(ContentFile<?> contentFile, PartitionSpec spec) {
return JsonUtil.generate(
generator -> ContentFileParser.toJson(contentFile, spec, generator), false);
}

static void toJson(ContentFile<?> contentFile, PartitionSpec spec, JsonGenerator generator)
throws IOException {
Preconditions.checkArgument(contentFile != null, "Invalid content file: null");
Preconditions.checkArgument(spec != null, "Invalid partition spec: null");
Preconditions.checkArgument(generator != null, "Invalid JSON generator: null");
Expand All @@ -183,8 +158,14 @@ static void unboundContentFileToJson(
"Invalid partition spec id from content file: expected = %s, actual = %s",
spec.specId(),
contentFile.specId());
Preconditions.checkArgument(
spec.isPartitioned() == hasPartitionData(contentFile.partition()),
"Invalid partition data from content file: expected = %s, actual = %s",
spec.isPartitioned() ? "partitioned" : "unpartitioned",
hasPartitionData(contentFile.partition()) ? "partitioned" : "unpartitioned");

generator.writeStartObject();

// ignore the ordinal position (ContentFile#pos) of the file in a manifest,
// as it isn't used and BaseFile constructor doesn't support it.

Expand Down Expand Up @@ -222,17 +203,33 @@ static void unboundContentFileToJson(
generator.writeEndObject();
}

static ContentFile<?> unboundContentFileFromJson(JsonNode jsonNode) {
// TODO this does not contain ParitionSpec at the time of serialization
// we will need to bind the correct ParitionData to the file at a later point in the protocol.

static ContentFile<?> fromJson(JsonNode jsonNode, PartitionSpec spec) {
Preconditions.checkArgument(jsonNode != null, "Invalid JSON node for content file: null");
Preconditions.checkArgument(
jsonNode.isObject(), "Invalid JSON node for content file: non-object (%s)", jsonNode);
Preconditions.checkArgument(spec != null, "Invalid partition spec: null");

int specId = JsonUtil.getInt(SPEC_ID, jsonNode);
FileContent fileContent = FileContent.valueOf(JsonUtil.getString(CONTENT, jsonNode));
String filePath = JsonUtil.getString(FILE_PATH, jsonNode);
FileFormat fileFormat = FileFormat.fromString(JsonUtil.getString(FILE_FORMAT, jsonNode));

PartitionData partitionData = null;
if (jsonNode.has(PARTITION)) {
partitionData = new PartitionData(spec.partitionType());
StructLike structLike =
(StructLike) SingleValueParser.fromJson(spec.partitionType(), jsonNode.get(PARTITION));
Preconditions.checkState(
partitionData.size() == structLike.size(),
"Invalid partition data size: expected = %s, actual = %s",
partitionData.size(),
structLike.size());
for (int pos = 0; pos < partitionData.size(); ++pos) {
Class<?> javaClass = spec.partitionType().fields().get(pos).type().typeId().javaClass();
partitionData.set(pos, structLike.get(pos, javaClass));
}
}

long fileSizeInBytes = JsonUtil.getLong(FILE_SIZE, jsonNode);
Metrics metrics = metricsFromJson(jsonNode);
ByteBuffer keyMetadata = JsonUtil.getByteBufferOrNull(KEY_METADATA, jsonNode);
Expand All @@ -245,7 +242,7 @@ static ContentFile<?> unboundContentFileFromJson(JsonNode jsonNode) {
specId,
filePath,
fileFormat,
null,
partitionData,
fileSizeInBytes,
metrics,
keyMetadata,
Expand All @@ -257,7 +254,7 @@ static ContentFile<?> unboundContentFileFromJson(JsonNode jsonNode) {
fileContent,
filePath,
fileFormat,
null,
partitionData,
fileSizeInBytes,
metrics,
equalityFieldIds,
Expand Down

This file was deleted.

Loading