COOPY » Guide  version 0.6.5
/home/paulfitz/cvs/coopy_scm/coopy/src/libcoopy_core/OrderMerge.cpp
Go to the documentation of this file.
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines