Skip to content

Commit 7110e80

Browse files
authored
Merge pull request #138 from gustingonzalez/fix/s16-s8b-unknown-len-check
Fix debug assert in Simple8b and Simple16 when input lenght is unknown (0)
2 parents abe46ae + cead076 commit 7110e80

File tree

7 files changed

+85
-3
lines changed

7 files changed

+85
-3
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ if(FASTPFOR_WITH_TEST)
173173
unittest/test_composite.cpp
174174
unittest/test_driver.cpp
175175
unittest/test_fastpfor.cpp
176+
unittest/test_simple8b.cpp
177+
unittest/test_simple16.cpp
176178
unittest/test_variablebyte.cpp)
177179
target_link_libraries(FastPFOR_unittest gtest FastPFOR)
178180
enable_testing()

headers/codecs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class IntegerCODEC {
5353
* of the variable nvalue gets updated with the number actually use
5454
* (if nvalue exceeds the original value, there might be a buffer
5555
* overrun).
56+
*
57+
* NOTE: Decoding can be performed with an unknown input length. This
58+
* case is indicated by a length of 0; however, nvalue must be provided
59+
* in order for the decoder knows how many values to decode.
5660
*/
5761
virtual const uint32_t *decodeArray(const uint32_t *in, const size_t length,
5862
uint32_t *out, size_t &nvalue) = 0;

headers/simple16.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ const uint32_t *Simple16<MarkLength>::decodeArray(const uint32_t *in,
745745
printf("simple16 stats[%u]=%f\n", k, stats[k] * 1.0 / sum);
746746
}
747747
#endif
748-
ASSERT(in <= endin, std::to_string(in - endin));
748+
ASSERT(len == 0 || in <= endin, std::to_string(in - endin));
749749
return in;
750750
}
751751

headers/simple8b.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,9 @@ const uint32_t *Simple8b<MarkLength>::decodeArray(const uint32_t *in,
637637
printf("simple8b stats[%u]=%f\n", k, stats[k] * 1.0 / sum);
638638
}
639639
#endif
640-
assert(in64 <= finalin64);
640+
assert(len == 0 || in64 <= finalin64);
641641
in = reinterpret_cast<const uint32_t *>(in64);
642-
assert(in <= endin);
642+
assert(len == 0 || in <= endin);
643643
// check that we don't overrun the buffer too much?
644644
ASSERT(out < end + 240, std::to_string(out - end));
645645
nvalue = MarkLength ? actualvalue : out - initout;

unittest/test_simple16.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <vector>
2+
3+
#include "simple16.h"
4+
#include "util.h"
5+
6+
namespace FastPForLib {
7+
8+
TEST(Simple16Test, DecodesWithUnknownLength) {
9+
Simple16<false> codec;
10+
std::vector<uint32_t> in;
11+
for (uint32_t i = 0; i < 128; ++i) {
12+
in.push_back(i);
13+
}
14+
15+
// Simple16 may overrun the output buffer regardless of `n`, so a headroom of
16+
// 28 (the maximum number of elements in a single pack) is added.
17+
std::vector<uint32_t> decoded(in.size() + 28, 0);
18+
verifyUnknownInputLengthDecode(codec, in, decoded);
19+
}
20+
} // namespace FastPForLib

unittest/test_simple8b.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <vector>
2+
3+
#include "simple8b.h"
4+
#include "util.h"
5+
6+
namespace FastPForLib {
7+
8+
TEST(Simple8bTest, DecodesWithUnknownLength) {
9+
Simple8b<false> codec;
10+
std::vector<uint32_t> in;
11+
for (uint32_t i = 0; i < 128; ++i) {
12+
in.push_back(i);
13+
}
14+
15+
std::vector<uint32_t> decoded(in.size(), 0);
16+
verifyUnknownInputLengthDecode(codec, in, decoded);
17+
}
18+
} // namespace FastPForLib

unittest/util.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef FASTPFORLIB_UTIL_H_
2+
#define FASTPFORLIB_UTIL_H_
3+
4+
#include <vector>
5+
6+
#include "gtest/gtest.h"
7+
8+
namespace FastPForLib {
9+
10+
template <class Codec>
11+
void verifyUnknownInputLengthDecode(Codec &codec,
12+
const std::vector<uint32_t> &in,
13+
std::vector<uint32_t> &decoded) {
14+
std::vector<uint32_t> encoded(in.size() * 2, 0);
15+
size_t encodedSize;
16+
codec.encodeArray(in.data(), in.size(), encoded.data(), encodedSize);
17+
encoded.resize(encodedSize);
18+
19+
size_t n = in.size();
20+
const uint32_t *decodedUntil =
21+
codec.decodeArray(encoded.data(), 0, decoded.data(), n);
22+
decoded.resize(n);
23+
24+
// Check that the decoded size matches the input size.
25+
EXPECT_EQ(n, in.size());
26+
27+
// Check that the returned pointer matches the end of the encoded buffer.
28+
EXPECT_EQ(decodedUntil, encoded.data() + encodedSize);
29+
30+
// Check each decoded element matches its corresponding input value.
31+
for (size_t i = 0; i < in.size(); ++i) {
32+
EXPECT_EQ(in[i], decoded[i]);
33+
}
34+
}
35+
36+
} // namespace FastPForLib
37+
38+
#endif // FASTPFORLIB_UTIL_H_

0 commit comments

Comments
 (0)