LCOV - code coverage report
Current view: top level - src/esys/repo/sharing - inventory_sharing.cpp (source / functions) Hit Total Coverage
Test: esysrepo_coverage.info Lines: 49 57 86.0 %
Date: 2026-11-07 22:18:26 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*!
       2             :  * \file esys/repo/sharing/inventory_sharing.cpp
       3             :  * \brief In-memory dependency inventory (ADR-0042)
       4             :  *
       5             :  * \cond
       6             :  * __legal_b__
       7             :  *
       8             :  * Copyright (c) 2026 Michel Gillet
       9             :  * Distributed under the MIT License.
      10             :  * (See accompanying file LICENSE.txt or
      11             :  * copy at https://opensource.org/licenses/MIT)
      12             :  *
      13             :  * __legal_e__
      14             :  * \endcond
      15             :  *
      16             :  */
      17             : 
      18             : #include "esys/repo/esysrepo_prec.h"
      19             : #include "esys/repo/sharing/inventory.h"
      20             : 
      21             : namespace esys::repo::sharing
      22             : {
      23             : 
      24          27 : void Inventory::clear()
      25             : {
      26          27 :     m_occurrences.clear();
      27          27 :     m_coverage = Coverage::Unknown;
      28          27 :     m_inspected_scopes.clear();
      29          27 :     m_seen_keys_this_pass.clear();
      30          27 : }
      31             : 
      32           5 : void Inventory::upsert(const Occurrence &occurrence)
      33             : {
      34           5 :     const std::string key = occurrence.scope_key();
      35           5 :     m_seen_keys_this_pass.insert(key);
      36           8 :     for (auto &existing : m_occurrences)
      37             :     {
      38           4 :         if (existing.scope_key() == key)
      39             :         {
      40           1 :             existing = occurrence;
      41           1 :             return;
      42             :         }
      43             :     }
      44           4 :     m_occurrences.push_back(occurrence);
      45           5 : }
      46             : 
      47           2 : const std::vector<Occurrence> &Inventory::get_occurrences() const
      48             : {
      49           2 :     return m_occurrences;
      50             : }
      51             : 
      52           1 : void Inventory::set_coverage(Coverage coverage)
      53             : {
      54           1 :     m_coverage = coverage;
      55           1 : }
      56             : 
      57           1 : Coverage Inventory::get_coverage() const
      58             : {
      59           1 :     return m_coverage;
      60             : }
      61             : 
      62           1 : void Inventory::mark_scope_inspected(const std::string &consumer_path)
      63             : {
      64           1 :     m_inspected_scopes.insert(consumer_path);
      65             :     // New inspection pass for this scope: clear seen keys that belong to it
      66           1 :     for (auto it = m_seen_keys_this_pass.begin(); it != m_seen_keys_this_pass.end();)
      67             :     {
      68           0 :         if (it->size() >= consumer_path.size() && it->compare(0, consumer_path.size(), consumer_path) == 0 &&
      69           0 :             (it->size() == consumer_path.size() || (*it)[consumer_path.size()] == '\x1f'))
      70           0 :             it = m_seen_keys_this_pass.erase(it);
      71             :         else
      72           1 :             ++it;
      73             :     }
      74           1 : }
      75             : 
      76           1 : void Inventory::drop_stale_in_scope(const std::string &consumer_path)
      77             : {
      78           1 :     if (m_inspected_scopes.find(consumer_path) == m_inspected_scopes.end()) return;
      79             : 
      80           1 :     std::vector<Occurrence> kept;
      81           1 :     kept.reserve(m_occurrences.size());
      82           2 :     for (const auto &occ : m_occurrences)
      83             :     {
      84           1 :         if (occ.get_consumer_path() != consumer_path)
      85             :         {
      86           0 :             kept.push_back(occ);
      87           0 :             continue;
      88             :         }
      89           3 :         if (m_seen_keys_this_pass.count(occ.scope_key()) != 0) kept.push_back(occ);
      90             :     }
      91           1 :     m_occurrences.swap(kept);
      92           1 : }
      93             : 
      94           3 : std::map<std::string, std::vector<Occurrence>> Inventory::group_by_identity() const
      95             : {
      96           3 :     std::map<std::string, std::vector<Occurrence>> groups;
      97          10 :     for (const auto &occ : m_occurrences)
      98             :     {
      99           7 :         if (occ.get_normalized_identity().empty()) continue;
     100           5 :         groups[occ.get_normalized_identity()].push_back(occ);
     101             :     }
     102           3 :     return groups;
     103           0 : }
     104             : 
     105             : std::map<std::string, std::vector<Occurrence>>
     106           3 : Inventory::unregistered_duplicates(const std::set<std::string> &registered_identities) const
     107             : {
     108           3 :     std::map<std::string, std::vector<Occurrence>> result;
     109           6 :     for (const auto &pair : group_by_identity())
     110             :     {
     111           3 :         if (pair.second.size() < 2) continue;
     112           2 :         if (registered_identities.count(pair.first) != 0) continue;
     113           1 :         result[pair.first] = pair.second;
     114           0 :     }
     115           3 :     return result;
     116           0 : }
     117             : 
     118             : } // namespace esys::repo::sharing

Generated by: LCOV version 1.14