COOPY » Guide
version 0.6.5
|
00001 #include <coopy/OrderMerge.h> 00002 #include <coopy/Dbg.h> 00003 #include <coopy/Viterbi.h> 00004 #include <coopy/EfficientMap.h> 00005 00006 #include <list> 00007 #include <map> 00008 00009 using namespace std; 00010 using namespace coopy::cmp; 00011 00012 /* 00013 00014 Order is currently not quite right. Inserts and deletes are ok, 00015 but no analysis is done yet to determine which of local vs remote 00016 orders should win. 00017 00018 */ 00019 00020 void OrderMerge::process(int ilocal, int iremote, 00021 int& base_local, int& base_remote, 00022 int stop_local, int stop_remote) { 00023 //dbg_printf("process %d %d / %d %d / %d %d\n", ilocal, iremote, 00024 //base_local, base_remote, stop_local, stop_remote); 00025 while (true) { 00026 //dbg_printf("--- process %d %d / %d %d / %d %d\n", ilocal, iremote, 00027 // base_local, base_remote, stop_local, stop_remote); 00028 if (ilocal>=stop_local && 00029 iremote>=stop_remote) { 00030 break; 00031 } 00032 int _l = ilocal; 00033 if (ilocal<stop_local) { 00034 if (_l<xlocal.height()) { 00035 if (xlocal.cell(0,_l)==0) { 00036 int _lp = order_local.b2a(_l); 00037 if (_lp!=-1) { 00038 int _lpr = order_remote.a2b(_lp); 00039 if (_lpr!=-1) { 00040 process(base_local,base_remote,base_local,base_remote,ilocal,_lpr); 00041 //dbg_printf("Local unit %d exists in pivot at %d and in remote at %d\n", _l, _lp, _lpr); 00042 accum.push_back(MatchUnit(_lp,_l,_lpr,false,MATCH_UNIT_PRESERVE)); 00043 if (_lpr>=0) { 00044 xremote.cell(0,_lpr) = 1; 00045 } 00046 if (_l>=0) { 00047 xlocal.cell(0,_l) = 1; 00048 } 00049 } else { 00050 dbg_printf("Local unit %d exists in pivot at %d, but not in remote - [DELETE]\n", _l, _lp); 00051 accum.push_back(MatchUnit(_lp,_l,-1,true,MATCH_UNIT_DELETE)); 00052 if (_l>=0) { 00053 xlocal.cell(0,_l) = 1; 00054 } 00055 } 00056 } else { 00057 dbg_printf("Local unit %d not in pivot - [ADD]\n", _l); 00058 accum.push_back(MatchUnit(-1,_l,-1,false,MATCH_UNIT_PRESERVE)); 00059 if (_l>=0) { 00060 xlocal.cell(0,_l) = 1; 00061 } 00062 } 00063 } 00064 } 00065 } else { 00066 int _r = iremote; 00067 if (_r<xremote.height()) { 00068 if (xremote.cell(0,_r)==0) { 00069 int _rp = order_remote.b2a(_r); 00070 if (_rp!=-1) { 00071 int _rpl = order_local.a2b(_rp); 00072 if (_rpl!=-1) { 00073 // we will get this (assuming no collisions), skip... 00074 } else { 00075 // deleted locally 00076 } 00077 } else { 00078 dbg_printf("Remote unit %d not in pivot - [ADD]\n", _r); 00079 accum.push_back(MatchUnit(-1,-1,_r,false,MATCH_UNIT_INSERT)); 00080 if (_r>=0) { 00081 xremote.cell(0,_r) = 1; 00082 } 00083 } 00084 } 00085 } 00086 } 00087 if (ilocal<stop_local) { 00088 ilocal++; 00089 base_local++; 00090 } else { 00091 iremote++; 00092 base_remote++; 00093 } 00094 } 00095 } 00096 00097 00098 00099 static bool summarize(int prev, int curr, int next) { 00100 if (prev!=-1) { 00101 if (prev==curr-1) { 00102 prev = 1; 00103 } else { 00104 prev = 0; 00105 } 00106 } 00107 if (next!=-1) { 00108 if (next==curr+1) { 00109 next = 1; 00110 } else { 00111 next = 0; 00112 } 00113 } 00114 return prev==1 || next==1; 00115 } 00116 00117 /* 00118 static bool shunt(list<MatchUnit>& canon, 00119 list<MatchUnit>& accum, 00120 const MatchUnit& unit, 00121 int prev, 00122 int curr, 00123 int next, 00124 int side) { 00125 bool remote = (side==1); 00126 list<MatchUnit>::iterator subj = canon.end(); 00127 list<MatchUnit>::iterator obj = canon.end(); 00128 bool before = false; 00129 int at_subj = -1; 00130 int at_obj = -1; 00131 int ct = 0; 00132 bool shunted = false; 00133 dbg_printf("Asked to shunt:\n"); 00134 if (_csv_verbose) { 00135 dbg_printf(" BEFORE "); 00136 for (list<MatchUnit>::iterator it=canon.begin(); 00137 it!=canon.end(); 00138 it++) { 00139 dbg_printf("%d:%d:%d ", (*it).pivotUnit, (*it).localUnit, (*it).remoteUnit); 00140 } 00141 dbg_printf("\n"); 00142 dbg_printf(" for P/L/R %d:%d:%d\n", unit.pivotUnit, unit.localUnit, unit.remoteUnit); 00143 dbg_printf(" side %s prev %d curr %d next %d\n", remote?"remote":"local", 00144 prev, curr, next); 00145 } 00146 bool unneeded = false; 00147 for (list<MatchUnit>::iterator it=canon.begin(); 00148 it!=canon.end(); 00149 it++) { 00150 MatchUnit& unit2 = *it; 00151 int r = remote?unit2.remoteUnit:unit2.localUnit; 00152 if (r!=-1) { 00153 if (r==prev||r==next) { 00154 dbg_printf("Shunt object found...\n"); 00155 obj = it; 00156 at_obj = ct; 00157 if (r==next) { 00158 before = true; 00159 if (at_subj!=-1) { 00160 if (at_obj==at_subj+1) unneeded = true; 00161 } 00162 } else { 00163 before = false; 00164 } 00165 } 00166 if (r==curr) { 00167 dbg_printf("Shunt subject found...\n"); 00168 subj = it; 00169 at_subj = ct; 00170 if (at_obj!=-1) { 00171 if (at_subj==at_obj+1) unneeded = true; 00172 } 00173 } 00174 } 00175 ct++; 00176 } 00177 if (obj!=canon.end() && subj!=canon.end()) { 00178 dbg_printf("Shunting... move %d %s %d\n", at_subj, before?"before":"after", 00179 at_obj); 00180 //bool unneeded = before?(at_subj<at_obj):(at_subj>at_obj); 00181 if (before==false) { 00182 obj++; 00183 at_obj++; 00184 } 00185 if (_csv_verbose) { 00186 dbg_printf("BEFORE "); 00187 for (list<MatchUnit>::iterator it=canon.begin(); 00188 it!=canon.end(); 00189 it++) { 00190 dbg_printf("%d:%d:%d ", (*it).pivotUnit, (*it).localUnit, (*it).remoteUnit); 00191 } 00192 dbg_printf("\n"); 00193 } 00194 if ((at_obj==at_subj || at_obj==at_subj+1)||unneeded) { 00195 dbg_printf(" ... skipping shunt\n"); 00196 } else { 00197 canon.splice(obj,canon,subj); 00198 shunted = true; 00199 if (_csv_verbose) { 00200 dbg_printf("AFTER "); 00201 for (list<MatchUnit>::iterator it=canon.begin(); 00202 it!=canon.end(); 00203 it++) { 00204 dbg_printf("%d:%d:%d ", (*it).pivotUnit, (*it).localUnit, (*it).remoteUnit); 00205 } 00206 dbg_printf("\n"); 00207 } 00208 } 00209 } else { 00210 dbg_printf("Shunt failed!\n"); 00211 } 00212 return shunted; 00213 } 00214 */ 00215 00216 /* 00217 void OrderMerge::merge(const OrderResult& nlocal, 00218 const OrderResult& nremote, 00219 const CompareFlags& flags) { 00220 this->flags = flags; 00221 order_local = nlocal; 00222 order_remote = nremote; 00223 if (flags.head_trimmed) { 00224 order_local.trimHead(-1,-2); 00225 order_remote.trimHead(-1,-2); 00226 } 00227 if (flags.tail_trimmed) { 00228 order_local.trimTail(-1,-2); 00229 order_remote.trimTail(-1,-2); 00230 } 00231 xlocal.resize(1,order_local.blen(),0); 00232 xremote.resize(1,order_remote.blen(),0); 00233 start_local = 0; 00234 start_remote = 0; 00235 int base_local = 0; 00236 int base_remote = 0; 00237 process(0,0,base_local,base_remote,order_local.blen(),order_remote.blen()); 00238 00239 list<MatchUnit> canon = accum; 00240 int shunt_count = 0; 00241 bool shunted = false; 00242 00243 // Prepare a list of constraints on order 00244 do { 00245 shunted = false; 00246 if (coopy_is_verbose()) { 00247 for (list<MatchUnit>::iterator it=canon.begin(); 00248 it!=canon.end(); 00249 it++) { 00250 MatchUnit& unit = *it; 00251 int pCol = unit.pivotUnit; 00252 int lCol = unit.localUnit; 00253 int rCol = unit.remoteUnit; 00254 bool deleted = unit.deleted; 00255 dbg_printf("match P/L/R %d %d %d %s\n", pCol, lCol, rCol, 00256 deleted?"(deleted)":""); 00257 } 00258 } 00259 for (list<MatchUnit>::iterator it=accum.begin(); 00260 it!=accum.end(); 00261 it++) { 00262 MatchUnit& unit = *it; 00263 int pCol = unit.pivotUnit; 00264 int lCol = unit.localUnit; 00265 int rCol = unit.remoteUnit; 00266 bool deleted = unit.deleted; 00267 00268 if (!deleted) { 00269 if (pCol!=-1&&lCol!=-1&&rCol!=-1) { 00270 //dbg_printf("Working on P/L/R %d %d %d\n", pCol, lCol, rCol); 00271 int lColNext = order_local.a2b(pCol+1); 00272 int rColNext = order_remote.a2b(pCol+1); 00273 int lColPrev = order_local.a2b(pCol-1); 00274 int rColPrev = order_remote.a2b(pCol-1); 00275 //lColNext = order_local.b2a(_lp); 00276 00277 bool lCont = summarize(lColPrev,lCol,lColNext); 00278 bool rCont = summarize(rColPrev,rCol,rColNext); 00279 00280 if (lCont&&!rCont) { 00281 dbg_printf("Remote constraint P/L/R %d/%d/%d\n", pCol, lCol, rCol); 00282 if (shunt(canon,accum,unit,rCol-1,rCol,rCol+1,1)) { 00283 shunt_count++; 00284 shunted = true; 00285 } 00286 } 00287 if (rCont&&!lCont) { 00288 dbg_printf("Local constraint P/L/R %d/%d/%d\n", pCol, lCol, rCol); 00289 if (shunt(canon,accum,unit,lCol-1,lCol,lCol+1,-1)) { 00290 shunt_count++; 00291 shunted = true; 00292 } 00293 } 00294 } else if (pCol==-1) { 00295 if (rCol!=-1 && lCol==-1) { 00296 int rColNext = order_remote.a2b(pCol+1); 00297 int rColPrev = order_remote.a2b(pCol-1); 00298 dbg_printf("Remote new col constraint P/L/R %d/%d/%d\n", pCol, lCol, rCol); 00299 if (shunt(canon,accum,unit,rCol-1,rCol,rCol+1,1)) { 00300 shunt_count++; 00301 shunted = true; 00302 } 00303 } 00304 } 00305 } 00306 } 00307 } while (shunted); 00308 if (coopy_is_verbose()) { 00309 for (list<MatchUnit>::iterator it=canon.begin(); 00310 it!=canon.end(); 00311 it++) { 00312 MatchUnit& unit = *it; 00313 int pCol = unit.pivotUnit; 00314 int lCol = unit.localUnit; 00315 int rCol = unit.remoteUnit; 00316 bool deleted = unit.deleted; 00317 dbg_printf("final match P/L/R %d %d %d %s\n", pCol, lCol, rCol, 00318 deleted?"(deleted)":""); 00319 } 00320 } 00321 if (shunt_count>0) { 00322 dbg_printf("Copying result of shunt...\n"); 00323 accum = canon; 00324 } 00325 } 00326 */ 00327 00328 00329 static void evaluate(const OrderResult& order_local, 00330 const OrderResult& order_remote, 00331 int lCol, 00332 int rCol, 00333 int lastWasL, 00334 float& lCost, 00335 float& rCost) { 00336 int plCol = order_local.b2a(lCol); 00337 int prCol = order_remote.b2a(rCol); 00338 int lprCol = -1; 00339 int rplCol = -1; 00340 00341 if (prCol>=0) { 00342 lprCol = order_local.a2b(prCol); 00343 if (lprCol>=0 && lprCol<lCol) { 00344 // already consumed, draw for free. 00345 rCost = 0; 00346 return; 00347 } 00348 } 00349 00350 if (plCol>=0) { 00351 rplCol = order_remote.a2b(plCol); 00352 if (rplCol>=0 && rplCol<rCol) { 00353 // already consumed, draw for free. 00354 lCost = 0; 00355 return; 00356 } 00357 } 00358 00359 int lColNext = order_local.a2b(plCol+1); 00360 int lColPrev = order_local.a2b(plCol-1); 00361 int rColNext = order_remote.a2b(prCol+1); 00362 int rColPrev = order_remote.a2b(prCol-1); 00363 bool lCont = summarize(lColPrev,lCol,lColNext); 00364 bool rCont = summarize(rColPrev,rCol,rColNext); 00365 } 00366 00367 00368 static int safe_next(const efficient_map<int,int>& m, int val, int def) { 00369 efficient_map<int,int>::const_iterator it = m.find(val); 00370 if (it==m.end()) return def; 00371 return it->second; 00372 } 00373 00374 static int next_avail(const set<int>& s, int val) { 00375 set<int>::const_iterator it = s.find(val); 00376 if (it==s.end()) return -2; 00377 it++; 00378 if (it==s.end()) return -2; 00379 return *it; 00380 } 00381 00382 void OrderMerge::merge(const OrderResult& nlocal, 00383 const OrderResult& nremote, 00384 const CompareFlags& flags, 00385 bool columnar) { 00386 this->flags = flags; 00387 order_local = nlocal; 00388 order_remote = nremote; 00389 if (flags.head_trimmed) { 00390 order_local.trimHead(-1,-2); 00391 order_remote.trimHead(-1,-2); 00392 } 00393 if (flags.tail_trimmed) { 00394 order_local.trimTail(-1,-2); 00395 order_remote.trimTail(-1,-2); 00396 } 00397 xlocal.resize(1,order_local.blen(),0); 00398 xremote.resize(1,order_remote.blen(),0); 00399 start_local = 0; 00400 start_remote = 0; 00401 int base_local = 0; 00402 int base_remote = 0; 00403 process(0,0,base_local,base_remote,order_local.blen(),order_remote.blen()); 00404 00405 bool good = false; 00406 bool more = true; 00407 list<MatchUnit> canon; 00408 list<MatchUnit> canon_rem1; 00409 list<MatchUnit> canon_rem2; 00410 list<MatchUnit> *canon_src = &accum; 00411 00412 bool ordered = flags.use_order; 00413 00414 if (flags.use_order||columnar) { 00415 00416 while (more) { 00417 00418 int ct = 0; 00419 efficient_map<int,int> l2k, r2k, p2k; 00420 efficient_map<int,int> it2k; 00421 efficient_map<int,MatchUnit *> mu; 00422 set<int> availableP; 00423 set<int> availableL; 00424 set<int> availableR; 00425 00426 int lowestL = -2; 00427 int lowestR = -2; 00428 int gct = 0; 00429 for (list<MatchUnit>::iterator it=canon_src->begin(); 00430 it!=canon_src->end(); 00431 it++) { 00432 MatchUnit& unit = *it; 00433 int pCol = unit.pivotUnit; 00434 int lCol = unit.localUnit; 00435 int rCol = unit.remoteUnit; 00436 bool deleted = unit.deleted; 00437 /*dbg_printf("match %d: %d: P/L/R %d %d %d %s\n", 00438 gct, deleted?-1:ct, pCol, lCol, rCol, 00439 deleted?"(deleted)":"");*/ 00440 gct++; 00441 if (deleted) { continue; } 00442 it2k[gct-1] = ct; 00443 if ((lCol<lowestL&&lCol>=0)||lowestL==-2) { 00444 lowestL = lCol; 00445 } 00446 if (lCol!=-1) { 00447 availableL.insert(lCol); 00448 } 00449 if ((rCol<lowestR&&rCol>=0)||lowestR==-2) { 00450 lowestR = rCol; 00451 } 00452 if (rCol!=-1) { 00453 availableR.insert(rCol); 00454 } 00455 if (pCol!=-1) { 00456 availableP.insert(pCol); 00457 } 00458 if (pCol>=0) { 00459 p2k[pCol] = ct; 00460 } 00461 if (lCol>=0) { 00462 l2k[lCol] = ct; 00463 } 00464 if (rCol>=0) { 00465 r2k[rCol] = ct; 00466 } 00467 mu[ct] = &unit; 00468 ct++; 00469 } 00470 int units = ct; 00471 00472 Viterbi v; 00473 00474 int dud = units; 00475 v.setSize(units+1,units+2); 00476 set<int> idx; 00477 00478 v.beginTransitions(); 00479 if (lowestL>=0) { 00480 v.addTransition(l2k[lowestL],l2k[lowestL],0); 00481 idx.insert(l2k[lowestL]); 00482 } 00483 if (lowestR>=0) { 00484 v.addTransition(r2k[lowestR],r2k[lowestR],0); 00485 idx.insert(r2k[lowestR]); 00486 } 00487 v.addTransition(dud,dud,1); 00488 v.endTransitions(); 00489 00490 for (int draw=0; draw<units-1; draw++) { 00491 //dbg_printf("DRAW %d (%d)\n", draw, units); 00492 v.beginTransitions(); 00493 00494 set<int> idx2; 00495 for (set<int>::const_iterator it1=idx.begin(); it1!=idx.end(); it1++) { 00496 int k = (*it1); 00497 //dbg_printf(" draw %d k %d\n", draw, k); 00498 if (k==dud) continue; 00499 00500 MatchUnit& unit = *mu[k]; 00501 int pCol = unit.pivotUnit; 00502 int lCol = unit.localUnit; 00503 int rCol = unit.remoteUnit; 00504 bool deleted = unit.deleted; 00505 00506 //dbg_printf(" match P/L/R %d %d %d %s\n", pCol, lCol, rCol, 00507 //deleted?"(deleted)":""); 00508 00509 if (lCol==-1 && rCol==-1) { 00510 int next = safe_next(p2k,next_avail(availableP,pCol),dud); 00511 v.addTransition(k,next,0); 00512 //dbg_printf(" transition %d %d\n", k, next); 00513 idx2.insert(next); 00514 continue; 00515 } 00516 if (rCol==-1) { 00517 int next = safe_next(l2k,next_avail(availableL,lCol),dud); 00518 v.addTransition(k,next,0); 00519 //dbg_printf(" transition %d %d\n", k, next); 00520 idx2.insert(next); 00521 continue; 00522 } 00523 if (lCol==-1) { 00524 int next = safe_next(r2k,next_avail(availableR,rCol),dud); 00525 v.addTransition(k,next,0); 00526 //dbg_printf(" transition %d %d\n", k, next); 00527 idx2.insert(next); 00528 continue; 00529 } 00530 int lnext = safe_next(l2k,next_avail(availableL,lCol),dud); 00531 int rnext = safe_next(r2k,next_avail(availableR,rCol),dud); 00532 /* 00533 if (lnext==dud||rnext==dud) { 00534 v.addTransition(k,lnext,0); 00535 dbg_printf(" transition %d %d\n", k, lnext); 00536 idx2.insert(lnext); 00537 v.addTransition(k,rnext,0); 00538 dbg_printf(" transition %d %d\n", k, rnext); 00539 idx2.insert(rnext); 00540 continue; 00541 } 00542 */ 00543 int pnext = safe_next(p2k,next_avail(availableP,pCol),dud); 00544 if (lnext!=pnext) { 00545 v.addTransition(k,lnext,0); 00546 //dbg_printf(" transition %d %d\n", k, lnext); 00547 idx2.insert(lnext); 00548 } 00549 if (rnext!=pnext) { 00550 v.addTransition(k,rnext,0); 00551 //dbg_printf(" transition %d %d\n", k, rnext); 00552 idx2.insert(rnext); 00553 } 00554 if (rnext==pnext&&lnext==pnext) { 00555 v.addTransition(k,pnext,0); 00556 //dbg_printf(" transition %d %d\n", k, pnext); 00557 idx2.insert(pnext); 00558 } 00559 } 00560 idx = idx2; 00561 v.addTransition(dud,dud,1); 00562 v.endTransitions(); 00563 } 00564 00565 v.beginTransitions(); 00566 for (int draw=0; draw<=units; draw++) { 00567 v.addTransition(draw,draw,(draw==units)); 00568 } 00569 v.endTransitions(); 00570 int qo = 1; 00571 00572 /* 00573 if (_csv_verbose) { 00574 dbg_printf("Viterbi calculation:\n"); 00575 int q = v.length()-qo; 00576 for (int i=0; i<q; i++) { 00577 int k = v.getPath(i); 00578 dbg_printf("*** %d\n", k); 00579 } 00580 } 00581 */ 00582 00583 int q = v.length()-qo; 00584 efficient_map<int,int> dups; 00585 efficient_map<int,int> accepted; 00586 dups[dud] = 1; 00587 good = true; 00588 //if (v.getPath(q)!=dud) { 00589 for (int i=0; i<q; i++) { 00590 int k = v.getPath(i); 00591 int k2 = k; 00592 if (i<q-1) { 00593 k2 = v.getPath(i+1); 00594 } 00595 if (dups.find(k)==dups.end() && dups.find(k2)==dups.end()) { 00596 canon.push_back(*mu[k]); 00597 //dbg_printf(" ADDED -> %d (%d %d %d)\n", canon.size(), 00598 // mu[k]->pivotUnit, mu[k]->localUnit, mu[k]->remoteUnit); 00599 dups[k] = 1; 00600 accepted[k] = 1; 00601 } else { 00602 //dbg_printf(" hit dodgy match\n"); 00603 good = false; 00604 break; 00605 } 00606 } 00607 00608 more = !good; 00609 list<MatchUnit> *canon_old_src = canon_src; 00610 if (canon_src != &canon_rem1) { 00611 canon_src = &canon_rem1; 00612 } else { 00613 canon_src = &canon_rem2; 00614 } 00615 canon_src->clear(); 00616 int gct2 = 0; 00617 int omit = 0; 00618 for (list<MatchUnit>::iterator it=canon_old_src->begin(); 00619 it!=canon_old_src->end(); 00620 it++) { 00621 if (it2k.find(gct2)!=it2k.end()) { 00622 if (accepted.find(it2k[gct2])!=accepted.end()) { 00623 omit++; 00624 } else { 00625 canon_src->push_back(*it); 00626 } 00627 } 00628 gct2++; 00629 } 00630 dbg_printf("Got to length %d of %d...\n", 00631 canon.size(), accum.size()); 00632 if (omit==0) { 00633 // dbg_printf("No progress made\n"); 00634 more = false; 00635 } 00636 dbg_printf("STATUS %d %d / %s, %s\n", canon.size(), accum.size(), good?"good":"no good", more?"more":"no more"); 00637 } 00638 00639 if (canon_src!=&accum) { 00640 for (list<MatchUnit>::iterator it=canon_src->begin(); 00641 it!=canon_src->end(); 00642 it++) { 00643 if (!it->deleted) { 00644 canon.push_back(*it); 00645 //dbg_printf(" ADDED UNORDERED -> %d (%d %d %d)\n", canon.size(), 00646 //it->pivotUnit, it->localUnit, it->remoteUnit); 00647 } 00648 } 00649 } 00650 00651 for (list<MatchUnit>::iterator it=accum.begin(); 00652 it!=accum.end(); 00653 it++) { 00654 if (it->deleted) { 00655 canon.push_back(*it); 00656 //dbg_printf(" ADDED DELETED -> %d (%d %d %d)\n", canon.size(), 00657 //it->pivotUnit, it->localUnit, it->remoteUnit); 00658 } 00659 } 00660 accum = canon; 00661 } 00662 00663 int ct = 0; 00664 overlap = 0; 00665 for (list<MatchUnit>::iterator it=accum.begin(); 00666 it!=accum.end(); 00667 it++) { 00668 MatchUnit& unit = *it; 00669 int pCol = unit.pivotUnit; 00670 int lCol = unit.localUnit; 00671 int rCol = unit.remoteUnit; 00672 bool deleted = unit.deleted; 00673 if (lCol!=-1&&rCol!=-1) { 00674 overlap++; 00675 } 00676 dbg_printf("final match %d: P/L/R %d %d %d %s\n", ct, pCol, lCol, rCol, 00677 deleted?"(deleted)":""); 00678 ct++; 00679 } 00680 dbg_printf("overlap is %d\n", overlap); 00681 00682 /* 00683 } else { 00684 fprintf(stderr, "No consistent order merge was possible.\n"); 00685 dbg_printf("No consistent order merge was possible.\n"); 00686 } 00687 */ 00688 } 00689 00690 00691 00692 void OrderMerge::merge_by_id(const OrderResult& nlocal, 00693 const OrderResult& nremote, 00694 const CompareFlags& flags) { 00695 /* 00696 vector<MergeUnit> units; 00697 for (int i=0; i<nlocal.alen(); i++) { 00698 MatchUnit unit; 00699 unit.pivotUnit = -1; 00700 unit.localUnit = i; 00701 unit.remoteUnit = nlocal.a2b(i); 00702 unit.deleted = false; 00703 units.push_back(unit); 00704 } 00705 00706 00707 bool more = true; 00708 00709 int at_local = 0; 00710 int at_remote = 0; 00711 int size_local = nlocal.alen(); 00712 int size_remote = nremote.blen(); 00713 while (more) { 00714 int l = -1; 00715 int l2r = -1; 00716 int r = -1; 00717 if (at_local<size_local) { 00718 l = at_local; 00719 l2r = nlocal.a2b(at_local); 00720 } 00721 if (at_remote<size_remote) { 00722 r = at_remote; 00723 } 00724 if (l==-1&&r==-1) { 00725 more = false; 00726 } 00727 MatchUnit unit; 00728 unit.pivotUnit = -1; 00729 unit.localUnit = -1; 00730 unit.remoteUnit = -1; 00731 unit.deleted = false; 00732 if (l!=-1 && l) 00733 00734 unit.pivotUnit = -1; 00735 unit.localUnit = -1; 00736 row_merge.accum.push_back(unit); 00737 00738 if (l!=-1) at_local++; 00739 if (r!=-1) at_remote++; 00740 } 00741 00742 00743 for (list<MatchUnit>::iterator it=accum.begin(); 00744 it!=accum.end(); 00745 it++) { 00746 if (it->deleted) { 00747 canon.push_back(*it); 00748 //dbg_printf(" ADDED DELETED -> %d (%d %d %d)\n", canon.size(), 00749 //it->pivotUnit, it->localUnit, it->remoteUnit); 00750 } 00751 } 00752 */ 00753 } 00754