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