Skip to content

Commit

Permalink
types: Fix encoding of negative varint
Browse files Browse the repository at this point in the history
We would sometimes produce an unnecessary extra 0xff prefix byte.

The new encoding matches what cassandra does.

This was both a efficiency and correctness issue, as using varint in a
key could produce different tokens.

Fixes #5656

Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
(cherry picked from commit c89c90d)
  • Loading branch information
espindola authored and avikivity committed Feb 2, 2020
1 parent c36f71c commit 1bbe619
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
2 changes: 2 additions & 0 deletions test/boost/types_test.cc
Expand Up @@ -415,6 +415,8 @@ BOOST_AUTO_TEST_CASE(test_varint) {
BOOST_CHECK_EQUAL(value_cast<boost::multiprecision::cpp_int>(varint_type->deserialize(from_hex("00deadbeef"))), boost::multiprecision::cpp_int("0xdeadbeef"));
BOOST_CHECK_EQUAL(value_cast<boost::multiprecision::cpp_int>(varint_type->deserialize(from_hex("00ffffffffffffffffffffffffffffffff"))), boost::multiprecision::cpp_int("340282366920938463463374607431768211455"));

BOOST_REQUIRE_EQUAL(from_hex("80000000"), varint_type->decompose(boost::multiprecision::cpp_int(-2147483648)));

test_parsing_fails(varint_type, "1A");
}

Expand Down
15 changes: 11 additions & 4 deletions types.cc
Expand Up @@ -2082,12 +2082,19 @@ static size_t concrete_serialized_size(const string_type_impl::native_type& v) {
static size_t concrete_serialized_size(const bytes_type_impl::native_type& v) { return v.size(); }
static size_t concrete_serialized_size(const inet_addr_type_impl::native_type& v) { return v.get().size(); }

static size_t concrete_serialized_size(const boost::multiprecision::cpp_int& num) {
if (!num) {
static size_t concrete_serialized_size_aux(const boost::multiprecision::cpp_int& num) {
if (num) {
return align_up(boost::multiprecision::msb(num) + 2, 8u) / 8;
} else {
return 1;
}
auto pnum = abs(num);
return align_up(boost::multiprecision::msb(pnum) + 2, 8u) / 8;
}

static size_t concrete_serialized_size(const boost::multiprecision::cpp_int& num) {
if (num < 0) {
return concrete_serialized_size_aux(-num - 1);
}
return concrete_serialized_size_aux(num);
}

static size_t concrete_serialized_size(const varint_type_impl::native_type& v) {
Expand Down

0 comments on commit 1bbe619

Please sign in to comment.