]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
2 | // This source code is licensed under both the GPLv2 (found in the |
3 | // COPYING file in the root directory) and Apache 2.0 License | |
4 | // (found in the LICENSE.Apache file in the root directory). | |
7c673cae FG |
5 | |
6 | #include "dynamic_bloom.h" | |
7 | ||
8 | #include <algorithm> | |
9 | ||
10 | #include "port/port.h" | |
11 | #include "rocksdb/slice.h" | |
12 | #include "util/allocator.h" | |
13 | #include "util/hash.h" | |
14 | ||
15 | namespace rocksdb { | |
16 | ||
17 | namespace { | |
18 | ||
19 | uint32_t GetTotalBitsForLocality(uint32_t total_bits) { | |
20 | uint32_t num_blocks = | |
21 | (total_bits + CACHE_LINE_SIZE * 8 - 1) / (CACHE_LINE_SIZE * 8); | |
22 | ||
23 | // Make num_blocks an odd number to make sure more bits are involved | |
24 | // when determining which block. | |
25 | if (num_blocks % 2 == 0) { | |
26 | num_blocks++; | |
27 | } | |
28 | ||
29 | return num_blocks * (CACHE_LINE_SIZE * 8); | |
30 | } | |
31 | } | |
32 | ||
33 | DynamicBloom::DynamicBloom(Allocator* allocator, uint32_t total_bits, | |
34 | uint32_t locality, uint32_t num_probes, | |
35 | uint32_t (*hash_func)(const Slice& key), | |
36 | size_t huge_page_tlb_size, | |
37 | Logger* logger) | |
38 | : DynamicBloom(num_probes, hash_func) { | |
39 | SetTotalBits(allocator, total_bits, locality, huge_page_tlb_size, logger); | |
40 | } | |
41 | ||
42 | DynamicBloom::DynamicBloom(uint32_t num_probes, | |
43 | uint32_t (*hash_func)(const Slice& key)) | |
44 | : kTotalBits(0), | |
45 | kNumBlocks(0), | |
46 | kNumProbes(num_probes), | |
11fdf7f2 TL |
47 | hash_func_(hash_func == nullptr ? &BloomHash : hash_func), |
48 | data_(nullptr) {} | |
7c673cae FG |
49 | |
50 | void DynamicBloom::SetRawData(unsigned char* raw_data, uint32_t total_bits, | |
51 | uint32_t num_blocks) { | |
52 | data_ = reinterpret_cast<std::atomic<uint8_t>*>(raw_data); | |
53 | kTotalBits = total_bits; | |
54 | kNumBlocks = num_blocks; | |
55 | } | |
56 | ||
57 | void DynamicBloom::SetTotalBits(Allocator* allocator, | |
58 | uint32_t total_bits, uint32_t locality, | |
59 | size_t huge_page_tlb_size, | |
60 | Logger* logger) { | |
61 | kTotalBits = (locality > 0) ? GetTotalBitsForLocality(total_bits) | |
62 | : (total_bits + 7) / 8 * 8; | |
63 | kNumBlocks = (locality > 0) ? (kTotalBits / (CACHE_LINE_SIZE * 8)) : 0; | |
64 | ||
65 | assert(kNumBlocks > 0 || kTotalBits > 0); | |
66 | assert(kNumProbes > 0); | |
67 | ||
68 | uint32_t sz = kTotalBits / 8; | |
69 | if (kNumBlocks > 0) { | |
70 | sz += CACHE_LINE_SIZE - 1; | |
71 | } | |
72 | assert(allocator); | |
73 | ||
74 | char* raw = allocator->AllocateAligned(sz, huge_page_tlb_size, logger); | |
75 | memset(raw, 0, sz); | |
76 | auto cache_line_offset = reinterpret_cast<uintptr_t>(raw) % CACHE_LINE_SIZE; | |
77 | if (kNumBlocks > 0 && cache_line_offset > 0) { | |
78 | raw += CACHE_LINE_SIZE - cache_line_offset; | |
79 | } | |
80 | data_ = reinterpret_cast<std::atomic<uint8_t>*>(raw); | |
81 | } | |
82 | ||
83 | } // rocksdb |