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 "dbCCSeg.h"
34
35 #include "db.h"
36 #include "dbBlock.h"
37 #include "dbCapNode.h"
38 #include "dbDatabase.h"
39 #include "dbJournal.h"
40 #include "dbNet.h"
41 #include "dbTable.h"
42 #include "dbTable.hpp"
43 #include "utl/Logger.h"
44
45 namespace odb {
46
47 template class dbTable<_dbCCSeg>;
48
operator ==(const _dbCCSeg & rhs) const49 bool _dbCCSeg::operator==(const _dbCCSeg& rhs) const
50 {
51 if (_flags._spef_mark_1 != rhs._flags._spef_mark_1)
52 return false;
53
54 if (_flags._mark != rhs._flags._mark)
55 return false;
56
57 if (_flags._inFileCnt != rhs._flags._inFileCnt)
58 return false;
59
60 if (_cap_node[0] != rhs._cap_node[0])
61 return false;
62
63 if (_cap_node[1] != rhs._cap_node[1])
64 return false;
65
66 if (_next[0] != rhs._next[0])
67 return false;
68
69 if (_next[1] != rhs._next[1])
70 return false;
71
72 return true;
73 }
74
differences(dbDiff & diff,const char * field,const _dbCCSeg & rhs) const75 void _dbCCSeg::differences(dbDiff& diff,
76 const char* field,
77 const _dbCCSeg& rhs) const
78 {
79 DIFF_BEGIN
80 DIFF_FIELD(_flags._spef_mark_1);
81 DIFF_FIELD(_flags._mark);
82 DIFF_FIELD(_flags._inFileCnt);
83 DIFF_FIELD(_cap_node[0]);
84 DIFF_FIELD(_cap_node[1]);
85 DIFF_FIELD(_next[0]);
86 DIFF_FIELD(_next[1]);
87 DIFF_END
88 }
89
out(dbDiff & diff,char side,const char * field) const90 void _dbCCSeg::out(dbDiff& diff, char side, const char* field) const
91 {
92 DIFF_OUT_BEGIN
93 DIFF_OUT_FIELD(_flags._spef_mark_1);
94 DIFF_OUT_FIELD(_flags._mark);
95 DIFF_OUT_FIELD(_flags._inFileCnt);
96 DIFF_OUT_FIELD(_cap_node[0]);
97 DIFF_OUT_FIELD(_cap_node[1]);
98 DIFF_OUT_FIELD(_next[0]);
99 DIFF_OUT_FIELD(_next[1]);
100 DIFF_END
101 }
102
103 ////////////////////////////////////////////////////////////////////
104 //
105 // dbCCSeg - Methods
106 //
107 ////////////////////////////////////////////////////////////////////
108
adjustCapacitance(float factor,int corner)109 void dbCCSeg::adjustCapacitance(float factor, int corner)
110 {
111 _dbCCSeg* seg = (_dbCCSeg*) this;
112 _dbBlock* block = (_dbBlock*) seg->getOwner();
113
114 float& value
115 = (*block->_cc_val_tbl)[(seg->getOID() - 1) * block->_corners_per_block
116 + 1 + corner];
117 float prev_value = value;
118 value *= factor;
119
120 if (block->_journal) {
121 debugPrint(getImpl()->getLogger(),
122 utl::ODB,
123 "DB_ECO",
124 1,
125 "ECO: dbCCSeg {}, adjustCapacitance {}, corner {}",
126 seg->getId(),
127 factor,
128 corner);
129 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
130 block->_journal->pushParam(dbCCSegObj);
131 block->_journal->pushParam(seg->getId());
132 block->_journal->pushParam(_dbCCSeg::CAPACITANCE);
133 block->_journal->pushParam(prev_value);
134 block->_journal->pushParam(value);
135 block->_journal->pushParam(0);
136 block->_journal->endAction();
137 }
138 }
139
adjustCapacitance(float factor)140 void dbCCSeg::adjustCapacitance(float factor)
141 {
142 _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
143 uint corner;
144 for (corner = 0; corner < block->_corners_per_block; corner++)
145 adjustCapacitance(factor, corner);
146 }
147
getCapacitance(int corner)148 double dbCCSeg::getCapacitance(int corner)
149 {
150 _dbCCSeg* seg = (_dbCCSeg*) this;
151 _dbBlock* block = (_dbBlock*) seg->getOwner();
152 uint cornerCnt = block->_corners_per_block;
153 ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
154 return (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
155 }
156
accAllCcCap(double * ttcap,double MillerMult)157 void dbCCSeg::accAllCcCap(double* ttcap, double MillerMult)
158 {
159 _dbCCSeg* seg = (_dbCCSeg*) this;
160 _dbBlock* block = (_dbBlock*) seg->getOwner();
161 uint cornerCnt = block->_corners_per_block;
162 for (uint ii = 0; ii < cornerCnt; ii++) {
163 ttcap[ii]
164 += ((*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii])
165 * MillerMult;
166 }
167 }
168
getAllCcCap(double * ttcap)169 void dbCCSeg::getAllCcCap(double* ttcap)
170 {
171 _dbCCSeg* seg = (_dbCCSeg*) this;
172 _dbBlock* block = (_dbBlock*) seg->getOwner();
173 uint cornerCnt = block->_corners_per_block;
174 for (uint ii = 0; ii < cornerCnt; ii++) {
175 ttcap[ii] = (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
176 }
177 }
178
setAllCcCap(double * ttcap)179 void dbCCSeg::setAllCcCap(double* ttcap)
180 {
181 _dbCCSeg* seg = (_dbCCSeg*) this;
182 _dbBlock* block = (_dbBlock*) seg->getOwner();
183 uint cornerCnt = block->_corners_per_block;
184 for (uint ii = 0; ii < cornerCnt; ii++) {
185 (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii] = ttcap[ii];
186 }
187 if (block->_journal) {
188 char ccCaps[400];
189 int pos = 0;
190 ccCaps[0] = '\0';
191 for (uint ii = 0; ii < cornerCnt; ii++)
192 pos += sprintf(&ccCaps[pos], "%f ", ttcap[ii]);
193 debugPrint(getImpl()->getLogger(),
194 utl::ODB,
195 "DB_ECO",
196 1,
197 "ECO: dbCCSeg::setAllCcCap, ccseg: {}, caps: {}",
198 seg->getId(),
199 ttcap[0]);
200 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
201 block->_journal->pushParam(dbCCSegObj);
202 block->_journal->pushParam(getId());
203 block->_journal->pushParam(_dbCCSeg::SETALLCCCAP);
204 for (uint ii = 0; ii < cornerCnt; ii++)
205 block->_journal->pushParam(ttcap[ii]);
206 block->_journal->endAction();
207 }
208 }
209
setCapacitance(double cap,int corner)210 void dbCCSeg::setCapacitance(double cap, int corner)
211 {
212 _dbCCSeg* seg = (_dbCCSeg*) this;
213 _dbBlock* block = (_dbBlock*) seg->getOwner();
214 uint cornerCnt = block->_corners_per_block;
215 ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
216
217 float& value
218 = (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
219 float prev_value = value;
220 value = (float) cap;
221
222 if (block->_journal) {
223 debugPrint(getImpl()->getLogger(),
224 utl::ODB,
225 "DB_ECO",
226 1,
227 "ECO: dbCCSeg {}, setCapacitance {}, corner {}",
228 seg->getId(),
229 value,
230 corner);
231 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
232 block->_journal->pushParam(dbCCSegObj);
233 block->_journal->pushParam(seg->getId());
234 block->_journal->pushParam(_dbCCSeg::CAPACITANCE);
235 block->_journal->pushParam(prev_value);
236 block->_journal->pushParam(value);
237 block->_journal->pushParam(corner);
238 block->_journal->endAction();
239 }
240 }
241
addCapacitance(double cap,int corner)242 void dbCCSeg::addCapacitance(double cap, int corner)
243 {
244 _dbCCSeg* seg = (_dbCCSeg*) this;
245 _dbBlock* block = (_dbBlock*) seg->getOwner();
246 uint cornerCnt = block->_corners_per_block;
247 ZASSERT((corner >= 0) && ((uint) corner < cornerCnt));
248
249 float& value
250 = (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + corner];
251 float prev_value = value;
252 value += (float) cap;
253
254 if (block->_journal) {
255 debugPrint(getImpl()->getLogger(),
256 utl::ODB,
257 "DB_ECO",
258 1,
259 "ECO: dbCCSeg {}, addCapacitance {}, corner {}",
260 seg->getId(),
261 value,
262 corner);
263 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
264 block->_journal->pushParam(dbCCSegObj);
265 block->_journal->pushParam(seg->getId());
266 block->_journal->pushParam(_dbCCSeg::CAPACITANCE);
267 block->_journal->pushParam(prev_value);
268 block->_journal->pushParam(value);
269 block->_journal->pushParam(corner);
270 block->_journal->endAction();
271 }
272 }
273
addCcCapacitance(dbCCSeg * other)274 void dbCCSeg::addCcCapacitance(dbCCSeg* other)
275 {
276 _dbCCSeg* seg = (_dbCCSeg*) this;
277 _dbBlock* block = (_dbBlock*) seg->getOwner();
278 _dbCCSeg* oseg = (_dbCCSeg*) other;
279 uint cornerCnt = block->_corners_per_block;
280
281 for (uint ii = 0; ii < cornerCnt; ii++) {
282 float& value
283 = (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii];
284 float& ovalue
285 = (*block->_cc_val_tbl)[(oseg->getOID() - 1) * cornerCnt + 1 + ii];
286 value += ovalue;
287 }
288
289 if (block->_journal) {
290 debugPrint(getImpl()->getLogger(),
291 utl::ODB,
292 "DB_ECO",
293 1,
294 "ECO: dbCCSeg {}, other dbCCSeg {}, addCcCapacitance",
295 seg->getOID(),
296 oseg->getOID());
297 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
298 block->_journal->pushParam(dbCCSegObj);
299 block->_journal->pushParam(seg->getId());
300 block->_journal->pushParam(_dbCCSeg::ADDCCCAPACITANCE);
301 block->_journal->pushParam(oseg->getId());
302 block->_journal->endAction();
303 }
304 }
305
getSourceCapNode()306 dbCapNode* dbCCSeg::getSourceCapNode()
307 {
308 _dbCCSeg* seg = (_dbCCSeg*) this;
309 _dbBlock* block = (_dbBlock*) seg->getOwner();
310 _dbCapNode* n = block->_cap_node_tbl->getPtr(seg->_cap_node[0]);
311 return (dbCapNode*) n;
312 }
313
getTargetCapNode()314 dbCapNode* dbCCSeg::getTargetCapNode()
315 {
316 _dbCCSeg* seg = (_dbCCSeg*) this;
317 _dbBlock* block = (_dbBlock*) seg->getOwner();
318 _dbCapNode* n = block->_cap_node_tbl->getPtr(seg->_cap_node[1]);
319 return (dbCapNode*) n;
320 }
321
getSourceNodeNum()322 uint dbCCSeg::getSourceNodeNum()
323 {
324 dbCapNode* n = getSourceCapNode();
325 return n->getNode();
326 }
327
328 /*
329 void
330 dbCCSeg::setSourceNode( uint source_node )
331 {
332 _dbCCSeg * seg = (_dbCCSeg *) this;
333 seg->_source_cap_node = source_node;
334 }
335 */
336
getTargetNodeNum()337 uint dbCCSeg::getTargetNodeNum()
338 {
339 dbCapNode* n = getTargetCapNode();
340 return n->getNode();
341 }
342
343 /*
344 void
345 dbCCSeg::setTargetNode( uint target_node )
346 {
347 _dbCCSeg * seg = (_dbCCSeg *) this;
348 seg->_target_cap_node = target_node;
349 }
350 */
351
getSourceNet()352 dbNet* dbCCSeg::getSourceNet()
353 {
354 dbCapNode* node = getSourceCapNode();
355 return node->getNet();
356 }
357
getTargetNet()358 dbNet* dbCCSeg::getTargetNet()
359 {
360 dbCapNode* node = getTargetCapNode();
361 return node->getNet();
362 }
363
getInfileCnt()364 uint dbCCSeg::getInfileCnt()
365 {
366 _dbCCSeg* seg = (_dbCCSeg*) this;
367 return (seg->_flags._inFileCnt);
368 }
369
incrInfileCnt()370 void dbCCSeg::incrInfileCnt()
371 {
372 _dbCCSeg* seg = (_dbCCSeg*) this;
373 seg->_flags._inFileCnt++;
374 }
375
isMarked()376 bool dbCCSeg::isMarked()
377 {
378 _dbCCSeg* seg = (_dbCCSeg*) this;
379 return seg->_flags._mark == 1;
380 }
381
setMark(bool value)382 void dbCCSeg::setMark(bool value)
383 {
384 _dbCCSeg* seg = (_dbCCSeg*) this;
385 seg->_flags._mark = (value == true) ? 1 : 0;
386 }
387
printCapnCC(uint capn)388 void dbCCSeg::printCapnCC(uint capn)
389 {
390 _dbCCSeg* seg = (_dbCCSeg*) this;
391 uint sidx;
392 if (capn == seg->_cap_node[0])
393 sidx = 0;
394 else if (capn == seg->_cap_node[1])
395 sidx = 1;
396 else {
397 debugPrint(getImpl()->getLogger(),
398 utl::ODB,
399 "DB_ECO",
400 1,
401 "ccSeg {} has capnd {} {}, not {} !",
402 getId(),
403 (uint) seg->_cap_node[0],
404 (uint) seg->_cap_node[1],
405 capn);
406 return;
407 }
408 getImpl()->getLogger()->info(
409 utl::ODB,
410 21,
411 " ccSeg={} capn0={} next0={} capn1={} next1={}",
412 getId(),
413 (uint) seg->_cap_node[0],
414 (uint) seg->_next[0],
415 (uint) seg->_cap_node[1],
416 (uint) seg->_next[1]);
417 if (seg->_next[sidx] == 0) {
418 return;
419 }
420 dbBlock* block = (dbBlock*) seg->getOwner();
421 dbCCSeg* nseg = getCCSeg(block, seg->_next[sidx]);
422 nseg->printCapnCC(capn);
423 }
424
checkCapnCC(uint capn)425 bool dbCCSeg::checkCapnCC(uint capn)
426 {
427 _dbCCSeg* seg = (_dbCCSeg*) this;
428 uint sidx;
429 if (capn == seg->_cap_node[0])
430 sidx = 0;
431 else if (capn == seg->_cap_node[1])
432 sidx = 1;
433 else {
434 getImpl()->getLogger()->info(utl::ODB,
435 22,
436 "ccSeg {} has capnd {} {}, not {} !",
437 getId(),
438 (uint) seg->_cap_node[0],
439 (uint) seg->_cap_node[1],
440 capn);
441 return false;
442 }
443 if (seg->_next[sidx] == 0) {
444 return true;
445 }
446 dbBlock* block = (dbBlock*) seg->getOwner();
447 dbCCSeg* nseg = getCCSeg(block, seg->_next[sidx]);
448 bool rc = nseg->checkCapnCC(capn);
449 return rc;
450 }
451
452 /*
453 * TODO: ????
454 dbCCSeg *
455 dbCCSeg::relinkTgtCC (dbNet *net_, dbCCSeg *pseg_, uint src_cap_node, uint
456 tgt_cap_node)
457 {
458 _dbNet *tnet = (_dbNet *)net_;
459 _dbCCSeg *pseg = (_dbCCSeg *)pseg_;
460 if (pseg && src_cap_node==0 && tgt_cap_node==0)
461 {
462 tnet->_cc_tgt_segs = pseg->getOID();
463 return NULL;
464 }
465 dbTable<_dbCCSeg> *cct = ((_dbBlock *)tnet->getOwner())->_cc_seg_tbl;
466 _dbCCSeg *seg;
467 uint psid = 0;
468 uint tsid;
469 for (tsid = tnet->_cc_tgt_segs; tsid; tsid = seg->_next_target)
470 {
471 seg = cct->getPtr(tsid);
472 if (seg->_source_cap_node == src_cap_node &&
473 seg->_target_cap_node == tgt_cap_node)
474 break;
475 psid = tsid;
476 }
477 if (!tsid)
478 return NULL;
479 if (psid)
480 cct->getPtr(psid)->_next_target = seg->_next_target;
481 else
482 tnet->_cc_tgt_segs = seg->_next_target;
483 seg->_next_target = 0;
484 if (pseg)
485 ((_dbCCSeg *)pseg)->_next_target = tsid;
486 return (dbCCSeg *) seg;
487 }
488 */
489
findParallelCCSeg(_dbBlock * block,_dbCapNode * src,_dbCapNode * tgt,bool reInsert)490 static _dbCCSeg* findParallelCCSeg(_dbBlock* block,
491 _dbCapNode* src,
492 _dbCapNode* tgt,
493 bool reInsert)
494 {
495 uint src_id = src->getOID();
496 uint tgt_id = tgt->getOID();
497 _dbCCSeg* pccs = NULL;
498 _dbCCSeg* ccs = NULL;
499 uint seg;
500
501 for (seg = tgt->_cc_segs; seg;) {
502 ccs = block->_cc_seg_tbl->getPtr(seg);
503
504 if (ccs->_cap_node[0] == tgt_id && ccs->_cap_node[1] == src_id)
505 break;
506
507 if (ccs->_cap_node[1] == tgt_id && ccs->_cap_node[0] == src_id)
508 break;
509
510 pccs = ccs;
511 seg = ccs->next(tgt_id);
512 }
513 if (!seg)
514 return NULL;
515 if (!pccs || !reInsert)
516 return ccs;
517 pccs->_next[pccs->idx(tgt_id)] = ccs->next(tgt_id);
518 ccs->_next[ccs->idx(tgt_id)] = tgt->_cc_segs;
519 tgt->_cc_segs = ccs->getOID();
520 return ccs;
521 }
522
findCC(dbCapNode * nodeA,dbCapNode * nodeB)523 dbCCSeg* dbCCSeg::findCC(dbCapNode* nodeA, dbCapNode* nodeB)
524 {
525 _dbBlock* block = (_dbBlock*) nodeA->getImpl()->getOwner();
526 _dbCCSeg* seg = findParallelCCSeg(
527 block, (_dbCapNode*) nodeA, (_dbCapNode*) nodeB, false);
528 return (dbCCSeg*) seg;
529 }
530
create(dbCapNode * src_,dbCapNode * tgt_,bool mergeParallel)531 dbCCSeg* dbCCSeg::create(dbCapNode* src_, dbCapNode* tgt_, bool mergeParallel)
532 {
533 _dbBlock* block = (_dbBlock*) src_->getImpl()->getOwner();
534
535 uint srcNetId = src_->getNet()->getImpl()->getOID();
536 uint tgtNetId = tgt_->getNet()->getImpl()->getOID();
537
538 _dbCapNode* src = (_dbCapNode*) src_;
539 _dbCapNode* tgt = (_dbCapNode*) tgt_;
540 if (srcNetId > tgtNetId) {
541 src = (_dbCapNode*) tgt_;
542 tgt = (_dbCapNode*) src_;
543 }
544
545 if (block->_journal) {
546 debugPrint(block->getImpl()->getLogger(),
547 utl::ODB,
548 "DB_ECO",
549 1,
550 "ECO: dbCCSeg::create, nodeA = {}, nodeB = {}, merge = {}",
551 src->getOID(),
552 tgt->getOID(),
553 mergeParallel);
554
555 block->_journal->beginAction(dbJournal::CREATE_OBJECT);
556 block->_journal->pushParam(dbCCSegObj);
557 block->_journal->pushParam(src->getOID());
558 block->_journal->pushParam(tgt->getOID());
559 block->_journal->pushParam(mergeParallel);
560 block->_journal->endAction();
561 }
562
563 _dbCCSeg* seg;
564 if (mergeParallel && (seg = findParallelCCSeg(block, src, tgt, true)))
565 return (dbCCSeg*) seg;
566
567 seg = block->_cc_seg_tbl->create();
568 // seg->_flags._cnt = block->_num_corners;
569
570 // set corner values
571 uint cornerCnt = block->_corners_per_block;
572 if (block->_maxCCSegId >= seg->getOID()) {
573 for (uint ii = 0; ii < cornerCnt; ii++)
574 (*block->_cc_val_tbl)[(seg->getOID() - 1) * cornerCnt + 1 + ii] = 0.0;
575 } else {
576 block->_maxCCSegId = seg->getOID();
577 uint ccCapIdx = block->_cc_val_tbl->getIdx(cornerCnt, (float) 0.0);
578 ZASSERT((seg->getOID() - 1) * cornerCnt + 1 == ccCapIdx);
579 }
580
581 seg->_cap_node[0] = src->getOID();
582 seg->_next[0] = src->_cc_segs;
583 src->_cc_segs = seg->getOID();
584
585 seg->_cap_node[1] = tgt->getOID();
586 seg->_next[1] = tgt->_cc_segs;
587 tgt->_cc_segs = seg->getOID();
588 return (dbCCSeg*) seg;
589 }
590
unlink_cc_seg(_dbBlock * block,_dbCapNode * node,_dbCCSeg * s)591 static void unlink_cc_seg(_dbBlock* block, _dbCapNode* node, _dbCCSeg* s)
592 {
593 dbId<_dbCapNode> cid = node->getOID();
594 uint prev = 0;
595 uint next = node->_cc_segs;
596 uint seg = s->getOID();
597
598 while (next) {
599 if (next == seg) {
600 if (prev == 0)
601 node->_cc_segs = s->next(cid);
602 else {
603 _dbCCSeg* p = block->_cc_seg_tbl->getPtr(prev);
604 p->next(cid) = s->next(cid);
605 }
606
607 break;
608 }
609
610 _dbCCSeg* ncc = block->_cc_seg_tbl->getPtr(next);
611 prev = next;
612 next = ncc->next(cid);
613 }
614 }
615
unLink_cc_seg(dbCapNode * capn)616 void dbCCSeg::unLink_cc_seg(dbCapNode* capn)
617 {
618 _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
619 unlink_cc_seg(block, (_dbCapNode*) capn, (_dbCCSeg*) this);
620 if (block->_journal) {
621 debugPrint(getImpl()->getLogger(),
622 utl::ODB,
623 "DB_ECO",
624 1,
625 "ECO: dbCCSeg::unLink, ccseg: {}, capNode: {}",
626 getId(),
627 capn->getId());
628 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
629 block->_journal->pushParam(dbCCSegObj);
630 block->_journal->pushParam(getId());
631 block->_journal->pushParam(_dbCCSeg::UNLINKCCSEG);
632 block->_journal->pushParam(capn->getId());
633 block->_journal->endAction();
634 }
635 }
636
Link_cc_seg(dbCapNode * capn,uint cseq)637 void dbCCSeg::Link_cc_seg(dbCapNode* capn, uint cseq)
638 {
639 _dbBlock* block = (_dbBlock*) getImpl()->getOwner();
640 _dbCapNode* tgt = (_dbCapNode*) capn;
641 ((_dbCCSeg*) this)->_next[cseq] = tgt->_cc_segs;
642 tgt->_cc_segs = getId();
643
644 if (block->_journal) {
645 debugPrint(getImpl()->getLogger(),
646 utl::ODB,
647 "DB_ECO",
648 1,
649 "ECO: dbCCSeg::Link, ccseg: {}, capNode: {}, cseq: {}",
650 getId(),
651 capn->getId(),
652 cseq);
653 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
654 block->_journal->pushParam(dbCCSegObj);
655 block->_journal->pushParam(getId());
656 block->_journal->pushParam(_dbCCSeg::LINKCCSEG);
657 block->_journal->pushParam(capn->getId());
658 block->_journal->pushParam(cseq);
659 block->_journal->endAction();
660 }
661 }
662
disconnect(dbCCSeg * tcc_)663 void dbCCSeg::disconnect(dbCCSeg* tcc_)
664 {
665 _dbCCSeg* tcc = (_dbCCSeg*) tcc_;
666 dbBlock* block = (dbBlock*) tcc->getOwner();
667
668 dbCapNode* src = dbCapNode::getCapNode(block, tcc->_cap_node[0]);
669 dbCapNode* tgt = dbCapNode::getCapNode(block, tcc->_cap_node[1]);
670 tcc_->unLink_cc_seg(src);
671 tcc_->unLink_cc_seg(tgt);
672 }
673
connect(dbCCSeg * tcc_)674 void dbCCSeg::connect(dbCCSeg* tcc_)
675 {
676 _dbCCSeg* tcc = (_dbCCSeg*) tcc_;
677 dbBlock* block = (dbBlock*) tcc->getOwner();
678
679 dbCapNode* src = dbCapNode::getCapNode(block, tcc->_cap_node[0]);
680 dbCapNode* tgt = dbCapNode::getCapNode(block, tcc->_cap_node[1]);
681 tcc_->Link_cc_seg(src, 0);
682 tcc_->Link_cc_seg(tgt, 1);
683 }
destroy(dbCCSeg * seg_)684 void dbCCSeg::destroy(dbCCSeg* seg_)
685 {
686 _dbCCSeg* seg = (_dbCCSeg*) seg_;
687 _dbBlock* block = (_dbBlock*) seg->getOwner();
688
689 if (block->_journal) {
690 debugPrint(block->getImpl()->getLogger(),
691 utl::ODB,
692 "DB_ECO",
693 1,
694 "ECO: dbCCSeg::destroy, seg id: {}",
695 seg->getId());
696 block->_journal->beginAction(dbJournal::DELETE_OBJECT);
697 block->_journal->pushParam(dbCCSegObj);
698 block->_journal->pushParam(seg->getId());
699 block->_journal->pushParam((uint) 1); // regular destroy
700 block->_journal->endAction();
701 }
702
703 _dbCapNode* src = block->_cap_node_tbl->getPtr(seg->_cap_node[0]);
704 _dbCapNode* tgt = block->_cap_node_tbl->getPtr(seg->_cap_node[1]);
705 unlink_cc_seg(block, src, seg);
706 unlink_cc_seg(block, tgt, seg);
707 dbProperty::destroyProperties(seg);
708 block->_cc_seg_tbl->destroy(seg);
709 }
destroyS(dbCCSeg * seg_)710 void dbCCSeg::destroyS(dbCCSeg* seg_)
711 {
712 _dbCCSeg* seg = (_dbCCSeg*) seg_;
713 _dbBlock* block = (_dbBlock*) seg->getOwner();
714
715 if (block->_journal) {
716 debugPrint(block->getImpl()->getLogger(),
717 utl::ODB,
718 "DB_ECO",
719 1,
720 "ECO: dbCCSeg::destroy, seg id: {}",
721 seg->getId());
722 block->_journal->beginAction(dbJournal::DELETE_OBJECT);
723 block->_journal->pushParam(dbCCSegObj);
724 block->_journal->pushParam(seg->getId());
725 block->_journal->pushParam((uint) 0); // simple destroy
726 block->_journal->endAction();
727 }
728
729 dbProperty::destroyProperties(seg);
730 block->_cc_seg_tbl->destroy(seg);
731 }
732
destroy(dbSet<dbCCSeg>::iterator & itr)733 dbSet<dbCCSeg>::iterator dbCCSeg::destroy(dbSet<dbCCSeg>::iterator& itr)
734 {
735 dbCCSeg* bt = *itr;
736 dbSet<dbCCSeg>::iterator next = ++itr;
737 destroy(bt);
738 return next;
739 }
740
swapCapnode(dbCapNode * orig_,dbCapNode * new_)741 void dbCCSeg::swapCapnode(dbCapNode* orig_, dbCapNode* new_)
742 {
743 _dbCCSeg* seg = (_dbCCSeg*) this;
744 _dbBlock* block = (_dbBlock*) seg->getOwner();
745 _dbCapNode* orig = (_dbCapNode*) orig_;
746 _dbCapNode* newn = (_dbCapNode*) new_;
747 uint oid = orig->getOID();
748 uint nid = newn->getOID();
749 uint sidx;
750 if (oid == seg->_cap_node[0]) {
751 sidx = 0;
752 } else if (oid == seg->_cap_node[1]) {
753 sidx = 1;
754 } else {
755 getImpl()->getLogger()->error(
756 utl::ODB,
757 23,
758 "CCSeg {} does not have orig capNode {}. Can not swap.",
759 seg->getOID(),
760 oid);
761 }
762 unlink_cc_seg(block, orig, seg);
763 seg->_cap_node[sidx] = nid;
764 seg->_next[sidx] = newn->_cc_segs;
765 newn->_cc_segs = seg->getOID();
766 if (block->_journal) {
767 debugPrint(getImpl()->getLogger(),
768 utl::ODB,
769 "DB_ECO",
770 1,
771 "ECO: dbCCSeg {}, origCapNode {}, newCapNode {}, swapCapnode",
772 seg->getOID(),
773 oid,
774 nid);
775 block->_journal->beginAction(dbJournal::UPDATE_FIELD);
776 block->_journal->pushParam(dbCCSegObj);
777 block->_journal->pushParam(seg->getId());
778 block->_journal->pushParam(_dbCCSeg::SWAPCAPNODE);
779 block->_journal->pushParam(oid);
780 block->_journal->pushParam(nid);
781 block->_journal->endAction();
782 }
783 }
784
getTheOtherCapn(dbCapNode * oneCap,uint & cid)785 dbCapNode* dbCCSeg::getTheOtherCapn(dbCapNode* oneCap, uint& cid)
786 {
787 _dbCCSeg* seg = (_dbCCSeg*) this;
788 _dbBlock* block = (_dbBlock*) seg->getOwner();
789 cid = ((_dbCapNode*) oneCap)->getOID() == seg->_cap_node[1] ? 0 : 1;
790 _dbCapNode* n = block->_cap_node_tbl->getPtr(seg->_cap_node[cid]);
791 return (dbCapNode*) n;
792 }
793
getCCSeg(dbBlock * block_,uint dbid_)794 dbCCSeg* dbCCSeg::getCCSeg(dbBlock* block_, uint dbid_)
795 {
796 _dbBlock* block = (_dbBlock*) block_;
797 return (dbCCSeg*) block->_cc_seg_tbl->getPtr(dbid_);
798 }
799
800 } // namespace odb
801