Skip to content

Commit 0f13c79

Browse files
authored
Improve block codecs (#492)
* Remove unnecessary variable * Replace uint32_t(-1) with numeric_limits * Use array instead of vector for buffer in codecs
1 parent 67b5200 commit 0f13c79

File tree

8 files changed

+48
-26
lines changed

8 files changed

+48
-26
lines changed

Diff for: include/pisa/block_freq_index.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class block_freq_index {
257257
void build(std::string const& index_path)
258258
{
259259
std::ofstream os(index_path.c_str());
260+
std::cout << index_path.c_str() << "\n";
260261
os.exceptions(std::ios::badbit | std::ios::failbit);
261262
mapper::detail::freeze_visitor freezer(os, 0);
262263
freezer(m_params, "m_params");

Diff for: include/pisa/codec/block_codecs.hpp

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <array>
4+
35
#include "FastPFor/headers/optpfor.h"
46
#include "FastPFor/headers/variablebyte.h"
57

@@ -121,13 +123,14 @@ class TightVariableByte {
121123
};
122124

123125
struct interpolative_block {
124-
static const uint64_t block_size = 128;
126+
static constexpr std::uint64_t block_size = 128;
125127

126128
static void encode(uint32_t const* in, uint32_t sum_of_values, size_t n, std::vector<uint8_t>& out)
127129
{
128130
assert(n <= block_size);
129-
thread_local std::vector<uint32_t> inbuf(block_size);
130-
thread_local std::vector<uint32_t> outbuf;
131+
thread_local std::array<std::uint32_t, block_size> inbuf{};
132+
thread_local std::vector<uint32_t> outbuf; // TODO: Can we use array? How long does it need
133+
// to be?
131134
inbuf[0] = *in;
132135
for (size_t i = 1; i < n; ++i) {
133136
inbuf[i] = inbuf[i - 1] + in[i];
@@ -148,23 +151,22 @@ struct interpolative_block {
148151
decode(uint8_t const* in, uint32_t* out, uint32_t sum_of_values, size_t n)
149152
{
150153
assert(n <= block_size);
151-
uint8_t const* inbuf = in;
152-
if (sum_of_values == uint32_t(-1)) {
153-
inbuf = TightVariableByte::decode(inbuf, &sum_of_values, 1);
154+
if (sum_of_values == std::numeric_limits<std::uint32_t>::max()) {
155+
in = TightVariableByte::decode(in, &sum_of_values, 1);
154156
}
155157

156158
out[n - 1] = sum_of_values;
157159
size_t read_interpolative = 0;
158160
if (n > 1) {
159-
bit_reader br(inbuf);
161+
bit_reader br(in);
160162
br.read_interpolative(out, n - 1, 0, sum_of_values);
161163
for (size_t i = n - 1; i > 0; --i) {
162164
out[i] -= out[i - 1];
163165
}
164166
read_interpolative = ceil_div(br.position(), 8);
165167
}
166168

167-
return inbuf + read_interpolative;
169+
return in + read_interpolative;
168170
}
169171
};
170172

@@ -214,7 +216,7 @@ struct optpfor_block {
214216
uint8_t const* b = nullptr) // if non-null forces b
215217
{
216218
thread_local codec_type optpfor_codec;
217-
thread_local std::vector<uint8_t> buf(2 * 4 * block_size);
219+
thread_local std::array<std::uint8_t, 2 * 4 * block_size> buf{};
218220
assert(n <= block_size);
219221

220222
if (n < block_size) {
@@ -284,7 +286,7 @@ struct varint_G8IU_block {
284286
static void encode(uint32_t const* in, uint32_t sum_of_values, size_t n, std::vector<uint8_t>& out)
285287
{
286288
thread_local codec_type varint_codec;
287-
thread_local std::vector<uint8_t> buf(2 * 4 * block_size);
289+
thread_local std::array<std::uint8_t, 2 * 4 * block_size> buf{};
288290
assert(n <= block_size);
289291

290292
if (n < block_size) {

Diff for: include/pisa/codec/maskedvbyte.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace pisa {
1111
struct maskedvbyte_block {
12-
static const uint64_t block_size = 128;
12+
static constexpr std::uint64_t block_size = 128;
1313
static void encode(uint32_t const* in, uint32_t sum_of_values, size_t n, std::vector<uint8_t>& out)
1414
{
1515
assert(n <= block_size);
@@ -18,7 +18,7 @@ struct maskedvbyte_block {
1818
interpolative_block::encode(src, sum_of_values, n, out);
1919
return;
2020
}
21-
thread_local std::vector<uint8_t> buf(2 * block_size * sizeof(uint32_t));
21+
thread_local std::array<std::uint8_t, 2 * block_size * sizeof(std::uint32_t)> buf{};
2222
size_t out_len = vbyte_encode(src, n, buf.data());
2323
out.insert(out.end(), buf.data(), buf.data() + out_len);
2424
}

Diff for: include/pisa/codec/qmx.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
namespace pisa {
77
struct qmx_block {
8-
static const uint64_t block_size = 128;
9-
static const uint64_t overflow = 512;
8+
static constexpr std::uint64_t block_size = 128;
9+
static constexpr std::uint64_t overflow = 512;
1010

1111
static void encode(uint32_t const* in, uint32_t sum_of_values, size_t n, std::vector<uint8_t>& out)
1212
{
@@ -17,7 +17,7 @@ struct qmx_block {
1717
return;
1818
}
1919
thread_local QMX::compress_integer_qmx_improved qmx_codec;
20-
thread_local std::vector<uint8_t> buf(2 * n * sizeof(uint32_t) + overflow);
20+
thread_local std::vector<std::uint8_t> buf(2 * n * sizeof(uint32_t) + overflow);
2121

2222
size_t out_len = qmx_codec.encode(buf.data(), buf.size(), in, n);
2323
TightVariableByte::encode_single(out_len, out);

Diff for: include/pisa/codec/simple16.hpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#pragma once
22
#include "FastPFor/headers/simple16.h"
33

4+
#include <array>
5+
46
namespace pisa {
57

68
struct simple16_block {
7-
static const uint64_t block_size = 128;
9+
static constexpr std::uint64_t block_size = 128;
810

911
static void
1012
encode(uint32_t const* in, uint32_t /* sum_of_values */, size_t n, std::vector<uint8_t>& out)
1113
{
1214
assert(n <= block_size);
1315
thread_local FastPForLib::Simple16<false> codec;
14-
thread_local std::vector<uint8_t> buf(2 * 8 * block_size);
16+
thread_local std::array<std::uint8_t, 2 * 8 * block_size> buf{};
1517
size_t out_len = buf.size();
1618
codec.encodeArray(in, n, reinterpret_cast<uint32_t*>(buf.data()), out_len);
1719
out_len *= 4;
@@ -23,14 +25,14 @@ struct simple16_block {
2325
{
2426
assert(n <= block_size);
2527
FastPForLib::Simple16<false> codec;
26-
std::vector<uint32_t> buf(2 * block_size);
28+
std::array<std::uint32_t, 2 * block_size> buf{};
2729

2830
auto const* ret = reinterpret_cast<uint8_t const*>(
2931
codec.decodeArray(reinterpret_cast<uint32_t const*>(in), 8 * n, buf.data(), n));
30-
for (size_t i = 0; i < n; ++i) {
31-
*out++ = buf[i];
32-
}
32+
33+
std::copy(buf.begin(), std::next(buf.begin(), n), out);
3334
return ret;
3435
}
3536
};
37+
3638
} // namespace pisa

Diff for: include/pisa/codec/simple8b.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
#pragma once
22
#include "FastPFor/headers/simple8b.h"
33

4+
#include <array>
5+
46
namespace pisa {
57

68
struct simple8b_block {
7-
static const uint64_t block_size = 128;
9+
static constexpr std::uint64_t block_size = 128;
810

911
static void
1012
encode(uint32_t const* in, uint32_t /* sum_of_values */, size_t n, std::vector<uint8_t>& out)
1113
{
1214
assert(n <= block_size);
1315
thread_local FastPForLib::Simple8b<false> codec;
14-
thread_local std::vector<uint8_t> buf(2 * 8 * block_size);
16+
thread_local std::array<std::uint8_t, 2 * 8 * block_size> buf{};
1517
size_t out_len = buf.size();
1618
codec.encodeArray(in, n, reinterpret_cast<uint32_t*>(buf.data()), out_len);
1719
out_len *= 4;

Diff for: include/pisa/codec/streamvbyte.hpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
#pragma once
22

3+
#include <array>
34
#include <cassert>
5+
#include <cstdint>
46
#include <vector>
57

68
#include "streamvbyte/include/streamvbyte.h"
79

810
namespace pisa {
911

12+
// This is a constexpr version of the function in the streamvbyte library.
13+
constexpr std::size_t streamvbyte_max_compressedbytes(std::uint32_t length)
14+
{
15+
// number of control bytes:
16+
size_t cb = (length + 3) / 4;
17+
// maximum number of control bytes:
18+
size_t db = (size_t)length * sizeof(uint32_t);
19+
return cb + db;
20+
}
21+
1022
struct streamvbyte_block {
1123
static const uint64_t block_size = 128;
1224
static void
1325
encode(uint32_t const* in, uint32_t /* sum_of_values */, size_t n, std::vector<uint8_t>& out)
1426
{
1527
assert(n <= block_size);
1628
auto* src = const_cast<uint32_t*>(in);
17-
thread_local std::vector<uint8_t> buf(streamvbyte_max_compressedbytes(block_size));
29+
thread_local std::array<std::uint8_t, pisa::streamvbyte_max_compressedbytes(block_size)> buf{};
1830
size_t out_len = streamvbyte_encode(src, n, buf.data());
1931
out.insert(out.end(), buf.data(), buf.data() + out_len);
2032
}

Diff for: include/pisa/codec/varintgb.hpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#pragma once
2-
#include "codec/block_codecs.hpp"
2+
3+
#include <array>
34
#include <vector>
45

56
#include "FastPFor/headers/common.h"
67

8+
#include "codec/block_codecs.hpp"
9+
710
using namespace std;
811

912
namespace pisa {
@@ -252,7 +255,7 @@ struct varintgb_block {
252255
interpolative_block::encode(in, sum_of_values, n, out);
253256
return;
254257
}
255-
thread_local std::vector<uint8_t> buf(2 * block_size * sizeof(uint32_t));
258+
thread_local std::array<std::uint8_t, 2 * block_size * sizeof(uint32_t)> buf{};
256259
size_t out_len = varintgb_codec.encodeArray(in, n, buf.data());
257260
out.insert(out.end(), buf.data(), buf.data() + out_len);
258261
}

0 commit comments

Comments
 (0)