LCOV - code coverage report
Current view: top level - engine/time/internal - snapshot_cache.hpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 30 30
Test Date: 2026-03-11 04:45:14 Functions: 100.0 % 6 6

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <jage/engine/concurrency/double_buffer.hpp>
       4              : #include <jage/engine/memory/cacheline_size.hpp>
       5              : #include <jage/engine/memory/cacheline_slot.hpp>
       6              : #include <jage/engine/time/cache_match_status.hpp>
       7              : 
       8              : #include <jage/engine/time/internal/concepts/cache_snapshot.hpp>
       9              : 
      10              : #include <array>
      11              : #include <atomic>
      12              : #include <cstdint>
      13              : #include <utility>
      14              : 
      15              : namespace jage::engine::time::internal {
      16              : template <std::uint64_t Capacity, internal::concepts::cache_snapshot TSnapshot,
      17              :           template <class, template <class> class> class TBuffer,
      18              :           template <class> class TAtomic>
      19              : class snapshot_cache {
      20              :   alignas(memory::cacheline_size) std::array<
      21              :       memory::cacheline_slot<TBuffer<TSnapshot, TAtomic>>, Capacity> buffer_{};
      22              :   alignas(memory::cacheline_size) TAtomic<std::uint64_t> write_index_{0UZ};
      23              : 
      24              : public:
      25              :   [[nodiscard]] constexpr auto capacity() const noexcept -> std::uint64_t {
      26              :     return Capacity;
      27              :   }
      28              : 
      29              :   auto
      30           26 :   push(const internal::concepts::cache_snapshot auto &input_snapshot) -> void {
      31           26 :     const auto write_index = write_index_.load(std::memory_order::acquire);
      32           26 :     buffer_[write_index % Capacity].write(input_snapshot);
      33           26 :     write_index_.store(write_index + 1, std::memory_order::release);
      34           26 :   }
      35              : 
      36            8 :   [[nodiscard]] auto find(const typename TSnapshot::duration &event_real_time)
      37              :       -> std::pair<TSnapshot, cache_match_status> {
      38            8 :     const auto write_index = write_index_.load(std::memory_order::acquire);
      39            8 :     const auto newest_index = (write_index + Capacity - 1UZ) % Capacity;
      40              : 
      41           20 :     for (auto offset = 0UZ; offset < Capacity; ++offset) {
      42           18 :       const auto index = (newest_index + Capacity - offset) % Capacity;
      43           18 :       const auto snap = buffer_[index].read();
      44           18 :       if (event_real_time >= snap.real_time) {
      45              :         return {
      46              :             snap,
      47            6 :             cache_match_status::matched,
      48            6 :         };
      49              :       }
      50              :     }
      51              : 
      52              :     return {
      53            2 :         buffer_[write_index % Capacity].read(),
      54            2 :         cache_match_status::evicted,
      55            2 :     };
      56              :   }
      57              : 
      58            7 :   [[nodiscard]] auto find(const std::uint64_t frame_index)
      59              :       -> std::pair<TSnapshot, cache_match_status> {
      60            7 :     const auto write_index = write_index_.load(std::memory_order::acquire);
      61            7 :     const auto newest_index = (write_index + Capacity - 1UZ) % Capacity;
      62            7 :     const auto oldest_index = write_index % Capacity;
      63              : 
      64            7 :     if (const auto newest_snap = buffer_[newest_index].read();
      65            7 :         newest_snap.frame < frame_index) [[unlikely]] {
      66            1 :       return {newest_snap, cache_match_status::ahead};
      67            6 :     } else if (const auto oldest_snap = buffer_[oldest_index].read();
      68            6 :                oldest_snap.frame > frame_index) [[unlikely]] {
      69            1 :       return {oldest_snap, cache_match_status::evicted};
      70              :     }
      71              :     return {
      72            5 :         buffer_[frame_index % Capacity].read(),
      73            5 :         cache_match_status::matched,
      74            5 :     };
      75              :   }
      76              : };
      77              : } // namespace jage::engine::time::internal
        

Generated by: LCOV version 2.0-1