44 uint64_t islandVersion = 0;
45 uint64_t recordVersion = 0;
46 std::unique_ptr<ISLAND_AUX> value;
51 std::optional<RULE_AREA_RESULT> value;
53 std::vector<std::pair<RECORD_KEY, ISLAND_STAGE>> islands;
54 std::map<ITEM_KEY, AREA_STAGE, KEY_LESS> areas(
KEY_LESS{
m_keys } );
55 std::set<INST_ID> instances;
57 std::map<SCREEN_ID, std::vector<KIID>> sourceChanges;
59 std::vector<const FRAME_INSTANCE*> frames;
60 frames.reserve( aFrame.size() );
63 frames.push_back( &frame );
66 std::sort( frames.begin(), frames.end(),
69 return m_keys.Instance( a->scope.instance ) < m_keys.Instance( b->scope.instance );
72 auto recordPosition = aRecords.
Entries().begin();
82 throw std::invalid_argument(
"Auxiliary publication requires captured instance facts" );
87 throw std::invalid_argument(
"Auxiliary publication requires captured screen facts" );
89 sourceVersion = std::max( { sourceVersion, screen->version, facts->version } );
91 instances.insert( instance );
96 for(
const ITEM_FACT& item : screen->value.items )
106 auto [changed, inserted] = sourceChanges.try_emplace( frame.
screen );
110 for(
const ITEM_FACT& item : screen->value.items )
112 const auto* source = aInputs.
Fact( { frame.
screen, item.
id } );
116 changed->second.push_back( item.
id );
119 changed->second.push_back(
pin.id );
124 for(
const KIID& item : changed->second )
133 const auto*
text = aInputs.
Text( { item.
id, instance } );
143 throw std::invalid_argument(
"Auxiliary publication requires captured islands" );
145 for(
const ISLAND& island : geometry->value.islands )
149 while( recordPosition != aRecords.
Entries().end() && less( recordPosition->first, key ) )
152 if( recordPosition == aRecords.
Entries().end() || recordPosition->first != key )
153 throw std::invalid_argument(
"Auxiliary island has no electrical record" );
155 const auto* record = recordPosition->second.get();
156 auto& stage = islands.emplace_back( key, ISLAND_STAGE{} ).second;
157 stage.islandVersion = geometry->version;
158 stage.recordVersion = record->version;
160 while( oldPosition !=
m_islands.cend() && less( oldPosition->first, key ) )
163 if( oldPosition !=
m_islands.cend() && oldPosition->first == key )
165 if( oldPosition->second.islandVersion == stage.islandVersion
166 && oldPosition->second.recordVersion == stage.recordVersion )
169 const ISLAND_AUX& value = oldPosition->second.value;
181 for(
const auto& area : facts->value.ruleAreas )
183 const ITEM_KEY key{ area.id, instance };
184 const auto* source = aInputs.
Area( key );
187 throw std::invalid_argument(
"Auxiliary rule area has no captured source" );
189 auto& stage = areas[key];
190 stage.version = source->version;
191 const auto old =
m_areas.find( key );
193 if( old !=
m_areas.end() && old->second.version == source->version )
196 RULE_AREA_RESULT value{ source->value.containedItems, source->value.attachedDirectives, {} };
198 for(
const wxString&
name : source->value.netclasses )
201 std::ranges::sort( value.netclasses,
NAME_LESS{ &m_keys } );
202 value.netclasses.erase( std::ranges::unique( value.netclasses ).begin(), value.netclasses.end() );
204 if( old ==
m_areas.end() || old->second.value != value )
205 stage.value = std::move( value );
209 auto replacement = islands.cbegin();
214 while( replacement != islands.cend() && less( replacement->first, it->first ) )
217 const bool removed = replacement == islands.cend() || less( it->first, replacement->first );
219 if( removed ||
bool( replacement->second.value ) )
223 for(
const KIID&
id : it->second.value.items )
225 const ITEM_KEY item{ id, it->first.inst };
240 for(
auto& [key, entry] : islands )
245 std::unordered_map<KIID, std::vector<KIID>*> neighborLists;
248 const auto appendNeighbor = [&](
const KIID& item,
const KIID& neighbor )
250 auto [found, inserted] = neighborLists.try_emplace( item,
nullptr );
255 found->second->push_back( neighbor );
258 for(
const auto& [first, second] : entry.value->adjacency )
260 appendNeighbor( first, second );
261 appendNeighbor( second, first );
264 for(
const KIID&
id : entry.value->items )
266 const ITEM_KEY item{ id, key.inst };
271 auto& values = neighbors->second;
272 std::sort( values.begin(), values.end() );
273 values.erase( std::unique( values.begin(), values.end() ), values.end() );
281 const auto current =
m_islands.try_emplace( hint, key );
282 hint = std::next( current );
283 auto& published = current->second;
284 published.islandVersion = entry.islandVersion;
285 published.recordVersion = entry.recordVersion;
288 published.value = std::move( *entry.value );
293 std::vector<KIID> items;
294 items.reserve( value.containedItems.size() + value.attachedDirectives.size() );
295 std::set_union( value.containedItems.begin(), value.containedItems.end(), value.attachedDirectives.begin(),
296 value.attachedDirectives.end(), std::back_inserter( items ) );
302 const auto updatedArea = areas.find( it->first );
303 const bool removed = updatedArea == areas.end();
305 if( removed || updatedArea->second.value.has_value() )
309 for(
const KIID&
id : areaItems( it->second.value ) )
311 const ITEM_KEY item{ id, it->first.inst };
316 std::erase( found->second, it->first.item );
318 if( found->second.empty() )
332 for(
auto& [key, entry] : areas )
338 for(
const KIID&
id : areaItems( *entry.value ) )
340 const ITEM_KEY item{ id, key.inst };
342 memberships.insert( std::lower_bound( memberships.begin(), memberships.end(), key.item ), key.item );
347 auto& published =
m_areas.try_emplace( key ).first->second;
348 published.version = entry.version;
351 published.value = std::move( *entry.value );
354 const auto canonicalize = [&](
auto& values )
357 values.erase( std::ranges::unique( values ).begin(), values.end() );