BigFile/Sasquatch #1

Merged
rboullard merged 100 commits from BigFile into Development 2026-09-01 16:32:02 +00:00
3 changed files with 57 additions and 61 deletions
Showing only changes of commit 6bc25a776e - Show all commits
@@ -121,6 +121,7 @@ class AssetContainerBase
{
using SlotMap = StableSlotMap<ContainerHandle>;
using SlotMapKey = SlotMap::SlotMapKey;
public:
virtual ~AssetContainerBase() = default;
@@ -262,6 +263,7 @@ class AssetContainer: public AssetContainerBase
{
using SlotMap = StableSlotMap<ASSET>;
using SlotMapKey = SlotMap::SlotMapKey;
public:
AssetContainer() = default;
@@ -10,18 +10,9 @@
#include <EASTL/array.h>
#include <EASTL/bitset.h>
#include <EASTL/iterator.h>
#include <EASTL/numeric.h>
#include <EASTL/unique_ptr.h>
#include <EASTL/vector.h>
#include <EASTL/numeric.h>
#include <cstddef>
#include <cstdint>
#include <limits>
#include <memory>
#include <new>
#include <type_traits>
#include <utility>
namespace Bigfoot
{
@@ -150,7 +141,8 @@ class DenseSlotMap
const std::size_t indexToRecyclingKey = m_freeListHead;
m_freeListHead = m_keys[indexToRecyclingKey].GetIndex();
m_keys[indexToRecyclingKey] = SlotMapKey {m_keys[indexToRecyclingKey].GetVersion(), static_cast<SlotMapKey::IndexType>(indexToInsertedData)};
m_keys[indexToRecyclingKey] = SlotMapKey {m_keys[indexToRecyclingKey].GetVersion(),
static_cast<SlotMapKey::IndexType>(indexToInsertedData)};
m_dataToKey.emplace_back(indexToRecyclingKey);
return SlotMapKey {m_keys[indexToRecyclingKey].GetVersion(),
@@ -305,7 +297,8 @@ class DenseSlotMap
void RecycleKey(const SlotMapKey p_key)
{
const typename SlotMapKey::VersionType nextVersion = static_cast<SlotMapKey::VersionType>(p_key.GetVersion() + 1);
const typename SlotMapKey::VersionType nextVersion = static_cast<SlotMapKey::VersionType>(p_key.GetVersion() +
1);
if (nextVersion == SlotMapKey::INVALID_VERSION)
{
@@ -345,7 +338,6 @@ class StableSlotMap
alignas(T) std::byte m_bytes[sizeof(T)];
};
struct Page
{
Page() = default;
@@ -395,8 +387,9 @@ class StableSlotMap
{
private:
using PagesVector = eastl::vector<eastl::unique_ptr<Page>>;
using PageIterator =
std::conditional_t<std::is_const_v<VALUE_TYPE>, typename PagesVector::const_iterator, typename PagesVector::iterator>;
using PageIterator = std::conditional_t<std::is_const_v<VALUE_TYPE>,
typename PagesVector::const_iterator,
typename PagesVector::iterator>;
using MapType = std::conditional_t<std::is_const_v<VALUE_TYPE>, const StableSlotMap, StableSlotMap>;
using PageType = std::conditional_t<std::is_const_v<VALUE_TYPE>, const Page, Page>;
@@ -585,12 +578,12 @@ class StableSlotMap
std::size_t Size() const
{
return eastl::accumulate(m_pages.begin(),
m_pages.end(),
0,
[](const std::size_t p_value, const eastl::unique_ptr<Page>& p_page)
{
return p_value + p_page->Size();
});
m_pages.end(),
0,
[](const std::size_t p_value, const eastl::unique_ptr<Page>& p_page)
{
return p_value + p_page->Size();
});
}
[[nodiscard]]
+41 -40
View File
@@ -14,7 +14,7 @@ namespace Bigfoot
class SlotMapKeyFixture: public ::testing::Test
{
protected:
using SlotMapKey = SlotMapKey<>;
using SlotMapKey = SlotMapKey<>;
};
/****************************************************************************************/
@@ -155,7 +155,8 @@ class SlotMapNameGenerator
}
};
using SlotMapTypes = ::testing::Types<DenseSlotMap<SlotMapValue, SlotMapKey<std::uint8_t, std::uint8_t>>, StableSlotMap<SlotMapValue, SlotMapKey<std::uint8_t, std::uint8_t>>>;
using SlotMapTypes = ::testing::Types<DenseSlotMap<SlotMapValue, SlotMapKey<std::uint8_t, std::uint8_t>>,
StableSlotMap<SlotMapValue, SlotMapKey<std::uint8_t, std::uint8_t>>>;
TYPED_TEST_SUITE(SlotMapFixture, SlotMapTypes, SlotMapNameGenerator);
/****************************************************************************************/
@@ -1114,51 +1115,51 @@ TYPED_TEST(SlotMapFixture, ConstReverseIterator)
/****************************************************************************************/
class StableSlotMapFixture: public ::testing::Test
{
protected:
StableSlotMap<std::uint32_t> m_slotMap;
class StableSlotMapFixture: public ::testing::Test
{
protected:
StableSlotMap<std::uint32_t> m_slotMap;
using SlotMapKey = StableSlotMap<std::uint32_t>::SlotMapKey;
};
using SlotMapKey = StableSlotMap<std::uint32_t>::SlotMapKey;
};
/****************************************************************************************/
/****************************************************************************************/
TEST_F(StableSlotMapFixture, PointersAreStable)
{
const SlotMapKey key = m_slotMap.Insert(42);
const std::uint32_t* const pointer = m_slotMap.Get(key);
TEST_F(StableSlotMapFixture, PointersAreStable)
{
const SlotMapKey key = m_slotMap.Insert(42);
const std::uint32_t* const pointer = m_slotMap.Get(key);
// Inserting enough elements to span multiple pages (PAGE_SIZE is 64) must not move already
// -inserted data: unlike DenseSlotMap's contiguous eastl::vector, growth only appends new
// Page objects (each individually heap-allocated), it never reallocates existing ones.
constexpr std::uint32_t elementCount = 200;
eastl::array<SlotMapKey, elementCount> keys;
for (std::uint32_t value = 0; value < elementCount; ++value)
{
keys[value] = m_slotMap.Insert(value);
}
// Inserting enough elements to span multiple pages (PAGE_SIZE is 64) must not move already
// -inserted data: unlike DenseSlotMap's contiguous eastl::vector, growth only appends new
// Page objects (each individually heap-allocated), it never reallocates existing ones.
constexpr std::uint32_t elementCount = 200;
eastl::array<SlotMapKey, elementCount> keys;
for (std::uint32_t value = 0; value < elementCount; ++value)
{
keys[value] = m_slotMap.Insert(value);
}
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
// Removing unrelated elements, including ones sharing the same page as key, must not move it
// either: Remove() only destroys that slot in place, it never compacts the page's array.
for (std::uint32_t value = 0; value < elementCount; value += 2)
{
m_slotMap.Remove(keys[value]);
}
// Removing unrelated elements, including ones sharing the same page as key, must not move it
// either: Remove() only destroys that slot in place, it never compacts the page's array.
for (std::uint32_t value = 0; value < elementCount; value += 2)
{
m_slotMap.Remove(keys[value]);
}
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
// Re-inserting into the freed slots must not move it either
for (std::uint32_t value = 0; value < elementCount / 2; ++value)
{
std::ignore = m_slotMap.Insert(value);
}
// Re-inserting into the freed slots must not move it either
for (std::uint32_t value = 0; value < elementCount / 2; ++value)
{
std::ignore = m_slotMap.Insert(value);
}
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
}
EXPECT_EQ(m_slotMap.Get(key), pointer);
EXPECT_EQ(*pointer, 42);
}
} // namespace Bigfoot