forked from meta-toolkit/meta
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbit_vector_test.cpp
123 lines (97 loc) · 4.17 KB
/
bit_vector_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* @file bit_vector_test.cpp
* @author Chase Geigle
*/
#include <fstream>
#include "bandit/bandit.h"
#include "meta/io/filesystem.h"
#include "meta/math/integer.h"
#include "meta/succinct/bit_vector.h"
#include "meta/util/disk_vector.h"
using namespace bandit;
go_bandit([]() {
using namespace meta;
using namespace succinct;
describe("[bit vector]", []() {
std::string filename = "bit-vector-test.bin";
it("should build files of the correct size", [&]() {
{
std::ofstream output{filename, std::ios::binary};
auto builder = make_bit_vector_builder(output);
auto all_ones = static_cast<uint64_t>(-1);
builder.write_bits({all_ones, 16});
builder.write_bits({all_ones, 64});
AssertThat(builder.total_bits(),
Equals(static_cast<uint64_t>(16 + 64)));
}
AssertThat(filesystem::file_size(filename),
Equals(sizeof(uint64_t) * 2));
filesystem::delete_file(filename);
});
it("should correctly extract single bits", [&]() {
auto alternating_ones
= static_cast<uint64_t>(0xaaaaaaaaaaaaaaaaULL);
auto sizes = {16, 8, 64, 2, 16, 32, 4};
uint64_t total_size
= std::accumulate(sizes.begin(), sizes.end(), 0ull);
{
std::ofstream output{filename, std::ios::binary};
auto builder = make_bit_vector_builder(output);
for (const auto& size : sizes)
builder.write_bits(
{alternating_ones, static_cast<uint8_t>(size)});
AssertThat(builder.total_bits(), Equals(total_size));
}
AssertThat(filesystem::file_size(filename),
Equals(sizeof(uint64_t)
* math::integer::div_ceil(total_size, 64)));
{
util::disk_vector<uint64_t> storage{filename};
util::array_view<const uint64_t> av{storage.begin(),
storage.end()};
bit_vector_view bvv{av, total_size};
for (std::size_t i = 0; i < total_size; ++i) {
auto bit = bvv[i];
if (i % 2 == 0) {
AssertThat(bit, Equals(0));
} else {
AssertThat(bit, Equals(1));
}
}
}
filesystem::delete_file(filename);
});
it("should correctly extract multi-bit patterns", [&]() {
uint64_t deadbeef = 0xdeadbeefULL;
auto sizes = {32, 16, 64, 38, 32, 64, 8, 1, 2, 3, 7, 9};
uint64_t total_size
= std::accumulate(sizes.begin(), sizes.end(), 0ull);
{
std::ofstream output{filename, std::ios::binary};
auto builder = make_bit_vector_builder(output);
for (const auto& size : sizes)
builder.write_bits({deadbeef, static_cast<uint8_t>(size)});
AssertThat(builder.total_bits(), Equals(total_size));
}
AssertThat(filesystem::file_size(filename),
Equals(sizeof(uint64_t)
* math::integer::div_ceil(total_size, 64)));
{
util::disk_vector<uint64_t> storage{filename};
util::array_view<const uint64_t> av{storage.begin(),
storage.end()};
bit_vector_view bvv{av, total_size};
uint64_t pos = 0;
for (const auto& sze : sizes) {
auto size = static_cast<uint8_t>(sze);
auto result = bvv.extract(pos, size);
auto mask = size == 64 ? static_cast<uint64_t>(-1)
: (1ull << size) - 1;
AssertThat(result, Equals(deadbeef & mask));
pos += size;
}
}
filesystem::delete_file(filename);
});
});
});