Skip to content

Commit 3d402c2

Browse files
committed
Improve performance with bloom_filter_length
1 parent 69eaefa commit 3d402c2

6 files changed

Lines changed: 75 additions & 5 deletions

File tree

parquet-hadoop/src/main/java/org/apache/parquet/format/converter/ParquetMetadataConverter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,10 @@ private void addRowGroup(ParquetMetadata parquetMetadata, List<RowGroup> rowGrou
541541
if (bloomFilterOffset >= 0) {
542542
metaData.setBloom_filter_offset(bloomFilterOffset);
543543
}
544+
int bloomFilterLength = columnMetaData.getBloomFilterLength();
545+
if (bloomFilterLength >= 0) {
546+
metaData.setBloom_filter_length(bloomFilterLength);
547+
}
544548
if (columnMetaData.getStatistics() != null && !columnMetaData.getStatistics().isEmpty()) {
545549
metaData.setStatistics(toParquetStatistics(columnMetaData.getStatistics(), this.statisticsTruncateLength));
546550
}
@@ -1595,6 +1599,9 @@ public ParquetMetadata fromParquetMetadata(FileMetaData parquetMetadata,
15951599
if (metaData.isSetBloom_filter_offset()) {
15961600
column.setBloomFilterOffset(metaData.getBloom_filter_offset());
15971601
}
1602+
if (metaData.isSetBloom_filter_length()) {
1603+
column.setBloomFilterLength(metaData.getBloom_filter_length());
1604+
}
15981605
} else { // column encrypted with column key
15991606
// Metadata will be decrypted later, if this column is accessed
16001607
EncryptionWithColumnKey columnKeyStruct = cryptoMetaData.getENCRYPTION_WITH_COLUMN_KEY();

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetFileReader.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static org.apache.parquet.hadoop.ParquetFileWriter.PARQUET_COMMON_METADATA_FILE;
3333
import static org.apache.parquet.hadoop.ParquetFileWriter.PARQUET_METADATA_FILE;
3434

35+
import java.io.ByteArrayInputStream;
3536
import java.io.Closeable;
3637
import java.io.IOException;
3738
import java.io.InputStream;
@@ -1347,11 +1348,24 @@ public BloomFilter readBloomFilter(ColumnChunkMetaData meta) throws IOException
13471348
}
13481349
}
13491350

1350-
// Read Bloom filter data header.
1351+
// Seek to Bloom filter offset.
13511352
f.seek(bloomFilterOffset);
1353+
1354+
// Read Bloom filter length.
1355+
int bloomFilterLength = meta.getBloomFilterLength();
1356+
1357+
// If it is set, read Bloom filter header and bitset together.
1358+
// Otherwise, read Bloom filter header first and then bitset.
1359+
InputStream in = null;
1360+
if (bloomFilterLength > 0) {
1361+
byte[] headerAndBitSet = new byte[bloomFilterLength];
1362+
f.readFully(headerAndBitSet);
1363+
in = new ByteArrayInputStream(headerAndBitSet);
1364+
}
1365+
13521366
BloomFilterHeader bloomFilterHeader;
13531367
try {
1354-
bloomFilterHeader = Util.readBloomFilterHeader(f, bloomFilterDecryptor, bloomFilterHeaderAAD);
1368+
bloomFilterHeader = Util.readBloomFilterHeader(in != null ? in : f, bloomFilterDecryptor, bloomFilterHeaderAAD);
13551369
} catch (IOException e) {
13561370
LOG.warn("read no bloom filter");
13571371
return null;
@@ -1373,9 +1387,13 @@ public BloomFilter readBloomFilter(ColumnChunkMetaData meta) throws IOException
13731387
byte[] bitset;
13741388
if (null == bloomFilterDecryptor) {
13751389
bitset = new byte[numBytes];
1376-
f.readFully(bitset);
1390+
if (in != null) {
1391+
in.read(bitset);
1392+
} else {
1393+
f.readFully(bitset);
1394+
}
13771395
} else {
1378-
bitset = bloomFilterDecryptor.decrypt(f, bloomFilterBitsetAAD);
1396+
bitset = bloomFilterDecryptor.decrypt(in != null ? in : f, bloomFilterBitsetAAD);
13791397
if (bitset.length != numBytes) {
13801398
throw new ParquetCryptoRuntimeException("Wrong length of decrypted bloom filter bitset");
13811399
}

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetFileWriter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,9 @@ private static void serializeBloomFilters(
13961396
serializedBitset = bloomFilterEncryptor.encrypt(serializedBitset, bloomFilterBitsetAAD);
13971397
}
13981398
out.write(serializedBitset);
1399+
1400+
int length = (int)(out.getPos() - offset);
1401+
column.setBloomFilterLength(length);
13991402
}
14001403
}
14011404
}

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/metadata/ColumnChunkMetaData.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ protected static boolean positiveLongFitsInAnInt(long value) {
211211
private IndexReference offsetIndexReference;
212212

213213
private long bloomFilterOffset = -1;
214+
private int bloomFilterLength = -1;
214215

215216
protected ColumnChunkMetaData(ColumnChunkProperties columnChunkProperties) {
216217
this(null, columnChunkProperties);
@@ -332,6 +333,15 @@ public void setBloomFilterOffset(long bloomFilterOffset) {
332333
this.bloomFilterOffset = bloomFilterOffset;
333334
}
334335

336+
/**
337+
* @param bloomFilterLength
338+
* the reference to the Bloom filter
339+
*/
340+
@Private
341+
public void setBloomFilterLength(int bloomFilterLength) {
342+
this.bloomFilterLength = bloomFilterLength;
343+
}
344+
335345
/**
336346
* @return the offset to the Bloom filter or {@code -1} if there is no bloom filter for this column chunk
337347
*/
@@ -341,6 +351,15 @@ public long getBloomFilterOffset() {
341351
return bloomFilterOffset;
342352
}
343353

354+
/**
355+
* @return the length to the Bloom filter or {@code -1} if there is no bloom filter for this column chunk
356+
*/
357+
@Private
358+
public int getBloomFilterLength() {
359+
decryptIfNeeded();
360+
return bloomFilterLength;
361+
}
362+
344363
/**
345364
* @return all the encodings used in this column
346365
*/
@@ -630,6 +649,9 @@ protected void decryptIfNeeded() {
630649
if (metaData.isSetBloom_filter_offset()) {
631650
setBloomFilterOffset(metaData.getBloom_filter_offset());
632651
}
652+
if (metaData.isSetBloom_filter_length()) {
653+
setBloomFilterLength(metaData.getBloom_filter_length());
654+
}
633655
}
634656

635657
@Override

parquet-hadoop/src/test/java/org/apache/parquet/format/converter/TestParquetMetadataConverter.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,26 @@ public void testBloomFilterOffset() throws IOException {
274274
assertEquals(1234, convertedMetaData.getBlocks().get(0).getColumns().get(0).getBloomFilterOffset());
275275
}
276276

277+
@Test
278+
public void testBloomFilterLength() throws IOException {
279+
ParquetMetadata origMetaData = createParquetMetaData(null, Encoding.PLAIN);
280+
ParquetMetadataConverter converter = new ParquetMetadataConverter();
281+
282+
// Without bloom filter length
283+
FileMetaData footer = converter.toParquetMetadata(1, origMetaData);
284+
assertFalse(footer.getRow_groups().get(0).getColumns().get(0).getMeta_data().isSetBloom_filter_length());
285+
ParquetMetadata convertedMetaData = converter.fromParquetMetadata(footer);
286+
assertTrue(convertedMetaData.getBlocks().get(0).getColumns().get(0).getBloomFilterLength() < 0);
287+
288+
// With bloom filter length
289+
origMetaData.getBlocks().get(0).getColumns().get(0).setBloomFilterLength(1024);
290+
footer = converter.toParquetMetadata(1, origMetaData);
291+
assertTrue(footer.getRow_groups().get(0).getColumns().get(0).getMeta_data().isSetBloom_filter_length());
292+
assertEquals(1024, footer.getRow_groups().get(0).getColumns().get(0).getMeta_data().getBloom_filter_length());
293+
convertedMetaData = converter.fromParquetMetadata(footer);
294+
assertEquals(1024, convertedMetaData.getBlocks().get(0).getColumns().get(0).getBloomFilterLength());
295+
}
296+
277297
@Test
278298
public void testLogicalTypesBackwardCompatibleWithConvertedTypes() {
279299
ParquetMetadataConverter parquetMetadataConverter = new ParquetMetadataConverter();

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
<japicmp.version>0.18.1</japicmp.version>
7272
<shade.prefix>shaded.parquet</shade.prefix>
7373
<hadoop.version>3.3.5</hadoop.version>
74-
<parquet.format.version>2.9.0</parquet.format.version>
74+
<parquet.format.version>2.10.0-SNAPSHOT</parquet.format.version>
7575
<previous.version>1.13.0</previous.version>
7676
<thrift.executable>thrift</thrift.executable>
7777
<format.thrift.executable>${thrift.executable}</format.thrift.executable>

0 commit comments

Comments
 (0)