@@ -40,16 +40,26 @@ namespace rocksdb {
40
40
41
41
PlainTableReader::PlainTableReader (const EnvOptions& storage_options,
42
42
uint64_t file_size, int user_key_size,
43
- int key_prefix_len) :
44
- soptions_ (storage_options), file_size_(file_size),
45
- user_key_size_ (user_key_size), key_prefix_len_(key_prefix_len) {
43
+ int key_prefix_len, int bloom_bits_per_key,
44
+ double hash_table_ratio) :
45
+ hash_table_size_ (0 ), soptions_(storage_options), file_size_(file_size),
46
+ user_key_size_ (user_key_size), key_prefix_len_(key_prefix_len),
47
+ hash_table_ratio_ (hash_table_ratio) {
48
+ if (bloom_bits_per_key > 0 ) {
49
+ filter_policy_ = NewBloomFilterPolicy (bloom_bits_per_key);
50
+ } else {
51
+ filter_policy_ = nullptr ;
52
+ }
46
53
hash_table_ = nullptr ;
47
54
}
48
55
49
56
PlainTableReader::~PlainTableReader () {
50
57
if (hash_table_ != nullptr ) {
51
58
delete[] hash_table_;
52
59
}
60
+ if (filter_policy_ != nullptr ) {
61
+ delete filter_policy_;
62
+ }
53
63
}
54
64
55
65
Status PlainTableReader::Open (const Options& options,
@@ -58,12 +68,16 @@ Status PlainTableReader::Open(const Options& options,
58
68
uint64_t file_size,
59
69
unique_ptr<TableReader>* table_reader,
60
70
const int user_key_size,
61
- const int key_prefix_len) {
71
+ const int key_prefix_len,
72
+ const int bloom_num_bits,
73
+ double hash_table_ratio) {
62
74
assert (options.allow_mmap_reads );
63
75
64
76
PlainTableReader* t = new PlainTableReader (soptions, file_size,
65
77
user_key_size,
66
- key_prefix_len);
78
+ key_prefix_len,
79
+ bloom_num_bits,
80
+ hash_table_ratio);
67
81
t->file_ = std::move (file);
68
82
t->options_ = options;
69
83
Status s = t->PopulateIndex (file_size);
@@ -146,14 +160,25 @@ Status PlainTableReader::PopulateIndex(uint64_t file_size) {
146
160
delete[] hash_table_;
147
161
}
148
162
// Make the hash table 3/5 full
149
- hash_table_size_ = tmp_index.size () * 1.66 ;
163
+ std::vector<Slice> filter_entries (0 ); // for creating bloom filter;
164
+ if (filter_policy_ != nullptr ) {
165
+ filter_entries.resize (tmp_index.size ());
166
+ }
167
+ double hash_table_size_multipier =
168
+ (hash_table_ratio_ < 1.0 ) ? 1.0 : 1.0 / hash_table_ratio_;
169
+ hash_table_size_ = tmp_index.size () * hash_table_size_multipier + 1 ;
150
170
hash_table_ = new char [GetHashTableRecordLen () * hash_table_size_];
151
171
for (int i = 0 ; i < hash_table_size_; i++) {
152
172
memcpy (GetHashTableBucketPtr (i) + key_prefix_len_, &file_size_,
153
173
kOffsetLen );
154
174
}
155
175
176
+ size_t count = 0 ;
156
177
for (auto it = tmp_index.begin (); it != tmp_index.end (); ++it) {
178
+ if (filter_policy_ != nullptr ) {
179
+ filter_entries[count++] = it->first ;
180
+ }
181
+
157
182
int bucket = GetHashTableBucket (it->first );
158
183
uint64_t * hash_value;
159
184
while (true ) {
@@ -168,6 +193,10 @@ Status PlainTableReader::PopulateIndex(uint64_t file_size) {
168
193
memcpy (bucket_ptr, it->first .data (), key_prefix_len_);
169
194
memcpy (bucket_ptr + key_prefix_len_, &it->second , kOffsetLen );
170
195
}
196
+ if (filter_policy_ != nullptr ) {
197
+ filter_policy_->CreateFilter (&filter_entries[0 ], count, &filter_str_);
198
+ filter_slice_ = Slice (filter_str_.data (), filter_str_.size ());
199
+ }
171
200
172
201
Log (options_.info_log , " Number of prefixes: %d, suffix_map length %ld" ,
173
202
hash_table_size_, sub_index_.length ());
@@ -187,7 +216,6 @@ inline void PlainTableReader::GetHashValue(int bucket, uint64_t** ret_value) {
187
216
188
217
Status PlainTableReader::GetOffset (const Slice& target, uint64_t * offset) {
189
218
Status s;
190
-
191
219
int bucket = GetHashTableBucket (target);
192
220
uint64_t * found_value;
193
221
Slice hash_key;
@@ -248,6 +276,12 @@ Status PlainTableReader::GetOffset(const Slice& target, uint64_t* offset) {
248
276
return s;
249
277
}
250
278
279
+ bool PlainTableReader::MayHavePrefix (const Slice& target_prefix) {
280
+ return filter_policy_ == nullptr
281
+ || filter_policy_->KeyMayMatch (target_prefix, filter_slice_);
282
+ }
283
+
284
+
251
285
uint64_t PlainTableReader::Next (uint64_t offset, Slice* key, Slice* value,
252
286
Slice* tmp_slice) {
253
287
if (offset >= file_size_) {
@@ -321,6 +355,11 @@ void PlainTableIterator::SeekToLast() {
321
355
}
322
356
323
357
void PlainTableIterator::Seek (const Slice& target) {
358
+ if (!table_->MayHavePrefix (Slice (target.data (), table_->key_prefix_len_ ))) {
359
+ offset_ = next_offset_ = table_->file_size_ ;
360
+ return ;
361
+ }
362
+
324
363
Status s = table_->GetOffset (target, &next_offset_);
325
364
if (!s.ok ()) {
326
365
status_ = s;
0 commit comments