Skip to content

Commit

Permalink
Fix for 32 bit archs for encoded Arrays (#7427)
Browse files Browse the repository at this point in the history
* tentative fix for 32 bit archs
* removed wrong cast to size_t from bf_iterator::set_value()
* fix inverted condition in 'unsigned_to_num_bits'
* fix inverted condition in 'unsigned_to_num_bits'

---------

Co-authored-by: Nicola Cabiddu <nicola.cabiddu@mongodb.com>
  • Loading branch information
finnschiermer and nicola-cab authored Mar 7, 2024
1 parent e7add60 commit f06e45d
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 22 deletions.
10 changes: 5 additions & 5 deletions src/realm/array_direct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,9 @@ class bf_iterator {
{
auto in_word_position = field_position & 0x3F;
auto first_word = first_word_ptr[0];
uint64_t mask = 0 - 1ULL;
uint64_t mask = 0ULL - 1ULL;
if (field_size < 64) {
mask = static_cast<size_t>((1ULL << field_size) - 1);
mask = (1ULL << field_size) - 1;
value &= mask;
}
// zero out field in first word:
Expand Down Expand Up @@ -389,16 +389,16 @@ inline void write_bitfield(uint64_t* data_area, size_t field_position, size_t wi
*it = value;
}

inline int64_t sign_extend_field_by_mask(size_t sign_mask, uint64_t value)
inline int64_t sign_extend_field_by_mask(uint64_t sign_mask, uint64_t value)
{
uint64_t sign_extension = 0 - (value & sign_mask);
uint64_t sign_extension = 0ULL - (value & sign_mask);
return value | sign_extension;
}

inline int64_t sign_extend_value(size_t width, uint64_t value)
{
uint64_t sign_mask = 1ULL << (width - 1);
uint64_t sign_extension = 0 - (value & sign_mask);
uint64_t sign_extension = 0ULL - (value & sign_mask);
return value | sign_extension;
}

Expand Down
7 changes: 3 additions & 4 deletions src/realm/array_encode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ArrayEncode {
// init from mem B
inline size_t size() const;
inline size_t width() const;
inline size_t width_mask() const;
inline uint64_t width_mask() const;
inline NodeHeader::Encoding get_encoding() const;

// get/set
Expand Down Expand Up @@ -71,8 +71,7 @@ class ArrayEncode {
using Encoding = NodeHeader::Encoding;
Encoding m_encoding{NodeHeader::Encoding::WTypBits}; // this is not ok .... probably
size_t m_v_width = 0, m_v_size = 0, m_ndx_width = 0, m_ndx_size = 0;
size_t m_v_mask = 0;
size_t m_ndx_mask = 0;
uint64_t m_v_mask = 0, m_ndx_mask = 0;

friend class ArrayPacked;
friend class ArrayFlex;
Expand All @@ -93,7 +92,7 @@ inline size_t ArrayEncode::width() const
return m_v_width;
}

inline size_t ArrayEncode::width_mask() const
inline uint64_t ArrayEncode::width_mask() const
{
return m_v_mask;
}
Expand Down
6 changes: 3 additions & 3 deletions src/realm/array_flex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ int64_t ArrayFlex::get(const Array& arr, size_t ndx) const
}

int64_t ArrayFlex::get(const char* data, size_t ndx, size_t v_width, size_t v_size, size_t ndx_width, size_t ndx_size,
size_t mask) const
uint64_t mask) const
{
return do_get((uint64_t*)data, ndx, v_width, v_size, ndx_width, ndx_size, mask);
}

int64_t ArrayFlex::do_get(uint64_t* data, size_t ndx, size_t v_width, size_t ndx_width, size_t v_size,
size_t ndx_size, size_t mask) const
size_t ndx_size, uint64_t mask) const
{
if (ndx >= ndx_size)
return realm::not_found;
Expand Down Expand Up @@ -176,7 +176,7 @@ bool ArrayFlex::find_all(const Array& arr, int64_t value, size_t start, size_t e
}

template <typename Cond, bool v>
inline size_t ArrayFlex::parallel_subword_find(const Array& arr, uint64_t value, size_t width_mask, size_t offset,
inline size_t ArrayFlex::parallel_subword_find(const Array& arr, uint64_t value, uint64_t width_mask, size_t offset,
uint_least8_t width, size_t start, size_t end) const
{
const auto MSBs = populate(width, width_mask);
Expand Down
9 changes: 4 additions & 5 deletions src/realm/array_flex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ class ArrayFlex {
// encoding/decoding
void init_array(char* h, uint8_t flags, size_t v_width, size_t ndx_width, size_t v_size, size_t ndx_size) const;
void copy_data(const Array&, const std::vector<int64_t>&, const std::vector<size_t>&) const;
std::vector<int64_t> fetch_all_values(const Array& h) const;
// getters/setters
int64_t get(const Array&, size_t) const;
int64_t get(const char*, size_t, size_t, size_t, size_t, size_t, size_t) const;
int64_t get(const char*, size_t, size_t, size_t, size_t, size_t, uint64_t) const;
void get_chunk(const Array& h, size_t ndx, int64_t res[8]) const;
void set_direct(const Array&, size_t, int64_t) const;

Expand All @@ -46,11 +45,11 @@ class ArrayFlex {
int64_t sum(const Array&, size_t, size_t) const;

private:
int64_t do_get(uint64_t*, size_t, size_t, size_t, size_t, size_t, size_t) const;
int64_t do_get(uint64_t*, size_t, size_t, size_t, size_t, size_t, uint64_t) const;
bool find_all_match(size_t start, size_t end, size_t baseindex, QueryStateBase* state) const;

template <typename Cond, bool = true> // true int64_t other uint64_t
inline size_t parallel_subword_find(const Array&, uint64_t, size_t, size_t, uint_least8_t, size_t, size_t) const;
template <typename Cond, bool = true> // true int64_t, false uint64_t
inline size_t parallel_subword_find(const Array&, uint64_t, uint64_t, size_t, uint_least8_t, size_t, size_t) const;

bool find_eq(const Array&, int64_t, size_t, size_t, size_t, QueryStateBase*) const;
bool find_neq(const Array&, int64_t, size_t, size_t, size_t, QueryStateBase*) const;
Expand Down
4 changes: 2 additions & 2 deletions src/realm/array_packed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ int64_t ArrayPacked::get(const Array& arr, size_t ndx) const
return do_get((uint64_t*)arr.m_data, ndx, w, sz, arr.get_encoder().width_mask());
}

int64_t ArrayPacked::get(const char* data, size_t ndx, size_t width, size_t sz, size_t mask) const
int64_t ArrayPacked::get(const char* data, size_t ndx, size_t width, size_t sz, uint64_t mask) const
{
return do_get((uint64_t*)data, ndx, width, sz, mask);
}

int64_t ArrayPacked::do_get(uint64_t* data, size_t ndx, size_t v_width, size_t v_size, size_t mask) const
int64_t ArrayPacked::do_get(uint64_t* data, size_t ndx, size_t v_width, size_t v_size, uint64_t mask) const
{
if (ndx >= v_size)
return realm::not_found;
Expand Down
4 changes: 2 additions & 2 deletions src/realm/array_packed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ArrayPacked {
void copy_data(const Array&, Array&) const;
// get or set
int64_t get(const Array&, size_t) const;
int64_t get(const char*, size_t, size_t, size_t, size_t) const;
int64_t get(const char*, size_t, size_t, size_t, uint64_t) const;
void get_chunk(const Array&, size_t, int64_t res[8]) const;
void set_direct(const Array&, size_t, int64_t) const;

Expand All @@ -46,7 +46,7 @@ class ArrayPacked {
int64_t sum(const Array&, size_t, size_t) const;

private:
int64_t do_get(uint64_t*, size_t, size_t, size_t, size_t) const;
int64_t do_get(uint64_t*, size_t, size_t, size_t, uint64_t) const;
bool find_all_match(size_t start, size_t end, size_t baseindex, QueryStateBase* state) const;

template <typename Cond>
Expand Down
10 changes: 9 additions & 1 deletion src/realm/node_header.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,15 @@ class NodeHeader {

static size_t unsigned_to_num_bits(uint64_t value)
{
return 1 + log2(static_cast<size_t>(value));
if constexpr (sizeof(size_t) == sizeof(uint64_t))
return 1 + log2(value);
uint32_t high = value >> 32;
if (high)
return 33 + log2(high);
uint32_t low = value & 0xFFFFFFFFUL;
if (low)
return 1 + log2(low);
return 0;
}

static size_t signed_to_num_bits(int64_t value)
Expand Down

0 comments on commit f06e45d

Please sign in to comment.