Skip to content

Commit

Permalink
work on interface
Browse files Browse the repository at this point in the history
  • Loading branch information
drexlerd committed Feb 12, 2024
1 parent a1b619f commit 9459449
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 66 deletions.
93 changes: 85 additions & 8 deletions include/flatmemory/details/types/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,37 @@ namespace flatmemory
assert(m_buf);
}

[[nodiscard]] bool operator==(const View& other) const
{
// Fetch data
const auto &blocks = get_blocks();
bool default_bit_value = get_default_bit_value();
const auto &other_blocks = other.get_blocks();
bool other_default_bit_value = other.get_default_bit_value();

std::size_t common_size = std::min(blocks.size(), other_blocks.size());
if (std::memcmp(blocks.data(), other_blocks.data(), common_size * sizeof(Block)) != 0) return false;

std::size_t max_size = std::max(blocks.size(), other_blocks.size());

for (std::size_t index = common_size; index < max_size; ++index)
{
Block this_value = index < blocks.size() ? blocks[index] : (default_bit_value ? block_ones : block_zeroes);
Block other_value = index < other_blocks.size() ? other_blocks[index] : (other_default_bit_value ? block_ones : block_zeroes);

if (this_value != other_value)
{
return false;
}
}

return true;
}

[[nodiscard]] bool operator!=(const View& other) const {
return !(*this == other);
}

[[nodiscard]] size_t buffer_size() const
{
assert(m_buf);
Expand All @@ -125,12 +156,25 @@ namespace flatmemory
return read_value<bool>(m_buf + Layout<Bitset<Block>>::default_bit_value_position);
}

[[nodiscard]] const bool& get_default_bit_value() const
{
assert(m_buf);
assert(test_correct_alignment<bool>(m_buf + Layout<Bitset<Block>>::default_bit_value_position));
return read_value<bool>(m_buf + Layout<Bitset<Block>>::default_bit_value_position);
}

[[nodiscard]] View<Vector<Block>> get_blocks()
{
assert(m_buf);
return View<Vector<Block>>(m_buf + Layout<Bitset<Block>>::blocks_position);
}

[[nodiscard]] ConstView<Vector<Block>> get_blocks() const
{
assert(m_buf);
return ConstView<Vector<Block>>(m_buf + Layout<Bitset<Block>>::blocks_position);
}

[[nodiscard]] size_t hash() const
{
const bool default_bit_value = get_default_bit_value();
Expand Down Expand Up @@ -184,6 +228,41 @@ namespace flatmemory
assert(m_buf);
}

/**
* Operators
*/

[[nodiscard]] bool operator==(const ConstView& other) const
{
// Fetch data
const auto &blocks = get_blocks();
bool default_bit_value = get_default_bit_value();
const auto &other_blocks = other.get_blocks();
bool other_default_bit_value = other.get_default_bit_value();

std::size_t common_size = std::min(blocks.size(), other_blocks.size());
if (std::memcmp(blocks.data(), other_blocks.data(), common_size * sizeof(Block)) != 0) return false;

std::size_t max_size = std::max(blocks.size(), other_blocks.size());

for (std::size_t index = common_size; index < max_size; ++index)
{
Block this_value = index < blocks.size() ? blocks[index] : (default_bit_value ? block_ones : block_zeroes);
Block other_value = index < other_blocks.size() ? other_blocks[index] : (other_default_bit_value ? block_ones : block_zeroes);

if (this_value != other_value)
{
return false;
}
}

return true;
}

[[nodiscard]] bool operator!=(const ConstView& other) const {
return !(*this == other);
}

[[nodiscard]] size_t buffer_size() const
{
assert(m_buf);
Expand Down Expand Up @@ -373,14 +452,7 @@ namespace flatmemory
bool other_default_bit_value = other.get_default_bit_value();

std::size_t common_size = std::min(m_blocks.size(), other_blocks.size());

for (std::size_t index = 0; index < common_size; ++index)
{
if (m_blocks[index] != other_blocks[index])
{
return false;
}
}
if (std::memcmp(m_blocks.data(), other_blocks.data(), common_size * sizeof(Block)) != 0) return false;

std::size_t max_size = std::max(m_blocks.size(), other_blocks.size());

Expand All @@ -398,6 +470,11 @@ namespace flatmemory
return true;
}

template <IsBitset Other>
[[nodiscard]] bool operator!=(const Other& other) const {
return !(*this == other);
}


/**
* Modifiers
Expand Down
54 changes: 9 additions & 45 deletions include/flatmemory/details/types/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,21 +224,9 @@ namespace flatmemory
/**
* Operators
*/
template<size_t... Is>
[[nodiscard]] bool are_equal_helper(std::index_sequence<Is...>, const Builder& other) const {
bool are_equal = true;
([&] {
if (this->get<Is>() != other.get<Is>()) {
are_equal = false;
return;
}
}(), ...);
return are_equal;
}

[[nodiscard]] bool operator==(const Builder& other) const {
if (this != &other) {
return are_equal_helper(std::make_index_sequence<sizeof...(Ts)>{}, other);
return m_data == other.m_data;
}
return true;
}
Expand Down Expand Up @@ -373,23 +361,11 @@ namespace flatmemory
}
}


template<size_t... Is>
[[nodiscard]] size_t hash_helper(std::index_sequence<Is...>) const {
size_t seed = Layout<Tuple<Ts...>>::size;
([&] {
constexpr bool is_trivial = IsTriviallyCopyable<element_type<Is>>;
if constexpr (is_trivial) {
hash_combine(seed, std::hash<element_type<Is>>()(get<Is>()));
} else {
hash_combine(seed, get<Is>().hash());
}
}(), ...);
return seed;
}

[[nodiscard]] size_t hash() const {
return hash_helper(std::make_index_sequence<sizeof...(Ts)>{});
size_t seed = Layout<Tuple<Ts...>>::size;
int64_t hash[2];
MurmurHash3_x64_128(m_buf, buffer_size(), seed, hash);
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
}
};

Expand Down Expand Up @@ -474,23 +450,11 @@ namespace flatmemory
return read_value<buffer_size_type>(m_buf + Layout<Tuple<Ts...>>::layout_data.buffer_size_position);
}


template<size_t... Is>
[[nodiscard]] size_t hash_helper(std::index_sequence<Is...>) const {
size_t seed = Layout<Tuple<Ts...>>::size;
([&] {
constexpr bool is_trivial = IsTriviallyCopyable<element_type<Is>>;
if constexpr (is_trivial) {
hash_combine(seed, std::hash<element_type<Is>>()(get<Is>()));
} else {
hash_combine(seed, get<Is>().hash());
}
}(), ...);
return seed;
}

[[nodiscard]] size_t hash() const {
return hash_helper(std::make_index_sequence<sizeof...(Ts)>{});
size_t seed = Layout<Tuple<Ts...>>::size;
int64_t hash[2];
MurmurHash3_x64_128(m_buf, buffer_size(), seed, hash);
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
}
};
}
Expand Down
30 changes: 24 additions & 6 deletions include/flatmemory/details/types/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "../view_const.hpp"
#include "../view.hpp"
#include "../type_traits.hpp"
#include "../algorithms/hash.hpp"
#include "../algorithms/murmurhash3.hpp"

#include <algorithm>
Expand Down Expand Up @@ -164,8 +165,7 @@ namespace flatmemory

[[nodiscard]] bool operator==(const Builder& other) const {
if (this != &other) {
if (m_buffer.size() != other.m_buffer.size()) return false;
return std::memcmp(m_buffer.data(), other.m_buffer.data(), m_buffer.size()) == 0;
return m_data == other.m_data;
}
return true;
}
Expand All @@ -189,12 +189,21 @@ namespace flatmemory
}

[[nodiscard]] size_t hash() const {
size_t seed = size();
int64_t hash[2];
MurmurHash3_x64_128(m_buffer.data(), m_buffer.size(), seed, hash);
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
constexpr bool is_trivial = IsTriviallyCopyable<T>;
if constexpr (is_trivial) {
return hash_combine(hash_container(m_data));
} else {
size_t seed = size();
for (const auto& builder : m_data) {
hash_combine(seed, builder.hash());
}
return seed;
}
}

[[nodiscard]] T_* data() { return m_data.data(); }
[[nodiscard]] const T_* data() const { return m_data.data(); }


/**
* Iterators
Expand Down Expand Up @@ -241,6 +250,8 @@ namespace flatmemory
class View<Vector<T>>
{
private:
using T_ = typename maybe_builder<T>::type;

uint8_t* m_buf;

/// @brief Default constructor to make view a trivial data type and serializable
Expand Down Expand Up @@ -311,6 +322,9 @@ namespace flatmemory
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
}

[[nodiscard]] T_* data() { return reinterpret_cast<T_*>(m_buf + Layout<Vector<T>>::vector_data_position); }
[[nodiscard]] const T_* data() const { return reinterpret_cast<const T_*>(m_buf + Layout<Vector<T>>::vector_data_position); }


/**
* Iterators
Expand Down Expand Up @@ -426,6 +440,8 @@ namespace flatmemory
class ConstView<Vector<T>>
{
private:
using T_ = typename maybe_builder<T>::type;

const uint8_t* m_buf;

/// @brief Default constructor to make view a trivial data type and serializable
Expand Down Expand Up @@ -483,6 +499,8 @@ namespace flatmemory
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
}

[[nodiscard]] const T_* data() const { return reinterpret_cast<const T_*>(m_buf + Layout<Vector<T>>::vector_data_position); }


/**
* Iterators
Expand Down
57 changes: 57 additions & 0 deletions tests/unit/types/bitset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,5 +163,62 @@ TEST(FlatmemoryTests, TypesBitsetNotTest) {
}


TEST(FlatmemoryTests, TypesBitsetEqualityTest) {
using BitsetLayout = Bitset<uint64_t>;

auto builder1 = Builder<BitsetLayout>(3);
builder1.get_default_bit_value() = false;
builder1.set(1);
builder1.finish();

auto builder2 = Builder<BitsetLayout>(3);
builder2.get_default_bit_value() = false;
builder2.set(1);
builder2.finish();

auto builder3 = Builder<BitsetLayout>(3);
builder3.get_default_bit_value() = false;
builder3.finish();

EXPECT_TRUE((builder1 == builder2));
EXPECT_EQ(builder1.hash(), builder2.hash());

EXPECT_FALSE((builder1 == builder3));
EXPECT_NE(builder1.hash(), builder3.hash());

EXPECT_FALSE((builder2 == builder3));
EXPECT_NE(builder2.hash(), builder3.hash());


auto view1 = View<BitsetLayout>(builder1.buffer().data());
auto view2 = View<BitsetLayout>(builder2.buffer().data());
auto view3 = View<BitsetLayout>(builder3.buffer().data());

EXPECT_TRUE((view1 == view2));
EXPECT_EQ(view1.hash(), view2.hash());

EXPECT_FALSE((view1 == view3));
EXPECT_NE(view1.hash(), view3.hash());

EXPECT_FALSE((view2 == view3));
EXPECT_NE(view2.hash(), view3.hash());


auto const_view1 = ConstView<BitsetLayout>(builder1.buffer().data());
auto const_view2 = ConstView<BitsetLayout>(builder2.buffer().data());
auto const_view3 = ConstView<BitsetLayout>(builder3.buffer().data());

EXPECT_TRUE((const_view1 == const_view2));
EXPECT_EQ(const_view1.hash(), const_view2.hash());

EXPECT_FALSE((const_view1 == const_view3));
EXPECT_NE(const_view1.hash(), const_view3.hash());

EXPECT_FALSE((const_view2 == const_view3));
EXPECT_NE(const_view2.hash(), const_view3.hash());

}



}
4 changes: 0 additions & 4 deletions tests/unit/types/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,6 @@ namespace flatmemory::tests

TEST(FlatmemoryTests, TypesTupleEqualityTest) {
using TupleLayout = Tuple<uint64_t, uint32_t>;
EXPECT_EQ((Layout<TupleLayout>::final_alignment), 8);
EXPECT_EQ((IsTriviallyCopyable<View<TupleLayout>>), true);
EXPECT_EQ((IsTriviallyCopyable<TupleLayout>), false);

auto builder1 = Builder<TupleLayout>();
builder1.get<0>() = 5;
Expand Down Expand Up @@ -219,6 +216,5 @@ namespace flatmemory::tests

EXPECT_FALSE((const_view2 == const_view3));
EXPECT_NE(const_view2.hash(), const_view3.hash());

}
}
3 changes: 0 additions & 3 deletions tests/unit/types/vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ TEST(FlatmemoryTests, TypesVectorViewTest) {

TEST(FlatmemoryTests, TypesVectorEqualityTest) {
using VectorLayout = Vector<uint64_t>;
EXPECT_EQ((Layout<VectorLayout>::final_alignment), 8);
EXPECT_EQ((IsTriviallyCopyable<View<VectorLayout>>), true);
EXPECT_EQ((IsTriviallyCopyable<VectorLayout>), false);

auto builder1 = Builder<VectorLayout>();
builder1.push_back(5);
Expand Down

0 comments on commit 9459449

Please sign in to comment.