1 /*
2 * CVirtualNet.cc
3 *
4 * Copyright 2014-2020 D. Mitch Bailey cvc at shuharisystem dot com
5 *
6 * This file is part of cvc.
7 *
8 * cvc is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * cvc is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with cvc. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * You can download cvc from https://github.com/d-m-bailey/cvc.git
22 */
23
24 #include "CVirtualNet.hh"
25 #include "mmappable_vector.h"
26
27 using namespace mmap_allocator_namespace;
28
29 extern long gVirtualNetUpdateCount;
30 extern long gVirtualNetAccessCount;
31
32
operator =(CVirtualNet & theEqualNet)33 void CVirtualNet::operator= (CVirtualNet& theEqualNet) {
34 nextNetId = theEqualNet.nextNetId;
35 resistance = theEqualNet.resistance;
36 finalNetId = theEqualNet.finalNetId;
37 finalResistance = theEqualNet.finalResistance;
38 backupNetId = theEqualNet.backupNetId;
39 }
40
operator ()(CVirtualNetVector & theVirtualNet_v,netId_t theNetId)41 CVirtualNet& CVirtualNet::operator() (CVirtualNetVector& theVirtualNet_v, netId_t theNetId) {
42 if ( theNetId == UNKNOWN_NET ) {
43 nextNetId = finalNetId = UNKNOWN_NET;
44 resistance = finalResistance = INFINITE_RESISTANCE;
45 } else {
46 gVirtualNetAccessCount++;
47 nextNetId = theVirtualNet_v[theNetId].nextNetId;
48 resistance = theVirtualNet_v[theNetId].resistance;
49 if ( theVirtualNet_v.lastUpdate_v.size() > 0
50 && theVirtualNet_v.lastUpdate_v[theNetId] < theVirtualNet_v.lastUpdate ) {
51 gVirtualNetUpdateCount++;
52 int myLinkCount = 0;
53 finalNetId = theNetId;
54 finalResistance = 0;
55 while ( finalNetId != theVirtualNet_v[finalNetId].nextNetId ) {
56 AddResistance(finalResistance, theVirtualNet_v[finalNetId].resistance);
57 finalNetId = theVirtualNet_v[finalNetId].nextNetId;
58 myLinkCount++;
59 if ( myLinkCount > 5000 ) {
60 cout << "looping at net " << finalNetId << endl;
61 assert ( myLinkCount < 5021 );
62 }
63 }
64 AddResistance(finalResistance, theVirtualNet_v[finalNetId].resistance);
65 theVirtualNet_v[theNetId].finalNetId = finalNetId;
66 theVirtualNet_v[theNetId].finalResistance = finalResistance;
67 theVirtualNet_v.lastUpdate_v[theNetId] = theVirtualNet_v.lastUpdate;
68 } else {
69 finalNetId = theVirtualNet_v[theNetId].finalNetId;
70 finalResistance = theVirtualNet_v[theNetId].finalResistance;
71 }
72 assert(finalResistance < MAX_RESISTANCE);
73 }
74 return (*this);
75 }
76
CVirtualNetMappedVector(mmap_allocator<CVirtualNet> theAllocator)77 CVirtualNetMappedVector::CVirtualNetMappedVector(mmap_allocator<CVirtualNet> theAllocator) :
78 mmappable_vector(theAllocator) {
79 }
80
operator =(CVirtualNetVector & theSourceVector)81 void CVirtualNetMappedVector::operator= (CVirtualNetVector& theSourceVector) {
82 mmap_file(theSourceVector.size());
83 assign(theSourceVector.begin(), theSourceVector.end());
84 remmap_file_for_read();
85 }
86
Set(netId_t theNetId,netId_t theNextNet,resistance_t theResistance,eventKey_t theTime)87 void CVirtualNetVector::Set(netId_t theNetId, netId_t theNextNet, resistance_t theResistance, eventKey_t theTime) {
88 if ( (*this)[theNextNet].nextNetId == theNetId && theNextNet != theNetId ) {
89 cout << "DEBUG: The next net of " << theNetId << " is already set to " << theNextNet << endl;
90 return;
91 }
92 (*this)[theNetId].nextNetId = theNextNet;
93 (*this)[theNetId].resistance = theResistance;
94 netId_t myFinalNetId;
95 resistance_t myFinalResistance;
96 if ( (*this)[theNetId].nextNetId == UNKNOWN_NET ) {
97 myFinalNetId = UNKNOWN_NET;
98 myFinalResistance = INFINITE_RESISTANCE;
99 } else {
100 int myLinkCount = 0;
101 myFinalNetId = theNetId;
102 myFinalResistance = 0;
103 while ( myFinalNetId != (*this)[myFinalNetId].nextNetId ) {
104 assert ((*this)[myFinalNetId].resistance >= 0);
105 AddResistance(myFinalResistance, (*this)[myFinalNetId].resistance);
106 myFinalNetId = (*this)[myFinalNetId].nextNetId;
107 myLinkCount++;
108 if ( myLinkCount > 5000 ) {
109 cout << "looping at net " << myFinalNetId << endl;
110 cout << "DEBUG: linking " << theNetId << " to " << theNextNet << endl;
111 assert ( myLinkCount < 5021 );
112 }
113 }
114 assert ((*this)[myFinalNetId].resistance >= 0);
115 AddResistance(myFinalResistance, (*this)[myFinalNetId].resistance);
116 }
117 (*this)[theNetId].finalNetId = myFinalNetId;
118 (*this)[theNetId].finalResistance = myFinalResistance;
119 lastUpdate = theTime;
120 (*this).lastUpdate_v[theNetId] = theTime;
121 }
122
Copy(const CVirtualNet & theBase)123 void CVirtualNet::Copy(const CVirtualNet& theBase) {
124 nextNetId = theBase.nextNetId;
125 resistance = theBase.resistance;
126 finalNetId = theBase.finalNetId;
127 finalResistance = theBase.finalResistance;
128 }
129
Print(ostream & theOutputFile)130 void CVirtualNet::Print(ostream& theOutputFile) {
131 theOutputFile << "Next net(R) " << nextNetId << "(" << resistance << ")";
132 theOutputFile << " final net(R) " << finalNetId << "(" << finalResistance << ")" << endl;
133 }
134
Print(string theTitle,string theIndentation)135 void CVirtualNetVector::Print(string theTitle, string theIndentation) {
136 cout << theIndentation << "VirtualNetVector" << theTitle << "> start " << size() << endl;
137 for ( netId_t net_it = 0; net_it < size(); net_it++ ) {
138 if ( net_it != (*this)[net_it].nextNetId ) {
139 cout << theIndentation + " " << net_it << "->" << (*this)[net_it].nextNetId << "@" << (*this)[net_it].resistance << endl;
140 }
141 }
142 cout << theIndentation << "VirtualNetVector" << theTitle << "> end" << endl;
143 }
144
DebugVirtualNet(netId_t theNetId,string theTitle,ostream & theOutputFile)145 void CVirtualNetVector::DebugVirtualNet(netId_t theNetId, string theTitle, ostream& theOutputFile) {
146 theOutputFile << theTitle << endl;
147 theOutputFile << theNetId << endl;
148 while ( theNetId != (*this)[theNetId].nextNetId ) {
149 theOutputFile << "->" << (*this)[theNetId].nextNetId << " r=" << (*this)[theNetId].resistance << endl;
150 theNetId = (*this)[theNetId].nextNetId;
151 }
152 theOutputFile << "-> last r=" << (*this)[theNetId].resistance << endl;
153 theOutputFile << endl;
154 }
155
BackupVirtualNets()156 void CVirtualNetVector::BackupVirtualNets() {
157 for ( auto net_pit = begin(); net_pit != end(); net_pit++ ) {
158 net_pit->backupNetId = net_pit->nextNetId;
159 }
160 }
161