Skip to content

Commit ec270b6

Browse files
committed
some more methods to bit_vector and compact_vector
1 parent a04dccf commit ec270b6

3 files changed

Lines changed: 73 additions & 3 deletions

File tree

include/bit_vector.hpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ struct bit_vector //
143143
}
144144

145145
uint64_t num_bits() const { return m_num_bits; }
146+
147+
std::vector<uint64_t>& data() { return m_data; }
146148
std::vector<uint64_t> const& data() const { return m_data; }
147149

148150
private:
@@ -192,12 +194,25 @@ struct bit_vector //
192194
struct iterator {
193195
iterator() : m_data(nullptr), m_num_64bit_words(0), m_pos(0), m_buf(0), m_avail(0) {}
194196

197+
iterator(uint64_t const* data, uint64_t num_64bit_words, uint64_t pos = 0)
198+
: m_data(data) //
199+
, m_num_64bit_words(num_64bit_words) //
200+
, m_pos(pos) //
201+
{
202+
skip_to(m_pos);
203+
}
204+
195205
iterator(bit_vector const* bv, uint64_t pos = 0)
196206
: m_data((bv->data()).data()) //
197207
, m_num_64bit_words((bv->data()).size()) //
198208
, m_pos(pos) //
199209
{
200-
assert(m_pos < bv->num_bits());
210+
skip_to(m_pos);
211+
}
212+
213+
void skip_to(uint64_t pos) {
214+
assert(pos < 64 * m_num_64bit_words);
215+
m_pos = pos;
201216
fill_buf();
202217
}
203218

include/compact_vector.hpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ struct compact_vector //
8686
struct builder {
8787
builder() : m_size(0), m_width(0), m_mask(0), m_back(0), m_cur_block(0), m_cur_shift(0) {}
8888

89-
builder(uint64_t n, uint64_t w) { resize(n, w); }
89+
builder(uint64_t n, uint64_t w) : builder() { resize(n, w); }
9090

9191
/*
9292
Resize the container to hold n values, each of width w.
@@ -96,6 +96,8 @@ struct compact_vector //
9696
m_width = w;
9797
m_mask = -(w == 64) | ((uint64_t(1) << w) - 1);
9898
m_back = 0;
99+
m_cur_block = 0;
100+
m_cur_shift = 0;
99101
m_data.resize(
100102
/* use 1 word more for safe access() */
101103
essentials::words_for(m_size * m_width) + 1, 0);
@@ -109,7 +111,9 @@ struct compact_vector //
109111
template <typename Iterator>
110112
void fill(Iterator begin, uint64_t n) {
111113
if (m_width == 0) throw std::runtime_error("width must be > 0");
112-
for (uint64_t i = 0; i != n; ++i, ++begin) set(i, *begin);
114+
for (uint64_t i = 0; i != n; ++i, ++begin) {
115+
set(i, *begin); // can just do push_back(*begin);
116+
}
113117
}
114118

115119
/*
@@ -134,6 +138,28 @@ struct compact_vector //
134138
}
135139
}
136140

141+
void push_back(uint64_t v) {
142+
assert(m_width != 0);
143+
m_back = v;
144+
m_data[m_cur_block] &= ~(m_mask << m_cur_shift);
145+
m_data[m_cur_block] |= v << m_cur_shift;
146+
147+
uint64_t res_shift = 64 - m_cur_shift;
148+
if (res_shift < m_width) {
149+
++m_cur_block;
150+
m_data[m_cur_block] &= ~(m_mask >> res_shift);
151+
m_data[m_cur_block] |= v >> res_shift;
152+
m_cur_shift = -res_shift;
153+
}
154+
155+
m_cur_shift += m_width;
156+
157+
if (m_cur_shift == 64) {
158+
m_cur_shift = 0;
159+
++m_cur_block;
160+
}
161+
}
162+
137163
void reduce_width_by(uint64_t n) {
138164
assert(m_width > n);
139165

test/test_bit_vector.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ TEST_CASE("bit_vector::iterator::operator*") {
5252
std::cout << "EVERYTHING OK!" << std::endl;
5353
}
5454

55+
TEST_CASE("bit_vector::iterator::skip_to") {
56+
const uint64_t max_int = test::get_random_uint();
57+
std::cout << "max_int = " << max_int << std::endl;
58+
constexpr bool all_distinct = true;
59+
std::vector<uint64_t> seq = test::get_sorted_sequence(sequence_length, max_int, all_distinct);
60+
const uint64_t num_bits = seq.back();
61+
bit_vector::builder bv_builder(num_bits + 1);
62+
std::vector<bool> vec_bools(num_bits + 1, false);
63+
for (auto pos : seq) {
64+
bv_builder.set(pos);
65+
vec_bools[pos] = true;
66+
}
67+
bit_vector bv;
68+
bv_builder.build(bv);
69+
std::cout << "checking correctness of bit_vector::iterator::skip_to..." << std::endl;
70+
bit_vector::iterator it = bv.begin();
71+
72+
srand(essentials::get_random_seed());
73+
for (int i = 0; i != 5; ++i) {
74+
uint64_t pos = rand() % num_bits;
75+
it.skip_to(pos);
76+
for (uint64_t j = pos; j != num_bits; ++j, ++it) {
77+
REQUIRE_MESSAGE(*it == vec_bools[j], "required " << vec_bools[j] << " but got " << *it);
78+
}
79+
}
80+
81+
std::cout << "EVERYTHING OK!" << std::endl;
82+
}
83+
5584
TEST_CASE("bit_vector::iterator::take") {
5685
const uint64_t max_int = test::get_random_uint();
5786
std::cout << "max_int = " << max_int << std::endl;

0 commit comments

Comments
 (0)