1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 // list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 // this list of conditions and the following disclaimer in the documentation
15 // and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32
33 #include "dbBTerm.h"
34
35 #include "db.h"
36 #include "dbArrayTable.h"
37 #include "dbBPinItr.h"
38 #include "dbBlock.h"
39 #include "dbBlockCallBackObj.h"
40 #include "dbBox.h"
41 #include "dbBoxItr.h"
42 #include "dbChip.h"
43 #include "dbCommon.h"
44 #include "dbDatabase.h"
45 #include "dbDiff.h"
46 #include "dbDiff.hpp"
47 #include "dbITerm.h"
48 #include "dbJournal.h"
49 #include "dbNet.h"
50 #include "dbShape.h"
51 #include "dbTable.h"
52 #include "dbTable.hpp"
53 #include "dbTransform.h"
54 #include "utl/Logger.h"
55
56 namespace odb {
57
58 template class dbTable<_dbBTerm>;
59
_dbBTerm(_dbDatabase *)60 _dbBTerm::_dbBTerm(_dbDatabase*)
61 {
62 _flags._io_type = dbIoType::INPUT;
63 _flags._sig_type = dbSigType::SIGNAL;
64 _flags._orient = 0;
65 _flags._status = 0;
66 _flags._spef = 0;
67 _flags._special = 0;
68 _flags._mark = 0;
69 _flags._spare_bits = 0;
70 _ext_id = 0;
71 _name = 0;
72 _sta_vertex_id = 0;
73 }
74
_dbBTerm(_dbDatabase *,const _dbBTerm & b)75 _dbBTerm::_dbBTerm(_dbDatabase*, const _dbBTerm& b)
76 : _flags(b._flags),
77 _ext_id(b._ext_id),
78 _name(NULL),
79 _next_entry(b._next_entry),
80 _net(b._net),
81 _next_bterm(b._next_bterm),
82 _prev_bterm(b._prev_bterm),
83 _parent_block(b._parent_block),
84 _parent_iterm(b._parent_iterm),
85 _bpins(b._bpins),
86 _ground_pin(b._ground_pin),
87 _supply_pin(b._supply_pin),
88 _sta_vertex_id(0)
89 {
90 if (b._name) {
91 _name = strdup(b._name);
92 ZALLOCATED(_name);
93 }
94 }
95
~_dbBTerm()96 _dbBTerm::~_dbBTerm()
97 {
98 if (_name)
99 free((void*) _name);
100 }
101
operator <(const _dbBTerm & rhs) const102 bool _dbBTerm::operator<(const _dbBTerm& rhs) const
103 {
104 return strcmp(_name, rhs._name) < 0;
105 }
106
operator ==(const _dbBTerm & rhs) const107 bool _dbBTerm::operator==(const _dbBTerm& rhs) const
108 {
109 if (_flags._io_type != rhs._flags._io_type)
110 return false;
111
112 if (_flags._sig_type != rhs._flags._sig_type)
113 return false;
114
115 if (_flags._spef != rhs._flags._spef)
116 return false;
117
118 if (_flags._special != rhs._flags._special)
119 return false;
120
121 if (_ext_id != rhs._ext_id)
122 return false;
123
124 if (_name && rhs._name) {
125 if (strcmp(_name, rhs._name) != 0)
126 return false;
127 } else if (_name || rhs._name)
128 return false;
129
130 if (_next_entry != rhs._next_entry)
131 return false;
132
133 if (_net != rhs._net)
134 return false;
135
136 if (_next_bterm != rhs._next_bterm)
137 return false;
138
139 if (_prev_bterm != rhs._prev_bterm)
140 return false;
141
142 if (_parent_block != rhs._parent_block)
143 return false;
144
145 if (_parent_iterm != rhs._parent_iterm)
146 return false;
147
148 if (_bpins != rhs._bpins)
149 return false;
150
151 if (_ground_pin != rhs._ground_pin)
152 return false;
153
154 if (_supply_pin != rhs._supply_pin)
155 return false;
156
157 return true;
158 }
159
differences(dbDiff & diff,const char * field,const _dbBTerm & rhs) const160 void _dbBTerm::differences(dbDiff& diff,
161 const char* field,
162 const _dbBTerm& rhs) const
163 {
164 _dbBlock* lhs_blk = (_dbBlock*) getOwner();
165 _dbBlock* rhs_blk = (_dbBlock*) rhs.getOwner();
166
167 DIFF_BEGIN
168 DIFF_FIELD(_name);
169 DIFF_FIELD(_flags._io_type);
170 DIFF_FIELD(_flags._sig_type);
171 DIFF_FIELD(_flags._spef);
172 DIFF_FIELD(_flags._special);
173 DIFF_FIELD(_ext_id);
174 DIFF_FIELD_NO_DEEP(_next_entry);
175
176 if (!diff.deepDiff()) {
177 DIFF_FIELD(_net);
178 } else {
179 _dbNet* lhs_net = lhs_blk->_net_tbl->getPtr(_net);
180 _dbNet* rhs_net = rhs_blk->_net_tbl->getPtr(rhs._net);
181
182 if (strcmp(lhs_net->_name, rhs_net->_name) != 0) {
183 diff.report("< _net %s\n", lhs_net->_name);
184 diff.report("> _net %s\n", rhs_net->_name);
185 }
186 }
187
188 DIFF_FIELD_NO_DEEP(_next_bterm);
189 DIFF_FIELD_NO_DEEP(_prev_bterm);
190 DIFF_FIELD_NO_DEEP(_parent_block);
191 DIFF_FIELD_NO_DEEP(_parent_iterm);
192 DIFF_FIELD_NO_DEEP(_bpins);
193 DIFF_FIELD_NO_DEEP(_ground_pin);
194 DIFF_FIELD_NO_DEEP(_supply_pin);
195 DIFF_END
196 }
197
out(dbDiff & diff,char side,const char * field) const198 void _dbBTerm::out(dbDiff& diff, char side, const char* field) const
199 {
200 _dbBlock* blk = (_dbBlock*) getOwner();
201
202 DIFF_OUT_BEGIN
203 DIFF_OUT_FIELD(_name);
204 DIFF_OUT_FIELD(_flags._io_type);
205 DIFF_OUT_FIELD(_flags._sig_type);
206 DIFF_OUT_FIELD(_flags._spef);
207 DIFF_OUT_FIELD(_flags._special);
208 DIFF_OUT_FIELD(_ext_id);
209 DIFF_OUT_FIELD_NO_DEEP(_next_entry);
210
211 if (!diff.deepDiff()) {
212 DIFF_OUT_FIELD(_net);
213 } else {
214 _dbNet* net = blk->_net_tbl->getPtr(_net);
215 diff.report("%c _net %s\n", side, net->_name);
216 }
217
218 DIFF_OUT_FIELD_NO_DEEP(_next_bterm);
219 DIFF_OUT_FIELD_NO_DEEP(_prev_bterm);
220 DIFF_OUT_FIELD_NO_DEEP(_parent_block);
221 DIFF_OUT_FIELD_NO_DEEP(_parent_iterm);
222 DIFF_OUT_FIELD_NO_DEEP(_bpins);
223 DIFF_OUT_FIELD_NO_DEEP(_ground_pin);
224 DIFF_OUT_FIELD_NO_DEEP(_supply_pin);
225 DIFF_END
226 }
227
operator <<(dbOStream & stream,const _dbBTerm & bterm)228 dbOStream& operator<<(dbOStream& stream, const _dbBTerm& bterm)
229 {
230 uint* bit_field = (uint*) &bterm._flags;
231 stream << *bit_field;
232 stream << bterm._ext_id;
233 stream << bterm._name;
234 stream << bterm._next_entry;
235 stream << bterm._net;
236 stream << bterm._next_bterm;
237 stream << bterm._prev_bterm;
238 stream << bterm._parent_block;
239 stream << bterm._parent_iterm;
240 stream << bterm._bpins;
241 stream << bterm._ground_pin;
242 stream << bterm._supply_pin;
243 return stream;
244 }
245
operator >>(dbIStream & stream,_dbBTerm & bterm)246 dbIStream& operator>>(dbIStream& stream, _dbBTerm& bterm)
247 {
248 uint* bit_field = (uint*) &bterm._flags;
249 stream >> *bit_field;
250 stream >> bterm._ext_id;
251 stream >> bterm._name;
252 stream >> bterm._next_entry;
253 stream >> bterm._net;
254 stream >> bterm._next_bterm;
255 stream >> bterm._prev_bterm;
256 stream >> bterm._parent_block;
257 stream >> bterm._parent_iterm;
258 stream >> bterm._bpins;
259 stream >> bterm._ground_pin;
260 stream >> bterm._supply_pin;
261
262 return stream;
263 }
264
265 ////////////////////////////////////////////////////////////////////
266 //
267 // dbBTerm - Methods
268 //
269 ////////////////////////////////////////////////////////////////////
270
getName()271 std::string dbBTerm::getName()
272 {
273 _dbBTerm* bterm = (_dbBTerm*) this;
274 return bterm->_name;
275 }
276
getConstName()277 const char* dbBTerm::getConstName()
278 {
279 _dbBTerm* bterm = (_dbBTerm*) this;
280 return bterm->_name;
281 }
282
rename(const char * name)283 bool dbBTerm::rename(const char* name)
284 {
285 _dbBTerm* bterm = (_dbBTerm*) this;
286 _dbBlock* block = (_dbBlock*) getBlock();
287
288 if (block->_bterm_hash.hasMember(name))
289 return false;
290
291 block->_bterm_hash.remove(bterm);
292 free((void*) bterm->_name);
293 bterm->_name = strdup(name);
294 ZALLOCATED(bterm->_name);
295 block->_bterm_hash.insert(bterm);
296
297 return true;
298 }
299
setSigType(dbSigType type)300 void dbBTerm::setSigType(dbSigType type)
301 {
302 _dbBTerm* bterm = (_dbBTerm*) this;
303 _dbBlock* block = (_dbBlock*) getBlock();
304 uint prev_flags = flagsToUInt(bterm);
305
306 bterm->_flags._sig_type = type.getValue();
307
308 if (block->_journal) {
309 debugPrint(getImpl()->getLogger(),
310 utl::ODB,
311 "DB_ECO",
312 1,
313 "ECO: setSigType {}",
314 type.getValue());
315 block->_journal->updateField(
316 this, _dbBTerm::FLAGS, prev_flags, flagsToUInt(bterm));
317 }
318 }
319
getSigType()320 dbSigType dbBTerm::getSigType()
321 {
322 _dbBTerm* bterm = (_dbBTerm*) this;
323 return dbSigType(bterm->_flags._sig_type);
324 }
325
setIoType(dbIoType type)326 void dbBTerm::setIoType(dbIoType type)
327 {
328 _dbBTerm* bterm = (_dbBTerm*) this;
329 _dbBlock* block = (_dbBlock*) getBlock();
330 uint prev_flags = flagsToUInt(bterm);
331
332 bterm->_flags._io_type = type.getValue();
333
334 if (block->_journal) {
335 debugPrint(getImpl()->getLogger(),
336 utl::ODB,
337 "DB_ECO",
338 1,
339 "ECO: setIoType {}",
340 type.getValue());
341 block->_journal->updateField(
342 this, _dbBTerm::FLAGS, prev_flags, flagsToUInt(bterm));
343 }
344 }
345
getIoType()346 dbIoType dbBTerm::getIoType()
347 {
348 _dbBTerm* bterm = (_dbBTerm*) this;
349 return dbIoType(bterm->_flags._io_type);
350 }
351
setSpefMark(uint v)352 void dbBTerm::setSpefMark(uint v)
353 {
354 _dbBTerm* bterm = (_dbBTerm*) this;
355 bterm->_flags._spef = v;
356 }
isSetSpefMark()357 bool dbBTerm::isSetSpefMark()
358 {
359 _dbBTerm* bterm = (_dbBTerm*) this;
360 return bterm->_flags._spef > 0 ? true : false;
361 }
isSpecial() const362 bool dbBTerm::isSpecial() const
363 {
364 _dbBTerm* bterm = (_dbBTerm*) this;
365 return bterm->_flags._special > 0 ? true : false;
366 }
setSpecial()367 void dbBTerm::setSpecial()
368 {
369 _dbBTerm* bterm = (_dbBTerm*) this;
370 bterm->_flags._special = 1;
371 }
setMark(uint v)372 void dbBTerm::setMark(uint v)
373 {
374 _dbBTerm* bterm = (_dbBTerm*) this;
375 bterm->_flags._mark = v;
376 }
isSetMark()377 bool dbBTerm::isSetMark()
378 {
379 _dbBTerm* bterm = (_dbBTerm*) this;
380 return bterm->_flags._mark > 0 ? true : false;
381 }
setExtId(uint v)382 void dbBTerm::setExtId(uint v)
383 {
384 _dbBTerm* bterm = (_dbBTerm*) this;
385 bterm->_ext_id = v;
386 }
getExtId()387 uint dbBTerm::getExtId()
388 {
389 _dbBTerm* bterm = (_dbBTerm*) this;
390 return bterm->_ext_id;
391 }
392
getNet()393 dbNet* dbBTerm::getNet()
394 {
395 _dbBTerm* bterm = (_dbBTerm*) this;
396 if (bterm->_net) {
397 _dbBlock* block = (_dbBlock*) getBlock();
398 _dbNet* net = block->_net_tbl->getPtr(bterm->_net);
399 return (dbNet*) net;
400 } else
401 return nullptr;
402 }
403
connect(dbNet * net_)404 void dbBTerm::connect(dbNet* net_)
405 {
406 _dbBTerm* bterm = (_dbBTerm*) this;
407 _dbNet* net = (_dbNet*) net_;
408 _dbBlock* block = (_dbBlock*) net->getOwner();
409
410 if (block->_journal) {
411 debugPrint(block->getImpl()->getLogger(),
412 utl::ODB,
413 "DB_ECO",
414 1,
415 "ECO: connect Bterm {} to net {}",
416 bterm->getId(),
417 net_->getId());
418 block->_journal->beginAction(dbJournal::CONNECT_OBJECT);
419 block->_journal->pushParam(dbBTermObj);
420 block->_journal->pushParam(bterm->getId());
421 block->_journal->pushParam(net_->getId());
422 block->_journal->endAction();
423 }
424
425 if (bterm->_net)
426 bterm->disconnectNet(bterm, block);
427 bterm->connectNet(net, block);
428 }
429
disconnect()430 void dbBTerm::disconnect()
431 {
432 _dbBTerm* bterm = (_dbBTerm*) this;
433 if (bterm->_net) {
434 _dbBlock* block = (_dbBlock*) bterm->getOwner();
435
436 if (block->_journal) {
437 debugPrint(block->getImpl()->getLogger(),
438 utl::ODB,
439 "DB_ECO",
440 1,
441 "ECO: disconnect Iterm {}",
442 bterm->getId());
443 block->_journal->beginAction(dbJournal::DISCONNECT_OBJECT);
444 block->_journal->pushParam(dbBTermObj);
445 block->_journal->pushParam(bterm->getId());
446 block->_journal->endAction();
447 }
448
449 bterm->disconnectNet(bterm, block);
450 }
451 }
452
getBPins()453 dbSet<dbBPin> dbBTerm::getBPins()
454 {
455 //_dbBTerm * bterm = (_dbBTerm *) this;
456 _dbBlock* block = (_dbBlock*) getBlock();
457 dbSet<dbBPin> bpins(this, block->_bpin_itr);
458 return bpins;
459 }
460
getITerm()461 dbITerm* dbBTerm::getITerm()
462 {
463 _dbBTerm* bterm = (_dbBTerm*) this;
464 _dbBlock* block = (_dbBlock*) getBlock();
465
466 if (bterm->_parent_block == 0)
467 return NULL;
468
469 _dbChip* chip = (_dbChip*) block->getOwner();
470 _dbBlock* parent = chip->_block_tbl->getPtr(bterm->_parent_block);
471 return (dbITerm*) parent->_iterm_tbl->getPtr(bterm->_parent_iterm);
472 }
473
getBlock()474 dbBlock* dbBTerm::getBlock()
475 {
476 return (dbBlock*) getImpl()->getOwner();
477 }
478
getBBox()479 Rect dbBTerm::getBBox()
480 {
481 Rect bbox;
482 bbox.mergeInit();
483 for (dbBPin* pin : getBPins()) {
484 bbox.merge(pin->getBBox());
485 }
486 return bbox;
487 }
488
getFirstPin(dbShape & shape)489 bool dbBTerm::getFirstPin(dbShape& shape)
490 {
491 dbSet<dbBPin> bpins = getBPins();
492 dbSet<dbBPin>::iterator bpin_itr;
493 for (bpin_itr = bpins.begin(); bpin_itr != bpins.end(); ++bpin_itr) {
494 dbBPin* bpin = *bpin_itr;
495
496 for (dbBox* box : bpin->getBoxes()) {
497 if (bpin->getPlacementStatus() == dbPlacementStatus::UNPLACED
498 || bpin->getPlacementStatus() == dbPlacementStatus::NONE
499 || box == NULL)
500 continue;
501
502 if (box->isVia()) // This is not possible...
503 continue;
504
505 Rect r;
506 box->getBox(r);
507 shape.setSegment(box->getTechLayer(), r);
508 return true;
509 }
510 }
511
512 return false;
513 }
514
getFirstPinPlacementStatus()515 dbPlacementStatus dbBTerm::getFirstPinPlacementStatus()
516 {
517 dbSet<dbBPin> bpins = getBPins();
518 auto bpin_itr = bpins.begin();
519 if (bpin_itr != bpins.end()) {
520 dbBPin* bpin = *bpin_itr;
521 return bpin->getPlacementStatus();
522 }
523
524 return dbPlacementStatus::NONE;
525 }
526
getFirstPinLocation(int & x,int & y)527 bool dbBTerm::getFirstPinLocation(int& x, int& y)
528 {
529 dbSet<dbBPin> bpins = getBPins();
530 dbSet<dbBPin>::iterator bpin_itr;
531 for (bpin_itr = bpins.begin(); bpin_itr != bpins.end(); ++bpin_itr) {
532 dbBPin* bpin = *bpin_itr;
533
534 dbSet<dbBox> boxes = bpin->getBoxes();
535 dbSet<dbBox>::iterator boxItr;
536
537 for (boxItr = boxes.begin(); boxItr != boxes.end(); ++boxItr) {
538 dbBox* box = *boxItr;
539 if (bpin->getPlacementStatus() == dbPlacementStatus::UNPLACED
540 || bpin->getPlacementStatus() == dbPlacementStatus::NONE
541 || box == NULL)
542 continue;
543
544 if (box->isVia()) // This is not possible...
545 continue;
546
547 Rect r;
548 box->getBox(r);
549 x = r.xMin() + (int) (r.dx() >> 1U);
550 y = r.yMin() + (int) (r.dy() >> 1U);
551 return true;
552 }
553 }
554
555 x = 0;
556 y = 0;
557 return false;
558 }
559
getGroundPin()560 dbBTerm* dbBTerm::getGroundPin()
561 {
562 _dbBTerm* bterm = (_dbBTerm*) this;
563 _dbBlock* block = (_dbBlock*) getBlock();
564
565 if (bterm->_ground_pin == 0)
566 return NULL;
567
568 _dbBTerm* ground = block->_bterm_tbl->getPtr(bterm->_ground_pin);
569 return (dbBTerm*) ground;
570 }
571
setGroundPin(dbBTerm * pin)572 void dbBTerm::setGroundPin(dbBTerm* pin)
573 {
574 _dbBTerm* bterm = (_dbBTerm*) this;
575 bterm->_ground_pin = pin->getImpl()->getOID();
576 }
577
getSupplyPin()578 dbBTerm* dbBTerm::getSupplyPin()
579 {
580 _dbBTerm* bterm = (_dbBTerm*) this;
581 _dbBlock* block = (_dbBlock*) getBlock();
582
583 if (bterm->_supply_pin == 0)
584 return NULL;
585
586 _dbBTerm* supply = block->_bterm_tbl->getPtr(bterm->_supply_pin);
587 return (dbBTerm*) supply;
588 }
589
setSupplyPin(dbBTerm * pin)590 void dbBTerm::setSupplyPin(dbBTerm* pin)
591 {
592 _dbBTerm* bterm = (_dbBTerm*) this;
593 bterm->_supply_pin = pin->getImpl()->getOID();
594 }
595
create(dbNet * net_,const char * name)596 dbBTerm* dbBTerm::create(dbNet* net_, const char* name)
597 {
598 _dbNet* net = (_dbNet*) net_;
599 _dbBlock* block = (_dbBlock*) net->getOwner();
600
601 if (block->_bterm_hash.hasMember(name))
602 return NULL;
603
604 if (block->_journal) {
605 debugPrint(block->getImpl()->getLogger(),
606 utl::ODB,
607 "DB_ECO",
608 1,
609 "ECO: dbBTerm:create");
610 block->_journal->beginAction(dbJournal::CREATE_OBJECT);
611 block->_journal->pushParam(dbBTermObj);
612 block->_journal->pushParam(net->getId());
613 block->_journal->pushParam(name);
614 block->_journal->endAction();
615 }
616
617 _dbBTerm* bterm = block->_bterm_tbl->create();
618 bterm->_name = strdup(name);
619 ZALLOCATED(bterm->_name);
620 block->_bterm_hash.insert(bterm);
621 for (auto callback : block->_callbacks)
622 callback->inDbBTermCreate((dbBTerm*) bterm);
623 bterm->connectNet(net, block);
624
625 return (dbBTerm*) bterm;
626 }
627
connectNet(_dbNet * net,_dbBlock * block)628 void _dbBTerm::connectNet(_dbNet* net, _dbBlock* block)
629 {
630 for (auto callback : block->_callbacks)
631 callback->inDbBTermPreConnect((dbBTerm*) this, (dbNet*) net);
632 _net = net->getOID();
633 if (net->_bterms != 0) {
634 _dbBTerm* tail = block->_bterm_tbl->getPtr(net->_bterms);
635 _next_bterm = net->_bterms;
636 tail->_prev_bterm = getOID();
637 } else
638 _next_bterm = 0;
639 _prev_bterm = 0;
640 net->_bterms = getOID();
641 for (auto callback : block->_callbacks)
642 callback->inDbBTermPostConnect((dbBTerm*) this);
643 }
644
destroy(dbBTerm * bterm_)645 void dbBTerm::destroy(dbBTerm* bterm_)
646 {
647 _dbBTerm* bterm = (_dbBTerm*) bterm_;
648 _dbBlock* block = (_dbBlock*) bterm->getOwner();
649
650 // delete bpins
651 dbSet<dbBPin> bpins = bterm_->getBPins();
652 dbSet<dbBPin>::iterator itr;
653
654 for (itr = bpins.begin(); itr != bpins.end();) {
655 itr = dbBPin::destroy(itr);
656 }
657 if (bterm->_net)
658 bterm->disconnectNet(bterm, block);
659 for (auto callback : block->_callbacks)
660 callback->inDbBTermDestroy(bterm_);
661 // remove from hash-table
662
663 if (block->_journal) {
664 debugPrint(block->getImpl()->getLogger(),
665 utl::ODB,
666 "DB_ECO",
667 1,
668 "ECO: dbBTerm:destroy");
669 block->_journal->beginAction(dbJournal::DELETE_OBJECT);
670 block->_journal->pushParam(dbBTermObj);
671 block->_journal->pushParam(bterm_->getId());
672 block->_journal->endAction();
673 }
674
675 block->_bterm_hash.remove(bterm);
676 dbProperty::destroyProperties(bterm);
677 block->_bterm_tbl->destroy(bterm);
678 }
679
disconnectNet(_dbBTerm * bterm,_dbBlock * block)680 void _dbBTerm::disconnectNet(_dbBTerm* bterm, _dbBlock* block)
681 {
682 // unlink bterm from the net
683 for (auto callback : block->_callbacks)
684 callback->inDbBTermPreDisconnect((dbBTerm*) this);
685 _dbNet* net = block->_net_tbl->getPtr(bterm->_net);
686 uint id = bterm->getOID();
687
688 if (net->_bterms == id) {
689 net->_bterms = bterm->_next_bterm;
690
691 if (net->_bterms != 0) {
692 _dbBTerm* t = block->_bterm_tbl->getPtr(net->_bterms);
693 t->_prev_bterm = 0;
694 }
695 } else {
696 if (bterm->_next_bterm != 0) {
697 _dbBTerm* next = block->_bterm_tbl->getPtr(bterm->_next_bterm);
698 next->_prev_bterm = bterm->_prev_bterm;
699 }
700
701 if (bterm->_prev_bterm != 0) {
702 _dbBTerm* prev = block->_bterm_tbl->getPtr(bterm->_prev_bterm);
703 prev->_next_bterm = bterm->_next_bterm;
704 }
705 }
706 _net = 0;
707 for (auto callback : block->_callbacks)
708 callback->inDbBTermPostDisConnect((dbBTerm*) this, (dbNet*) net);
709 }
710
destroy(dbSet<dbBTerm>::iterator & itr)711 dbSet<dbBTerm>::iterator dbBTerm::destroy(dbSet<dbBTerm>::iterator& itr)
712 {
713 dbBTerm* bt = *itr;
714 dbSet<dbBTerm>::iterator next = ++itr;
715 destroy(bt);
716 return next;
717 }
718
getBTerm(dbBlock * block_,uint dbid_)719 dbBTerm* dbBTerm::getBTerm(dbBlock* block_, uint dbid_)
720 {
721 _dbBlock* block = (_dbBlock*) block_;
722 return (dbBTerm*) block->_bterm_tbl->getPtr(dbid_);
723 }
724
staVertexId()725 uint32_t dbBTerm::staVertexId()
726 {
727 _dbBTerm* iterm = (_dbBTerm*) this;
728 return iterm->_sta_vertex_id;
729 }
730
staSetVertexId(uint32_t id)731 void dbBTerm::staSetVertexId(uint32_t id)
732 {
733 _dbBTerm* iterm = (_dbBTerm*) this;
734 iterm->_sta_vertex_id = id;
735 }
736
737 } // namespace odb
738