Skip to content

Commit 99ce6e5

Browse files
committed
fixup! Add Indexes and Stats format reader and writer
ByteBuffer for writes
1 parent 1a4819a commit 99ce6e5

3 files changed

Lines changed: 26 additions & 33 deletions

File tree

core/src/main/java/org/apache/iceberg/stats/StatsFormat.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.io.IOException;
2626
import java.io.OutputStream;
2727
import java.math.BigInteger;
28-
import java.util.Arrays;
28+
import java.nio.ByteBuffer;
2929
import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
3030

3131
final class StatsFormat {
@@ -57,27 +57,28 @@ static int readIntegerLittleEndian(byte[] data, int offset) {
5757
(Byte.toUnsignedInt(data[offset + 3]) << 24);
5858
}
5959

60-
static byte[] compressFooterPayload(byte[] payload) {
61-
return compress(StatsCompressionCodec.LZ4, payload, 0, payload.length);
60+
static ByteBuffer compressFooterPayload(ByteBuffer payload) {
61+
return compress(StatsCompressionCodec.LZ4, payload);
6262
}
6363

6464
static byte[] decompressFooterPayload(byte[] footer, int offset, int length) {
6565
return decompress(StatsCompressionCodec.LZ4, footer, offset, length);
6666
}
6767

68-
static byte[] compressBlob(StatsCompressionCodec codec, byte[] data, int dataOffset, int dataLength) {
69-
return compress(codec, data, dataOffset, dataLength);
68+
static ByteBuffer compressBlob(StatsCompressionCodec codec, ByteBuffer data) {
69+
return compress(codec, data);
7070
}
7171

7272
static byte[] decompressBlob(StatsCompressionCodec codec, byte[] data, int dataOffset, int dataLength) {
7373
return decompress(codec, data, dataOffset, dataLength);
7474
}
7575

76-
private static byte[] compress(StatsCompressionCodec codec, byte[] input, int inputOffset, int inputLength) {
76+
private static ByteBuffer compress(StatsCompressionCodec codec, ByteBuffer input) {
7777
Compressor compressor = getCompressor(codec);
78-
byte[] output = new byte[compressor.maxCompressedLength(inputLength)];
79-
int length = compressor.compress(input, inputOffset, inputLength, output, 0, output.length);
80-
return length == output.length ? output : Arrays.copyOf(output, length);
78+
ByteBuffer output = ByteBuffer.allocate(compressor.maxCompressedLength(input.remaining()));
79+
compressor.compress(input, output);
80+
output.flip();
81+
return output;
8182
}
8283

8384
private static Compressor getCompressor(StatsCompressionCodec codec) {

core/src/main/java/org/apache/iceberg/stats/StatsWriter.java

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import java.io.Closeable;
2323
import java.io.IOException;
24+
import java.nio.ByteBuffer;
25+
import java.nio.channels.Channels;
2426
import java.nio.charset.StandardCharsets;
2527
import java.util.List;
2628
import java.util.Map;
@@ -58,32 +60,21 @@ public void addFileProperty(String name, String value) {
5860
throw new IllegalStateException(String.format("Property '%s' already set", name));
5961
}
6062
}
61-
6263
public void append(
6364
String type,
6465
Set<Integer> columnsCovered,
65-
byte[] blobData,
66-
int dataOffset,
67-
int dataLength,
66+
ByteBuffer blobData,
6867
Optional<StatsCompressionCodec> compression) throws IOException {
6968
checkNotFinished();
7069
writeHeaderIfNeeded();
7170

7271
Objects.requireNonNull(type, "type is null");
7372
long fileOffset = outputStream.getPos();
74-
byte[] data;
75-
int offset;
76-
int length;
77-
if (compression.isPresent()) {
78-
data = StatsFormat.compressBlob(compression.get(), blobData, dataOffset, dataLength);
79-
offset = 0;
80-
length = data.length;
81-
} else {
82-
data = blobData;
83-
offset = dataOffset;
84-
length = dataLength;
85-
}
86-
outputStream.write(data, offset, length);
73+
ByteBuffer data;
74+
data = compression.map(codec -> StatsFormat.compressBlob(codec, blobData))
75+
.orElse(blobData);
76+
int length = data.remaining();
77+
Channels.newChannel(outputStream).write(data);
8778
@Nullable String codecName = compression.map(StatsCompressionCodec::getCodecName).orElse(null);
8879
blobs.add(new BlobMetadata(type, columnsCovered, fileOffset, length, codecName));
8980
}
@@ -120,13 +111,13 @@ public void finish() throws IOException {
120111
}
121112

122113
FileMetadata fileMetadata = new FileMetadata(blobs, properties);
123-
byte[] footerJson = FileMetadataParser.toJson(fileMetadata).getBytes(StandardCharsets.UTF_8);
124-
byte[] footerPayload = compressFooter ? StatsFormat.compressFooterPayload(footerJson) : footerJson;
114+
ByteBuffer footerJson = ByteBuffer.wrap(FileMetadataParser.toJson(fileMetadata).getBytes(StandardCharsets.UTF_8));
115+
ByteBuffer footerPayload = compressFooter ? StatsFormat.compressFooterPayload(footerJson) : footerJson;
125116
long footerOffset = outputStream.getPos();
126117
byte[] magic = StatsFormat.getMagic();
127118
outputStream.write(magic);
128-
outputStream.write(footerPayload);
129-
StatsFormat.writeIntegerLittleEndian(outputStream, footerPayload.length);
119+
int footerPayloadLength = Channels.newChannel(outputStream).write(footerPayload);
120+
StatsFormat.writeIntegerLittleEndian(outputStream, footerPayloadLength);
130121
StatsFormat.writeIntegerLittleEndian(outputStream, 0); // Reserved
131122
StatsFormat.writeIntegerLittleEndian(outputStream, getFileFlags());
132123
StatsFormat.writeIntegerLittleEndian(outputStream, StatsFormat.CURRENT_FORMAT_VERSION);

core/src/test/java/org/apache/iceberg/stats/TestStatsWriter.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.iceberg.stats;
2121

22+
import java.nio.ByteBuffer;
2223
import java.util.Optional;
2324
import org.apache.iceberg.io.InMemoryOutputFile;
2425
import org.apache.iceberg.relocated.com.google.common.collect.ImmutableSet;
@@ -33,7 +34,7 @@
3334

3435
public class TestStatsWriter {
3536
@Test
36-
public void testEmptyFooterCompressed() throws Exception {
37+
public void testEmptyFooterCompressed() {
3738
InMemoryOutputFile outputFile = new InMemoryOutputFile();
3839
StatsWriter writer = new StatsWriter(outputFile);
3940
writer.setCompressFooter(true);
@@ -91,13 +92,13 @@ private void testWriteMetric(Optional<StatsCompressionCodec> compression, String
9192
try (StatsWriter writer = new StatsWriter(outputFile)) {
9293
writer.addFileProperty("writer.version", "1234");
9394

94-
writer.append("some-blob", ImmutableSet.of(1), "abcdefghi".getBytes(UTF_8), 0, 9, compression);
95+
writer.append("some-blob", ImmutableSet.of(1), ByteBuffer.wrap("abcdefghi".getBytes(UTF_8)), compression);
9596

9697
/// "xxx"s are stripped away by data offsets
9798
byte[] bytes =
9899
"xxx some blob \u0000 binary data 🤯 that is not very very very very very very long, is it? xxx".getBytes(
99100
UTF_8);
100-
writer.append("some-other-blob", ImmutableSet.of(2), bytes, 4, bytes.length - 8, compression);
101+
writer.append("some-other-blob", ImmutableSet.of(2), ByteBuffer.wrap(bytes, 4, bytes.length - 8), compression);
101102
}
102103

103104
byte[] expected = readTestResource(expectedResource);

0 commit comments

Comments
 (0)