Skip to content

Commit

Permalink
Add FixedMapRawView
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyril Sharma authored and CyrilSharma committed Dec 7, 2024
1 parent 0298e75 commit 26ff0bf
Show file tree
Hide file tree
Showing 8 changed files with 454 additions and 39 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
build

### Bazel ###
# Ignore the lock file
Expand Down
39 changes: 38 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,18 @@ cc_library(
copts = ["-std=c++20"],
)

cc_library(
name = "fixed_map_raw_view",
hdrs = ["include/fixed_containers/fixed_map_raw_view.hpp",],
includes = includes_config(),
strip_include_prefix = strip_include_prefix_config(),
deps = [
":fixed_red_black_tree",
":fixed_red_black_tree_view",
],
copts = ["-std=c++20"],
)

cc_library(
name = "wyhash",
hdrs = ["include/fixed_containers/wyhash.hpp"],
Expand Down Expand Up @@ -409,6 +421,15 @@ cc_library(
]
)

cc_library(
name = "map_entry_raw_view",
hdrs = ["include/fixed_containers/map_entry_raw_view.hpp",],
includes = includes_config(),
strip_include_prefix = strip_include_prefix_config(),
deps = [],
copts = ["-std=c++20"],
)

cc_library(
name = "fixed_unordered_map_raw_view",
hdrs = ["include/fixed_containers/fixed_unordered_map_raw_view.hpp"],
Expand All @@ -417,6 +438,7 @@ cc_library(
deps = [
":fixed_doubly_linked_list_raw_view",
":forward_iterator",
":map_entry_raw_view"
],
copts = ["-std=c++20"],
)
Expand Down Expand Up @@ -1289,6 +1311,20 @@ cc_test(
copts = ["-std=c++20"],
)

cc_test(
name = "fixed_map_raw_view_test",
srcs = ["test/fixed_map_raw_view_test.cpp"],
deps = [
":assert_or_abort",
":fixed_map",
":fixed_map_raw_view",
":fixed_red_black_tree",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
copts = ["-std=c++20"],
)

cc_test(
name = "fixed_unordered_map_test",
srcs = ["test/fixed_unordered_map_test.cpp"],
Expand All @@ -1314,9 +1350,10 @@ cc_test(
srcs = ["test/fixed_unordered_map_raw_view_test.cpp"],
deps = [
":map_entry",
":map_entry_raw_view",
":mock_testing_types",
":fixed_unordered_map",
":fixed_unordered_map_raw_view",
":mock_testing_types",
":test_utilities_common",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ if(BUILD_TESTS)
add_test_dependencies(fixed_list_test)
add_executable(fixed_map_test test/fixed_map_test.cpp)
add_test_dependencies(fixed_map_test)
add_executable(fixed_map_raw_view_test test/fixed_map_raw_view_test.cpp)
add_test_dependencies(fixed_map_raw_view_test)
add_executable(fixed_map_perf_test test/fixed_map_perf_test.cpp)
add_test_dependencies(fixed_map_perf_test)
add_executable(fixed_red_black_tree_test test/fixed_red_black_tree_test.cpp)
Expand Down
187 changes: 187 additions & 0 deletions include/fixed_containers/fixed_map_raw_view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#pragma once

#include "fixed_containers/assert_or_abort.hpp"
#include "fixed_containers/fixed_red_black_tree_nodes.hpp"
#include "fixed_containers/fixed_red_black_tree_types.hpp"
#include "fixed_containers/fixed_red_black_tree_view.hpp"

#include <cstddef>
#include <iterator>

namespace fixed_containers
{

class FixedMapRawView
{
using Compactness = fixed_red_black_tree_detail::RedBlackTreeNodeColorCompactness;
using StorageType = fixed_red_black_tree_detail::RedBlackTreeStorageType;
using NodeIndex = fixed_red_black_tree_detail::NodeIndex;

public:
class Iterator
{
public:

// I use Entry so we can match UnorderedMapRawView's API where,
// *it returns an object with .key() and .value() methods.
class Entry {

private:
FixedRedBlackTreeRawView::Iterator base_iterator_;
std::size_t value_offset_;

public:
friend class Iterator;
Entry(const std::byte* ptr,
std::size_t value_offset_bytes,
std::size_t element_size_bytes,
std::size_t max_size_bytes,
Compactness compactness,
StorageType storage_type,
bool end = false) noexcept:
base_iterator_(ptr,
element_size_bytes,
max_size_bytes,
compactness,
storage_type,
end),
value_offset_(value_offset_bytes) {}

Entry(): base_iterator_(), value_offset_(0) {}

[[nodiscard]] const std::byte* key() const { return *base_iterator_; }

[[nodiscard]] const std::byte* value() const
{
return std::next(*base_iterator_, static_cast<std::ptrdiff_t>(value_offset_));
}

};

private:
Entry entry_;

public:
using value_type = Entry;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using iterator_category = std::forward_iterator_tag;

// Constructor that initializes the base iterator
Iterator(const std::byte* ptr,
std::size_t key_size_bytes,
std::size_t key_align_bytes,
std::size_t value_size_bytes,
std::size_t value_align_bytes,
std::size_t max_size_bytes,
Compactness compactness,
StorageType storage_type,
bool end = false) noexcept
: entry_(ptr,
align_up(key_size_bytes, value_align_bytes),
align_up(align_up(key_size_bytes, value_align_bytes) + value_size_bytes, key_align_bytes),
max_size_bytes,
compactness,
storage_type,
end)
{
}

Iterator() noexcept: entry_() {}
Iterator(const Iterator&) noexcept = default;
Iterator(Iterator&&) noexcept = default;
Iterator& operator=(const Iterator&) noexcept = default;
Iterator& operator=(Iterator&&) noexcept = default;

Iterator& operator++()
{
++entry_.base_iterator_;
return *this;
}

Iterator operator++(int) & noexcept
{
Iterator tmp = *this;
++entry_.base_iterator_;
return tmp;
}

const_reference operator*() const { return entry_; }

const_pointer operator->() const { return &entry_; }

bool operator==(const Iterator& other) const
{
return entry_.base_iterator_ == other.entry_.base_iterator_;
}

bool operator!=(const Iterator& other) const { return !(*this == other); }

[[nodiscard]] std::size_t size() const { return entry_.base_iterator_.size(); }
};

private:
const std::byte* tree_ptr_;
const std::size_t key_size_bytes_;
const std::size_t key_align_bytes_;
const std::size_t value_size_bytes_;
const std::size_t value_align_bytes_;
const std::size_t max_size_bytes_;
const Compactness compactness_;
const StorageType storage_type_;

public:
FixedMapRawView(const void* tree_ptr,
std::size_t key_size_bytes,
std::size_t key_align_bytes,
std::size_t value_size_bytes,
std::size_t value_align_bytes,
std::size_t max_size_bytes,
Compactness compactness,
StorageType storage_type)
: tree_ptr_{reinterpret_cast<const std::byte*>(tree_ptr)}
, key_size_bytes_{key_size_bytes}
, key_align_bytes_{key_align_bytes}
, value_size_bytes_{value_size_bytes}
, value_align_bytes_{value_align_bytes}
, max_size_bytes_{max_size_bytes}
, compactness_{compactness}
, storage_type_{storage_type}
{
// Needed until FixedRedBlackTreeRawView supports types with alignment >= 8.
// Currently, it tacititly presumes alignment will be <= 8 for the keys and values.
assert_or_abort(std::max(value_align_bytes, key_align_bytes) <= 8);
}

[[nodiscard]] Iterator begin() const
{
return Iterator(tree_ptr_,
key_size_bytes_,
key_align_bytes_,
value_size_bytes_,
value_align_bytes_,
max_size_bytes_,
compactness_,
storage_type_);
}

[[nodiscard]] Iterator end() const
{
return Iterator(tree_ptr_,
key_size_bytes_,
key_align_bytes_,
value_size_bytes_,
value_align_bytes_,
max_size_bytes_,
compactness_,
storage_type_,
true);
}

[[nodiscard]] std::size_t size() const { return end().size(); }
};

} // namespace fixed_containers
40 changes: 2 additions & 38 deletions include/fixed_containers/fixed_unordered_map_raw_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,13 @@

#include "fixed_containers/fixed_doubly_linked_list_raw_view.hpp"
#include "fixed_containers/forward_iterator.hpp"

#include "fixed_containers/map_entry_raw_view.hpp"
#include <cstddef>
#include <cstdint>

namespace fixed_containers
{

class MapEntryRawView
{
private:
const std::byte* base_ptr_;
const std::ptrdiff_t value_offs_;

public:
static constexpr std::ptrdiff_t get_value_offs(std::size_t key_size,
std::size_t /*key_alignment*/,
std::size_t /*value_size*/,
std::size_t value_alignment)
{
std::size_t value_offs = key_size;
// align the value start addr to the correct alignment
if (value_offs % value_alignment != 0)
{
value_offs += value_alignment - value_offs % value_alignment;
}
return static_cast<std::ptrdiff_t>(value_offs);
}

public:
MapEntryRawView(const void* ptr,
std::size_t key_size,
std::size_t key_alignment,
std::size_t value_size,
std::size_t value_alignment)
: base_ptr_{reinterpret_cast<const std::byte*>(ptr)}
, value_offs_{get_value_offs(key_size, key_alignment, value_size, value_alignment)}
{
}

[[nodiscard]] const std::byte* key() const { return base_ptr_; }

[[nodiscard]] const std::byte* value() const { return std::next(base_ptr_, value_offs_); }
};

class FixedUnorderedMapRawView
{
private:
Expand Down
43 changes: 43 additions & 0 deletions include/fixed_containers/map_entry_raw_view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include <cstddef>
#include <iterator>

class MapEntryRawView
{
private:
const std::byte* base_ptr_;
const std::ptrdiff_t value_offs_;

public:
static constexpr std::ptrdiff_t get_value_offs(std::size_t key_size,
std::size_t /*key_alignment*/,
std::size_t /*value_size*/,
std::size_t value_alignment)
{
std::size_t value_offs = key_size;
// align the value start addr to the correct alignment
if (value_offs % value_alignment != 0)
{
value_offs += value_alignment - value_offs % value_alignment;
}
return static_cast<std::ptrdiff_t>(value_offs);
}

public:
MapEntryRawView(const void* ptr,
std::size_t key_size,
std::size_t key_alignment,
std::size_t value_size,
std::size_t value_alignment)
: base_ptr_{reinterpret_cast<const std::byte*>(ptr)}
, value_offs_{get_value_offs(key_size, key_alignment, value_size, value_alignment)}
{
}

[[nodiscard]] const std::byte* key() const { return base_ptr_; }

[[nodiscard]] const std::byte* value() const { return std::next(base_ptr_, value_offs_); }

[[nodiscard]] std::ptrdiff_t value_offset() const { return value_offs_; }
};
Loading

0 comments on commit 26ff0bf

Please sign in to comment.