Skip to content

Commit 6186a55

Browse files
committed
move atomicbitvector to utils
1 parent bed1365 commit 6186a55

File tree

4 files changed

+90
-14
lines changed

4 files changed

+90
-14
lines changed

CMakeLists.txt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,6 @@ CPMAddPackage(
266266
)
267267
include_directories(SYSTEM "${magic_enum_SOURCE_DIR}/include")
268268

269-
CPMAddPackage(
270-
NAME atomicbitvector
271-
GITHUB_REPOSITORY ekg/atomicbitvector
272-
GIT_TAG e295358fea9532fa4c37197630d037a4a53ddede
273-
DOWNLOAD_ONLY True
274-
)
275-
include_directories(SYSTEM "${atomicbitvector_SOURCE_DIR}/include")
276-
277269
if(DESBORDANTE_BUILD_TESTS)
278270
CPMAddPackage(
279271
NAME googletest

src/core/algorithms/ind/faida/inclusion_testing/sampled_inverted_index.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void SampledInvertedIndex::Init(std::vector<size_t> const& sampled_hashes, int m
1212
max_id_ = max_id;
1313

1414
seen_cc_indices_ = boost::dynamic_bitset<>(max_id);
15-
non_covered_cc_indices_ = atomicbitvector::atomic_bv_t(max_id);
15+
non_covered_cc_indices_ = util::AtomicBitVector(max_id);
1616

1717
discovered_inds_.clear();
1818
}

src/core/algorithms/ind/faida/inclusion_testing/sampled_inverted_index.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22

3-
#include <atomic_bitvector.hpp>
43
#include <hash_set2.hpp>
54
#include <hash_table8.hpp>
65
#include <mutex>
@@ -10,6 +9,7 @@
109

1110
#include "core/algorithms/ind/faida/inclusion_testing/hll_data.h"
1211
#include "core/algorithms/ind/faida/util/simple_ind.h"
12+
#include "core/util/atomic_bit_vector.h"
1313

1414
namespace algos::faida {
1515

@@ -24,7 +24,7 @@ class SampledInvertedIndex {
2424
emhash2::HashSet<SimpleIND> discovered_inds_;
2525

2626
boost::dynamic_bitset<> seen_cc_indices_;
27-
atomicbitvector::atomic_bv_t non_covered_cc_indices_;
27+
util::AtomicBitVector non_covered_cc_indices_;
2828

2929
int max_id_;
3030

@@ -37,8 +37,8 @@ class SampledInvertedIndex {
3737
auto set_iter = inverted_index_.find(hash);
3838

3939
if (set_iter == inverted_index_.end()) {
40-
if (!non_covered_cc_indices_.test(combination.GetIndex())) {
41-
non_covered_cc_indices_.set(combination.GetIndex());
40+
if (!non_covered_cc_indices_.Test(combination.GetIndex())) {
41+
non_covered_cc_indices_.Set(combination.GetIndex());
4242
}
4343
return false;
4444
}
@@ -50,7 +50,7 @@ class SampledInvertedIndex {
5050
}
5151

5252
bool IsCovered(std::shared_ptr<SimpleCC> const& combination) {
53-
return !non_covered_cc_indices_.test(combination->GetIndex());
53+
return !non_covered_cc_indices_.Test(combination->GetIndex());
5454
}
5555

5656
bool IsIncludedIn(std::shared_ptr<SimpleCC> const& a, std::shared_ptr<SimpleCC> const& b) {

src/core/util/atomic_bit_vector.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Based on atomic_bitvector by Erik Garrison (Apache 2.0)
3+
* https://github.com/ekg/atomicbitvector
4+
*
5+
* Simplified version without iterator support.
6+
*/
7+
8+
#pragma once
9+
10+
#include <atomic>
11+
#include <cassert>
12+
#include <cstddef>
13+
#include <limits>
14+
#include <memory>
15+
16+
namespace util {
17+
18+
class AtomicBitVector {
19+
public:
20+
AtomicBitVector(size_t size)
21+
: size_(size),
22+
num_blocks_((size + kBitsPerBlock - 1) / kBitsPerBlock),
23+
data_(std::make_unique<std::atomic<BlockType>[]>(num_blocks_)) {}
24+
25+
// Set bit to true. Returns previous value.
26+
bool Set(size_t idx, std::memory_order order = std::memory_order_seq_cst) {
27+
assert(idx < size_);
28+
BlockType mask = kOne << BitOffset(idx);
29+
return data_[BlockIndex(idx)].fetch_or(mask, order) & mask;
30+
}
31+
32+
// Set bit to false. Returns previous value.
33+
bool Reset(size_t idx, std::memory_order order = std::memory_order_seq_cst) {
34+
assert(idx < size_);
35+
BlockType mask = kOne << BitOffset(idx);
36+
return data_[BlockIndex(idx)].fetch_and(~mask, order) & mask;
37+
}
38+
39+
// Set bit to given value. Returns previous value.
40+
bool Set(size_t idx, bool value, std::memory_order order = std::memory_order_seq_cst) {
41+
return value ? Set(idx, order) : Reset(idx, order);
42+
}
43+
44+
// Read bit value.
45+
bool Test(size_t idx, std::memory_order order = std::memory_order_seq_cst) const {
46+
assert(idx < size_);
47+
BlockType mask = kOne << BitOffset(idx);
48+
return data_[BlockIndex(idx)].load(order) & mask;
49+
}
50+
51+
bool operator[](size_t idx) const {
52+
return Test(idx);
53+
}
54+
55+
constexpr size_t Size() const noexcept {
56+
return size_;
57+
}
58+
59+
private:
60+
#if (ATOMIC_LLONG_LOCK_FREE == 2)
61+
using BlockType = unsigned long long;
62+
#elif (ATOMIC_LONG_LOCK_FREE == 2)
63+
using BlockType = unsigned long;
64+
#else
65+
using BlockType = unsigned int;
66+
#endif
67+
68+
static constexpr size_t kBitsPerBlock = std::numeric_limits<BlockType>::digits;
69+
static constexpr BlockType kOne = 1;
70+
71+
static constexpr size_t BlockIndex(size_t bit) {
72+
return bit / kBitsPerBlock;
73+
}
74+
75+
static constexpr size_t BitOffset(size_t bit) {
76+
return bit % kBitsPerBlock;
77+
}
78+
79+
size_t size_;
80+
size_t num_blocks_;
81+
std::unique_ptr<std::atomic<BlockType>[]> data_;
82+
};
83+
84+
} // namespace util

0 commit comments

Comments
 (0)