Skip to content

Commit

Permalink
Merge branch 'flatbag'
Browse files Browse the repository at this point in the history
  • Loading branch information
malytomas committed Jan 11, 2024
2 parents 5eb30f0 + 4ac651c commit 631d266
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 6 deletions.
85 changes: 85 additions & 0 deletions sources/include/cage-core/flatBag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#ifndef guard_flatBag_sezik4edrt5
#define guard_flatBag_sezik4edrt5

#include <vector>

#include <unordered_dense.h>

#include <cage-core/core.h>

namespace cage
{
template<class Value>
struct FlatBag
{
public:
using key_type = Value;
using value_type = Value;
using const_iterator = typename std::vector<Value>::const_iterator;
using size_type = uintPtr;

constexpr void insert(const Value &value)
{
if (indices.count(value))
return;
indices[value] = data_.size();
data_.push_back(value);
}

constexpr uintPtr erase(const Value &value)
{
auto it = indices.find(value);
if (it == indices.end())
return 0;
const uintPtr off = it->second;
indices.erase(it);
if (off + 1 != data_.size())
{
indices[data_.back()] = off;
std::swap(data_[off], data_.back());
}
data_.pop_back();
return 1;
}

constexpr void clear()
{
indices.clear();
data_.clear();
}

constexpr void reserve(uintPtr s)
{
indices.reserve(s);
data_.reserve(s);
}

constexpr const_iterator find(const Value &value) const
{
auto it = indices.find(value);
if (it == indices.end())
return data_.end();
return data_.begin() + it->second;
}

constexpr uintPtr count(const Value &value) const { return find(value) == end() ? 0 : 1; }

constexpr uintPtr size() const noexcept { return data_.size(); }

constexpr bool empty() const noexcept { return data_.empty(); }

constexpr const Value *data() const noexcept { return data_.data(); }

constexpr const_iterator begin() const noexcept { return data_.begin(); }

constexpr const_iterator end() const noexcept { return data_.end(); }

constexpr std::vector<Value> &unsafeData() noexcept { return data_; }

private:
ankerl::unordered_dense::map<Value, uintPtr> indices;
std::vector<Value> data_;
};
}

#endif // guard_flatBag_sezik4edrt5
4 changes: 1 addition & 3 deletions sources/include/cage-core/flatSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace cage
using value_type = Value;
using const_iterator = typename std::vector<Value>::const_iterator;
using const_reverse_iterator = typename std::vector<Value>::const_reverse_iterator;
using size_type = typename std::vector<Value>::size_type;
using size_type = uintPtr;

constexpr FlatSet() = default;
constexpr FlatSet(const FlatSet &other) = default;
Expand Down Expand Up @@ -113,8 +113,6 @@ namespace cage

constexpr const_reverse_iterator rend() const noexcept { return data_.rend(); }

constexpr const std::vector<Value> &unsafeData() const noexcept { return data_; }

constexpr std::vector<Value> &unsafeData() noexcept { return data_; }

private:
Expand Down
6 changes: 3 additions & 3 deletions sources/libcore/entities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <unordered_dense.h>

#include <cage-core/entities.h>
#include <cage-core/flatSet.h>
#include <cage-core/flatBag.h>
#include <cage-core/memoryAllocators.h>
#include <cage-core/pointerRangeHolder.h>

Expand Down Expand Up @@ -35,7 +35,7 @@ namespace cage
std::vector<Holder<ComponentImpl>> components;
std::vector<EntityComponent *> componentsByTypes;
ankerl::unordered_dense::map<uint32, Entity *> namedEntities;
FlatSet<Entity *> allEntities;
FlatBag<Entity *> allEntities;
uint32 generateName = 0;
uint32 entSize = 0;

Expand Down Expand Up @@ -76,7 +76,7 @@ namespace cage
class ComponentImpl : public EntityComponent
{
public:
FlatSet<Entity *> componentEntities;
FlatBag<Entity *> componentEntities;
EntityManagerImpl *const manager = nullptr;
Holder<MemoryArena> arena;
Holder<void> prototype;
Expand Down
113 changes: 113 additions & 0 deletions sources/test-core/flatBag.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#include "main.h"

#include <cage-core/flatBag.h>
#include <cage-core/flatSet.h>
#include <cage-core/math.h>
#include <cage-core/stdHash.h>

void testFlatBag()
{
CAGE_TESTCASE("flatBag");

{
CAGE_TESTCASE("basics");

FlatBag<uint32> s;
s.insert(13);
s.insert(1024);
s.insert(42);
CAGE_TEST(s.size() == 3);
s.insert(42);
CAGE_TEST(s.size() == 3);
CAGE_TEST(s.count(20) == 0);
CAGE_TEST(s.count(42) == 1);
CAGE_TEST(!s.empty());
s.erase(13);
CAGE_TEST(s.size() == 2);
s.erase(13);
CAGE_TEST(s.size() == 2);
s.clear();
CAGE_TEST(s.size() == 0);
CAGE_TEST(s.empty());
}

{
CAGE_TESTCASE("const bag");

const FlatBag<uint32> s = []()
{
FlatBag<uint32> s;
s.insert(13);
s.insert(42);
return s;
}();
CAGE_TEST(s.count(20) == 0);
CAGE_TEST(s.count(42) == 1);
CAGE_TEST(s.size() == 2);
CAGE_TEST(!s.empty());
}

{
CAGE_TESTCASE("access FlatBag as PointerRange");

FlatBag<uint32> s;
s.insert(1024);
s.insert(13);
s.insert(42);
PointerRange<const uint32> pr = s;
CAGE_TEST(pr.size() == 3);
}

{
CAGE_TESTCASE("find");

FlatBag<uint32> s;
s.insert(1024);
s.insert(13);
s.insert(42);
CAGE_TEST(s.find(13) != s.end());
CAGE_TEST(s.find(20) == s.end());
}

{
CAGE_TESTCASE("erase");

FlatBag<uint32> s;
s.insert(1024);
s.insert(13);
s.insert(42);
CAGE_TEST(s.size() == 3);
s.erase(42);
CAGE_TEST(s.size() == 2);
CAGE_TEST(s.count(1024) == 1);
CAGE_TEST(s.count(13) == 1);
CAGE_TEST(s.count(42) == 0);
}

{
CAGE_TESTCASE("randomized");

FlatBag<uint32> b;
FlatSet<uint32> s; // reference implementation

for (uint32 round = 0; round < 10000; round++)
{
const uint32 i = randomRange(13, 420);
if (s.count(i))
{
CAGE_TEST(b.count(i));
s.erase(i);
b.erase(i);
}
else
{
CAGE_TEST(!b.count(i));
s.insert(i);
b.insert(i);
}
CAGE_TEST(s.size() == b.size());
const FlatSet<uint32> tmp = makeFlatSet<uint32>(b.unsafeData());
CAGE_TEST(tmp == s);
}
}
}
1 change: 1 addition & 0 deletions sources/test-core/flatSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace
s.insert("you");
s.insert("you");
s.insert("are");
s.erase("bro");
return s.size();
}
}
Expand Down
2 changes: 2 additions & 0 deletions sources/test-core/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ void testProfiling();
void testTasks();
void testLruCache();
void testFlatSet();
void testFlatBag();
void testFiles();
void testArchives();
void testArchivesRecursion();
Expand Down Expand Up @@ -112,6 +113,7 @@ int main()
testTasks();
testLruCache();
testFlatSet();
testFlatBag();
testFiles();
testArchives();
testArchivesRecursion();
Expand Down

0 comments on commit 631d266

Please sign in to comment.