1717
1818#include " parquet/bloom_filter_reader.h"
1919#include " parquet/bloom_filter.h"
20+ #include " parquet/encryption/encryption_internal.h"
21+ #include " parquet/encryption/internal_file_decryptor.h"
2022#include " parquet/exception.h"
2123#include " parquet/metadata.h"
2224
@@ -26,10 +28,14 @@ class RowGroupBloomFilterReaderImpl final : public RowGroupBloomFilterReader {
2628 public:
2729 RowGroupBloomFilterReaderImpl (std::shared_ptr<::arrow::io::RandomAccessFile> input,
2830 std::shared_ptr<RowGroupMetaData> row_group_metadata,
29- const ReaderProperties& properties)
31+ const ReaderProperties& properties,
32+ int32_t row_group_ordinal,
33+ std::shared_ptr<InternalFileDecryptor> file_decryptor)
3034 : input_(std::move(input)),
3135 row_group_metadata_ (std::move(row_group_metadata)),
32- properties_(properties) {}
36+ properties_(properties),
37+ row_group_ordinal_(row_group_ordinal),
38+ file_decryptor_(std::move(file_decryptor)) {}
3339
3440 std::unique_ptr<BloomFilter> GetColumnBloomFilter (int i) override ;
3541
@@ -42,6 +48,12 @@ class RowGroupBloomFilterReaderImpl final : public RowGroupBloomFilterReader {
4248
4349 // / Reader properties used to deserialize thrift object.
4450 const ReaderProperties& properties_;
51+
52+ // / The ordinal of the row group in the file.
53+ int32_t row_group_ordinal_;
54+
55+ // / File-level decryptor.
56+ std::shared_ptr<InternalFileDecryptor> file_decryptor_;
4557};
4658
4759std::unique_ptr<BloomFilter> RowGroupBloomFilterReaderImpl::GetColumnBloomFilter (int i) {
@@ -50,11 +62,6 @@ std::unique_ptr<BloomFilter> RowGroupBloomFilterReaderImpl::GetColumnBloomFilter
5062 }
5163
5264 auto col_chunk = row_group_metadata_->ColumnChunk (i);
53- std::unique_ptr<ColumnCryptoMetaData> crypto_metadata = col_chunk->crypto_metadata ();
54- if (crypto_metadata != nullptr ) {
55- ParquetException::NYI (" BloomFilter decryption is not yet supported" );
56- }
57-
5865 auto bloom_filter_offset = col_chunk->bloom_filter_offset ();
5966 if (!bloom_filter_offset.has_value ()) {
6067 return nullptr ;
@@ -76,10 +83,28 @@ std::unique_ptr<BloomFilter> RowGroupBloomFilterReaderImpl::GetColumnBloomFilter
7683 " bloom filter length + bloom filter offset greater than file size" );
7784 }
7885 }
79- auto stream = ::arrow::io::RandomAccessFile::GetStream (
80- input_, *bloom_filter_offset, file_size - *bloom_filter_offset);
86+ std::unique_ptr<ColumnCryptoMetaData> crypto_metadata = col_chunk->crypto_metadata ();
87+ std::unique_ptr<Decryptor> header_decryptor =
88+ InternalFileDecryptor::GetColumnMetaDecryptorFactory (file_decryptor_.get (),
89+ crypto_metadata.get ())();
90+ std::unique_ptr<Decryptor> bitset_decryptor =
91+ InternalFileDecryptor::GetColumnDataDecryptorFactory (file_decryptor_.get (),
92+ crypto_metadata.get ())();
93+ if (header_decryptor != nullptr ) {
94+ UpdateDecryptor (header_decryptor.get (), row_group_ordinal_, static_cast <int16_t >(i),
95+ encryption::kBloomFilterHeader );
96+ }
97+ if (bitset_decryptor != nullptr ) {
98+ UpdateDecryptor (bitset_decryptor.get (), row_group_ordinal_, static_cast <int16_t >(i),
99+ encryption::kBloomFilterBitset );
100+ }
101+ const int64_t stream_length =
102+ bloom_filter_length ? *bloom_filter_length : file_size - *bloom_filter_offset;
103+ auto stream = ::arrow::io::RandomAccessFile::GetStream (input_, *bloom_filter_offset,
104+ stream_length);
81105 auto bloom_filter =
82- BlockSplitBloomFilter::Deserialize (properties_, stream->get (), bloom_filter_length);
106+ BlockSplitBloomFilter::Deserialize (properties_, stream->get (), bloom_filter_length,
107+ header_decryptor.get (), bitset_decryptor.get ());
83108 return std::make_unique<BlockSplitBloomFilter>(std::move (bloom_filter));
84109}
85110
@@ -91,11 +116,8 @@ class BloomFilterReaderImpl final : public BloomFilterReader {
91116 std::shared_ptr<InternalFileDecryptor> file_decryptor)
92117 : input_(std::move(input)),
93118 file_metadata_ (std::move(file_metadata)),
94- properties_(properties) {
95- if (file_decryptor != nullptr ) {
96- ParquetException::NYI (" BloomFilter decryption is not yet supported" );
97- }
98- }
119+ properties_(properties),
120+ file_decryptor_(std::move(file_decryptor)) {}
99121
100122 std::shared_ptr<RowGroupBloomFilterReader> RowGroup (int i) {
101123 if (i < 0 || i >= file_metadata_->num_row_groups ()) {
@@ -104,7 +126,7 @@ class BloomFilterReaderImpl final : public BloomFilterReader {
104126
105127 auto row_group_metadata = file_metadata_->RowGroup (i);
106128 return std::make_shared<RowGroupBloomFilterReaderImpl>(
107- input_, std::move (row_group_metadata), properties_);
129+ input_, std::move (row_group_metadata), properties_, i, file_decryptor_ );
108130 }
109131
110132 private:
@@ -116,6 +138,9 @@ class BloomFilterReaderImpl final : public BloomFilterReader {
116138
117139 // / Reader properties used to deserialize thrift object.
118140 const ReaderProperties& properties_;
141+
142+ // / File-level decryptor, if any.
143+ std::shared_ptr<InternalFileDecryptor> file_decryptor_;
119144};
120145
121146std::unique_ptr<BloomFilterReader> BloomFilterReader::Make (
0 commit comments