KiCad PCB EDA Suite
Loading...
Searching...
No Matches
conn_component_cache.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include "conn_partition.h"
23#include "conn_cache.h"
24#include <algorithm>
25#include <memory>
26#include <stdexcept>
27#include <unordered_map>
28#include <utility>
29#include <vector>
30
31namespace SCH_CONNECTIVITY
32{
38template <typename VALUE>
40{
41public:
42 struct ENTRY
43 {
46 uint64_t version;
47 };
48
49 explicit COMPONENT_CACHE( CACHE_VERSIONS& aVersions ) :
50 m_versions( aVersions )
51 {
52 }
53 COMPONENT_CACHE( const COMPONENT_CACHE& ) = delete;
55
62 template <typename EVALUATE>
63 void UpdateBatch( std::span<const PARTITION> aPartitions, EVALUATE&& aEvaluate )
64 {
65 std::unordered_multimap<uint64_t, size_t> previous;
66 previous.reserve( m_entries.size() );
67
68 for( size_t i = 0; i < m_entries.size(); ++i )
69 previous.emplace( m_entries[i]->input.hash, i );
70
71 auto stale = std::exchange( m_entries, {} );
72 std::vector<std::unique_ptr<const ENTRY>> current( aPartitions.size() );
73 std::vector<const PARTITION*> missing;
74 std::vector<size_t> ordinals;
75
76 for( size_t ordinal = 0; ordinal < aPartitions.size(); ++ordinal )
77 {
78 const PARTITION& partition = aPartitions[ordinal];
79 const auto [begin, end] = previous.equal_range( partition.hash );
80 const auto found = std::find_if( begin, end,
81 [&]( const auto& aCandidate )
82 {
83 const auto& entry = stale[aCandidate.second];
84 return entry && entry->input == partition;
85 } );
86
87 if( found != end )
88 {
89 current[ordinal] = std::move( stale[found->second] );
90 }
91 else
92 {
93 missing.push_back( &partition );
94 ordinals.push_back( ordinal );
95 }
96 }
97
98 auto values = aEvaluate( missing );
99
100 if( values.size() != missing.size() )
101 throw std::logic_error( "Connectivity component batch returned an incorrect result count" );
102
103 for( size_t i = 0; i < missing.size(); ++i )
104 {
105 current[ordinals[i]] =
106 std::make_unique<const ENTRY>( ENTRY{ *missing[i], std::move( values[i] ), m_versions.Next() } );
107 }
108
109 m_entries = std::move( current );
110 }
111
112 const auto& Entries() const { return m_entries; }
113 void Clear() { m_entries.clear(); }
114
115private:
117 std::vector<std::unique_ptr<const ENTRY>> m_entries;
118};
119} // namespace SCH_CONNECTIVITY
One sequence for all cache tables for the lifetime of an engine session.
Definition conn_cache.h:37
void UpdateBatch(std::span< const PARTITION > aPartitions, EVALUATE &&aEvaluate)
Main-thread update that evaluates only cache misses, returning values in the supplied partition order...
COMPONENT_CACHE(CACHE_VERSIONS &aVersions)
COMPONENT_CACHE(const COMPONENT_CACHE &)=delete
std::vector< std::unique_ptr< const ENTRY > > m_entries
COMPONENT_CACHE & operator=(const COMPONENT_CACHE &)=delete
Value keys and the key session of the schematic connectivity engine.
Exact identity of one connected component.
@ VALUE
Field Value of part, i.e. "3.3K".
VECTOR2I end