Skip to content

Commit

Permalink
with prints in case of further errors
Browse files Browse the repository at this point in the history
  • Loading branch information
drexlerd committed Mar 5, 2024
1 parent 2630f9d commit f337021
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 30 deletions.
2 changes: 1 addition & 1 deletion include/flatmemory/details/byte_buffer_segmented.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ namespace flatmemory
memcpy(result_data, data, amount);
cur_segment_pos += amount;
m_size += amount;
last_written += amount;
last_written = amount;
return result_data;
}

Expand Down
41 changes: 33 additions & 8 deletions include/flatmemory/details/containers/unordered_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,48 @@
#include "../view.hpp"
#include "../view_const.hpp"
#include "../type_traits.hpp"
#include "../byte_buffer_utils.hpp"

#include <unordered_set>
#include <iostream>


namespace flatmemory {

template<typename T>
struct CustomHash {
size_t operator()(const T& element) const {
return element.hash();
}
};

template<typename T>
struct CustomEqual {
bool operator()(const T& left_element, const T& right_element) const {
return left_element == right_element;
}
};

/**
* UnorderedSet behaves like std::unordered_set
* but without the functionality to erase elements
* since m_storage would keep growing.
*/
template<typename T, typename Hash = std::hash<ConstView<T>>, typename Equal = std::equal_to<ConstView<T>>, typename Allocator = std::allocator<ConstView<T>>>
template<typename T>
class UnorderedSet
{
private:
// Persistent storage
ByteBufferSegmented m_storage;

// Data to be accessed
std::unordered_set<ConstView<T>, Hash, Equal, Allocator> m_data;
std::unordered_set<ConstView<T>, CustomHash<ConstView<T>>, CustomEqual<ConstView<T>>> m_data;

using iterator = std::unordered_set<ConstView<T>, Hash, Equal, Allocator>::iterator;
using const_iterator = std::unordered_set<ConstView<T>, Hash, Equal, Allocator>::const_iterator;
using iterator = std::unordered_set<ConstView<T>>::iterator;
using const_iterator = std::unordered_set<ConstView<T>>::const_iterator;

public:
explicit UnorderedSet(NumBytes n = 1000000)
explicit UnorderedSet(NumBytes n = 1000000)
: m_storage(ByteBufferSegmented(n)) { }
// Move only
UnorderedSet(const UnorderedSet& other) = delete;
Expand Down Expand Up @@ -86,24 +102,33 @@ class UnorderedSet


[[nodiscard]] ConstView<T> insert(const ConstView<T>& view) {
std::cout << "unordered_set written: ";
print(view.buffer(), view.buffer_size());
const uint8_t* data = view.buffer();
size_t amount = view.get_buffer_size();
size_t amount = view.buffer_size();
const uint8_t* new_data = m_storage.write(data, amount);
auto result_view = ConstView<T>(new_data);
std::cout << "data: " << data << " result_view_ptr: " << &result_view << std::endl;
auto it = m_data.find(result_view);

if (it != m_data.end()) {
// not unique, mark the storage as free again
m_storage.undo_last_write();
//m_storage.undo_last_write();
std::cout << "not unique!" << std::endl;
auto obtained_view = *it;
std::cout << "unordered_set obtained: ";
print(obtained_view.buffer(), obtained_view.buffer_size());
return *it;
}

auto result = m_data.insert(result_view);
return *result.first;
}


[[nodiscard]] ConstView<T> insert(const View<T>& view) {
const uint8_t* data = view.buffer();
size_t amount = view.get_buffer_size();
size_t amount = view.buffer_size();
const uint8_t* new_data = m_storage.write(data, amount);
auto result_view = ConstView<T>(new_data);
auto it = m_data.find(result_view);
Expand Down
16 changes: 8 additions & 8 deletions include/flatmemory/details/containers/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace flatmemory {

/**
* VariableSizedTypeVector can handle different sized objects
* but does not support resize since the exact
* but does not support resize since the exact
* amount of needed bytes is not known in advance.
*/
template<typename T>
Expand All @@ -34,7 +34,7 @@ class VariableSizedTypeVector
using const_iterator = std::vector<View<T>>::const_iterator;

public:
explicit VariableSizedTypeVector(NumBytes n = 1000000)
explicit VariableSizedTypeVector(NumBytes n = 1000000)
: m_storage(ByteBufferSegmented(n)) { }
// Move only
VariableSizedTypeVector(const VariableSizedTypeVector& other) = delete;
Expand All @@ -56,9 +56,9 @@ class VariableSizedTypeVector
return m_data[pos];
}

[[nodiscard]] View<T> back() {
[[nodiscard]] View<T> back() {
assert(!m_data.empty());
return m_data.back();
return m_data.back();
}

[[nodiscard]] ConstView<T> back() const {
Expand Down Expand Up @@ -99,11 +99,11 @@ class VariableSizedTypeVector
}

void push_back(const View<T>& view) {
m_data.push_back(View<T>(m_storage.write(view.buffer(), view.get_buffer_size())));
m_data.push_back(View<T>(m_storage.write(view.buffer(), view.buffer_size())));
}

void push_back(const ConstView<T>& view) {
m_data.push_back(View<T>(m_storage.write(view.buffer(), view.get_buffer_size())));
m_data.push_back(View<T>(m_storage.write(view.buffer(), view.buffer_size())));
}
};

Expand All @@ -127,9 +127,9 @@ class FixedSizedTypeVector
using const_iterator = std::vector<View<T>>::const_iterator;

public:
FixedSizedTypeVector(Builder<T>&& default_builder, NumBytes n = 1000000)
FixedSizedTypeVector(Builder<T>&& default_builder, NumBytes n = 1000000)
: m_storage(ByteBufferSegmented(n))
, m_default_builder(std::move(default_builder)) {
, m_default_builder(std::move(default_builder)) {
if (m_default_builder.buffer().data() == nullptr) {
throw std::runtime_error("Builder is not fully initialized! Did you forget to call finish()?");
}
Expand Down
2 changes: 1 addition & 1 deletion include/flatmemory/details/types/bitset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ namespace flatmemory
const auto length = static_cast<std::size_t>(last_relevant_index + 1) * sizeof(Block);

// Compute a hash value up to and including this block
int64_t hash[2];
int64_t hash[2] = {0, 0};
MurmurHash3_x64_128(blocks.data(), length, seed, hash);
return static_cast<std::size_t>(hash[0] + 0x9e3779b9 + (hash[1] << 6) + (hash[1] >> 2));
}
Expand Down
29 changes: 28 additions & 1 deletion include/flatmemory/details/types/tuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ namespace flatmemory
} else {
// write offset
m_buffer.write(element_data.position, buffer_size);
std::cout << "offset: " << buffer_size << std::endl;
m_buffer.write_padding(element_data.end, element_data.padding);

// write data
Expand Down Expand Up @@ -321,6 +322,7 @@ namespace flatmemory
* Operators
*/
[[nodiscard]] bool operator==(const View& other) const {
std::cout << "operator==" << std::endl;
if (this != &other) {
if (buffer_size() != other.buffer_size()) return false;
return std::memcmp(m_buf, other.m_buf, buffer_size()) == 0;
Expand Down Expand Up @@ -436,6 +438,7 @@ namespace flatmemory
*/

[[nodiscard]] bool operator==(const ConstView& other) const {
std::cout << "operator==" << std::endl;
if (this != &other) {
if (m_buf != other.m_buf) {
if (buffer_size() != other.buffer_size()) return false;
Expand Down Expand Up @@ -466,6 +469,7 @@ namespace flatmemory
assert(test_correct_alignment<element_type<I>>(m_buf + Layout<Tuple<Ts...>>::layout_data.element_datas[I].position));
return read_value<element_type<I>>(m_buf + Layout<Tuple<Ts...>>::layout_data.element_datas[I].position);
} else {
std::cout << "get: " << read_value<offset_type>(m_buf + Layout<Tuple<Ts...>>::layout_data.element_datas[I].position) << std::endl;
return element_view_type<I>(m_buf + read_value<offset_type>(m_buf + Layout<Tuple<Ts...>>::layout_data.element_datas[I].position));
}
}
Expand Down Expand Up @@ -503,12 +507,33 @@ namespace flatmemory

namespace std
{
// Inject hash into the std namespace
// Inject comparison and hash into the std namespace
template<flatmemory::IsTriviallyCopyableOrCustom... Ts>
struct equal_to<flatmemory::View<flatmemory::Tuple<Ts...>>>
{
bool operator()(const flatmemory::View<flatmemory::Tuple<Ts...>>& view_left, const flatmemory::View<flatmemory::Tuple<Ts...>>& view_right) const
{
std::cout << "equal_to" << std::endl;
return view_left == view_right;
}
};

template<flatmemory::IsTriviallyCopyableOrCustom... Ts>
struct equal_to<flatmemory::ConstView<flatmemory::Tuple<Ts...>>>
{
bool operator()(const flatmemory::ConstView<flatmemory::Tuple<Ts...>>& view_left, const flatmemory::ConstView<flatmemory::Tuple<Ts...>>& view_right) const
{
std::cout << "equal_to" << std::endl;
return view_left == view_right;
}
};

template <flatmemory::IsTriviallyCopyableOrCustom... Ts>
struct hash<flatmemory::View<flatmemory::Tuple<Ts...>>>
{
std::size_t operator()(const flatmemory::View<flatmemory::Tuple<Ts...>> &tuple) const
{
std::cout << "hash" << std::endl;
return tuple.hash();
}
};
Expand All @@ -518,6 +543,7 @@ namespace std
{
std::size_t operator()(const flatmemory::ConstView<flatmemory::Tuple<Ts...>> &tuple) const
{
std::cout << "hash" << std::endl;
return tuple.hash();
}
};
Expand All @@ -527,6 +553,7 @@ namespace std
{
std::size_t operator()(const flatmemory::Builder<flatmemory::Tuple<Ts...>> &tuple) const
{
std::cout << "hash" << std::endl;
return tuple.hash();
}
};
Expand Down
19 changes: 9 additions & 10 deletions include/flatmemory/flatmemory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,20 @@
#define FLATMEMORY_FLATMEMORY_HPP_


/**
* Containers
*/

#include "details/containers/unordered_set.hpp"
#include "details/containers/vector.hpp"


/**
* Types
*/

#include "details/types/bitset.hpp"
#include "details/types/trivial.hpp"
#include "details/types/tuple.hpp"
#include "details/types/vector.hpp"
#include "details/types/vector.hpp"

/**
* Containers
*/

#include "details/containers/unordered_set.hpp"
#include "details/containers/vector.hpp"

#endif
#endif
38 changes: 37 additions & 1 deletion tests/unit/types/tuple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <gtest/gtest.h>

#include <string>
#include <random>


namespace flatmemory::tests
Expand Down Expand Up @@ -193,7 +194,7 @@ namespace flatmemory::tests
auto view1 = View<TupleLayout>(builder1.buffer().data());
auto view2 = View<TupleLayout>(builder2.buffer().data());
auto view3 = View<TupleLayout>(builder3.buffer().data());

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

Expand All @@ -217,4 +218,39 @@ namespace flatmemory::tests
EXPECT_FALSE((const_view2 == const_view3));
EXPECT_NE(const_view2.hash(), const_view3.hash());
}


TEST(FlatmemoryTests, TypesTupleStateTest) {
using BitsetLayout = Bitset<uint64_t>;
using TupleLayout = Tuple<uint32_t, BitsetLayout>;
using UnorderedSet = UnorderedSet<TupleLayout>;

Layout<TupleLayout>().print();
std::cout << std::endl;
Layout<BitsetLayout>().print();
std::cout << std::endl;

auto vec = UnorderedSet();

std::random_device rd; // Obtain a random number from hardware
std::mt19937 eng(rd()); // Seed the generator

auto builder = Builder<TupleLayout>();

for (size_t i = 0; i < 2; ++i) {
std::cout << std::endl << std::endl;
size_t i2 = eng() % 2;

//i2 = 2;
builder.get<1>().get_blocks().resize(i2);
builder.finish();
auto const_view = ConstView<TupleLayout>(builder.buffer().data());
auto view = vec.insert(const_view);

std::cout << "unordered_set returned: ";
print(view.buffer(), view.buffer_size());

EXPECT_EQ(view.get<1>().get_blocks().size(), i2);
}
}
}

0 comments on commit f337021

Please sign in to comment.