Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
helios::ecs::details::QueryCacheManager Class Reference

Manages query state caching with Bevy-inspired optimizations. More...

#include <query_cache.hpp>

Public Member Functions

 QueryCacheManager ()=default
 
 QueryCacheManager (const QueryCacheManager &)=delete
 
 QueryCacheManager (QueryCacheManager &&other) noexcept
 
 ~QueryCacheManager ()=default
 
QueryCacheManageroperator= (const QueryCacheManager &)=delete
 
QueryCacheManageroperator= (QueryCacheManager &&other) noexcept
 
void Clear () noexcept
 Clears all cached query states and resets statistics.
 
void ResetStats () noexcept
 Resets cache statistics without clearing query states.
 
const QueryStateTryGetCache (std::span< const ComponentTypeId > with_components, std::span< const ComponentTypeId > without_components, size_t current_generation) const
 Tries to retrieve a valid cached query state.
 
void StoreCache (std::span< const ComponentTypeId > with_components, std::span< const ComponentTypeId > without_components, std::vector< std::reference_wrapper< const Archetype > > matching_archetypes, size_t current_generation)
 Stores or updates a query state in the cache.
 
void InvalidateAll ()
 Invalidates all cached query states.
 
void InvalidateForComponents (std::span< const ComponentTypeId > component_ids)
 Invalidates query states that involve specific components.
 
void NotifyArchetypeChange ()
 Notifies the cache of an archetype structural change.
 
size_t CacheSize () const noexcept
 Gets the number of cached query states.
 
QueryCacheStats Stats () const noexcept
 Gets cache performance statistics.
 

Static Public Member Functions

static bool ValidateQueryState (const QueryState &state, size_t current_generation)
 Validates a cached query state against current archetype generations.
 

Detailed Description

Manages query state caching with Bevy-inspired optimizations.

Provides efficient caching of archetype matching results with smart invalidation.

Key features:

  • Archetype generation tracking: Each archetype has a generation counter that increments on structural changes. Query states cache these generations and can detect stale data.
  • Component-aware invalidation: Only queries using specific components are invalidated when those components are modified.
  • Query state reuse: Pre-computed query metadata is cached and reused across frames.
  • Efficient validation: Quick checks using generation counters avoid full re-computation.
Note
Thread-safe for read operations, single-writer for updates.

Definition at line 204 of file query_cache.hpp.

Constructor & Destructor Documentation

◆ QueryCacheManager() [1/3]

helios::ecs::details::QueryCacheManager::QueryCacheManager ( )
default

◆ QueryCacheManager() [2/3]

helios::ecs::details::QueryCacheManager::QueryCacheManager ( const QueryCacheManager )
delete

◆ QueryCacheManager() [3/3]

helios::ecs::details::QueryCacheManager::QueryCacheManager ( QueryCacheManager &&  other)
inlinenoexcept

Definition at line 328 of file query_cache.hpp.

329 : cache_(std::move(other.cache_)),
330 stats_(std::move(other.stats_)),
331 access_counter_(other.access_counter_.load(std::memory_order_relaxed)) {}

◆ ~QueryCacheManager()

helios::ecs::details::QueryCacheManager::~QueryCacheManager ( )
default

Member Function Documentation

◆ CacheSize()

size_t helios::ecs::details::QueryCacheManager::CacheSize ( ) const
inlinenoexcept

Gets the number of cached query states.

Returns
Cache entry count

Definition at line 275 of file query_cache.hpp.

275{ return cache_.size(); }

◆ Clear()

void helios::ecs::details::QueryCacheManager::Clear ( )
inlinenoexcept

Clears all cached query states and resets statistics.

Definition at line 345 of file query_cache.hpp.

345 {
346 cache_.clear();
347 stats_.Reset();
348 access_counter_.store(0, std::memory_order_relaxed);
349}

◆ InvalidateAll()

void helios::ecs::details::QueryCacheManager::InvalidateAll ( )
inline

Invalidates all cached query states.

Called when major structural changes occur that affect many queries. Increments global invalidation counter.

Definition at line 379 of file query_cache.hpp.

379 {
380 cache_.clear();
381 ++stats_.invalidation_count;
382}
std::atomic< size_t > invalidation_count
Number of cache invalidations.

◆ InvalidateForComponents()

void helios::ecs::details::QueryCacheManager::InvalidateForComponents ( std::span< const ComponentTypeId component_ids)
inline

Invalidates query states that involve specific components.

Selective invalidation - only queries using the specified components need to be recomputed. More efficient than full invalidation.

Parameters
component_idsComponent types that were modified

Definition at line 384 of file query_cache.hpp.

384 {
385 if (component_ids.empty()) {
386 return;
387 }
388
389 // Remove cache entries that involve any of the specified components
390 std::vector<size_t> keys_to_remove;
391 cache_.cvisit_all([&keys_to_remove, component_ids](const auto& pair) {
392 if (QueryInvolvesAnyComponents(pair.second, component_ids)) {
393 keys_to_remove.push_back(pair.first);
394 }
395 });
396
397 for (const size_t key : keys_to_remove) {
398 cache_.erase(key);
399 }
400
401 if (!keys_to_remove.empty()) {
402 stats_.partial_invalidations.fetch_add(keys_to_remove.size(), std::memory_order_relaxed);
403 }
404}
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481
std::atomic< size_t > partial_invalidations
Number of partial (component-specific) invalidations.

◆ NotifyArchetypeChange()

void helios::ecs::details::QueryCacheManager::NotifyArchetypeChange ( )
inline

Notifies the cache of an archetype structural change.

Increments archetype change counter for statistics tracking. Does not directly invalidate - queries validate themselves using generation checks.

Definition at line 269 of file query_cache.hpp.

269{ ++stats_.archetype_changes; }
std::atomic< size_t > archetype_changes
Number of archetype structural changes.

◆ operator=() [1/2]

QueryCacheManager & helios::ecs::details::QueryCacheManager::operator= ( const QueryCacheManager )
delete

◆ operator=() [2/2]

QueryCacheManager & helios::ecs::details::QueryCacheManager::operator= ( QueryCacheManager &&  other)
inlinenoexcept

Definition at line 333 of file query_cache.hpp.

333 {
334 if (this == &other) {
335 return *this;
336 }
337
338 cache_ = std::move(other.cache_);
339 stats_ = other.stats_;
340 access_counter_.store(other.access_counter_.load(std::memory_order_relaxed), std::memory_order_relaxed);
341
342 return *this;
343}

◆ ResetStats()

void helios::ecs::details::QueryCacheManager::ResetStats ( )
inlinenoexcept

Resets cache statistics without clearing query states.

Definition at line 222 of file query_cache.hpp.

222{ stats_.Reset(); }

◆ Stats()

QueryCacheStats helios::ecs::details::QueryCacheManager::Stats ( ) const
inlinenoexcept

Gets cache performance statistics.

Returns
Struct containing hit/miss counts and other metrics

Definition at line 281 of file query_cache.hpp.

281{ return stats_; }

◆ StoreCache()

void helios::ecs::details::QueryCacheManager::StoreCache ( std::span< const ComponentTypeId with_components,
std::span< const ComponentTypeId without_components,
std::vector< std::reference_wrapper< const Archetype > >  matching_archetypes,
size_t  current_generation 
)

Stores or updates a query state in the cache.

Caches the matched archetypes along with their current generation counters. This allows future queries to validate the cache using generation checks.

Parameters
with_componentsComponent types that must be present (must be sorted)
without_componentsComponent types that must not be present (must be sorted)
matching_archetypesArchetypes that match the query criteria
current_generationCurrent world structural generation

Definition at line 43 of file query_cache.cpp.

46 {
47 const size_t hash = ComputeQueryHash(with_components, without_components);
48
49 QueryState state;
50 state.matching_archetypes = std::move(matching_archetypes);
51 state.archetype_generations.reserve(state.matching_archetypes.size());
52
53 // Store each archetype's current generation for validation
54 for (const auto& archetype_ref : state.matching_archetypes) {
55 state.archetype_generations.push_back(archetype_ref.get().GetGeneration());
56 }
57
58 state.with_component_types.assign(with_components.begin(), with_components.end());
59 state.without_component_types.assign(without_components.begin(), without_components.end());
60 state.query_generation = current_generation;
61 state.query_hash = hash;
62 state.last_access_time.store(access_counter_.fetch_add(1, std::memory_order_relaxed), std::memory_order_relaxed);
63
64 cache_.insert_or_assign(hash, std::move(state));
65}

◆ TryGetCache()

const QueryState * helios::ecs::details::QueryCacheManager::TryGetCache ( std::span< const ComponentTypeId with_components,
std::span< const ComponentTypeId without_components,
size_t  current_generation 
) const
inline

Tries to retrieve a valid cached query state.

Checks if cached state exists and validates it against current archetype generations. If state is stale (archetypes changed), returns nullptr to trigger re-computation.

Parameters
with_componentsComponent types that must be present (must be sorted)
without_componentsComponent types that must not be present (must be sorted)
current_generationCurrent world structural generation
Returns
Pointer to valid cached state, or nullptr if cache miss/stale

Definition at line 351 of file query_cache.hpp.

353 {
354 const size_t hash = ComputeQueryHash(with_components, without_components);
355 const QueryState* found = nullptr;
356
357 cache_.cvisit(hash, [this, &found, current_generation](const auto& pair) {
358 auto& state = const_cast<QueryState&>(pair.second);
359
360 // Validate state against current generation
362 return; // State is stale
363 }
364
365 UpdateAccessTime(state);
366 found = &state;
367 });
368
369 if (found == nullptr) {
370 ++stats_.miss_count;
371 } else {
372 ++stats_.hit_count;
373 }
374 ++stats_.total_queries;
375
376 return found;
377}
static bool ValidateQueryState(const QueryState &state, size_t current_generation)
Validates a cached query state against current archetype generations.
std::atomic< size_t > miss_count
Number of cache misses.
std::atomic< size_t > total_queries
Total number of queries executed.
std::atomic< size_t > hit_count
Number of cache hits.

◆ ValidateQueryState()

bool helios::ecs::details::QueryCacheManager::ValidateQueryState ( const QueryState state,
size_t  current_generation 
)
static

Validates a cached query state against current archetype generations.

Compares cached archetype generations with current ones to detect if any archetypes have changed structure since caching.

Parameters
stateQuery state to validate
current_generationCurrent world structural generation
Returns
True if state is still valid, false if stale

Definition at line 67 of file query_cache.cpp.

67 {
68 // Quick check: world generation mismatch
69 if (state.query_generation != current_generation) {
70 return false;
71 }
72
73 // Validate each cached archetype's generation
74 HELIOS_ASSERT(state.matching_archetypes.size() == state.archetype_generations.size(),
75 "Archetype count mismatch in query state! Expected {}, got {}", state.matching_archetypes.size(),
76 state.archetype_generations.size());
77
78 for (size_t i = 0; i < state.matching_archetypes.size(); ++i) {
79 const Archetype& archetype = state.matching_archetypes[i].get();
80 const size_t cached_generation = state.archetype_generations[i];
81
82 // Check if archetype structure has changed
83 if (archetype.GetGeneration() != cached_generation) {
84 return false;
85 }
86 }
87
88 return true;
89}
#define HELIOS_ASSERT(condition,...)
Assertion macro that aborts execution in debug builds.
Definition assert.hpp:140