Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

SparseBitvector_intersection.hpp

Go to the documentation of this file.
00001 /*
00002  * SparseBitvector_intersection.hpp
00003  *
00004  * Time-stamp: <05/05/14 21:13:20 lars>
00005  *
00006  */
00007 
00008 #ifndef __SPARSE_BITVECTOR_INTERSECTION__
00009 #define __SPARSE_BITVECTOR_INTERSECTION__ t
00010 
00011 #include <iostream>
00012 using namespace std;
00013 
00014 #include "common/debug.hpp"
00015 
00016 extern long long numint;
00017 extern long long numlen;
00018 
00030 template <bool EARLY_FILTERING>
00031 //inline 
00032 bool intersection(SparseBitvector& result, const SparseBitvector& x, const SparseBitvector& y, const int minimalLength) {
00033   assert(x.length() > 0);
00034   assert(y.length() > 0);
00035   assert(&result != &x);
00036   assert(&result != &y);
00037   assert(result.capacity() >= minimalLength);
00038 
00039   // It is a bad idea to perform rowswapping here as this prevents inlining. Now done in the caller.
00040 
00041   // 1. setup stopping criteria.
00042   SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00043   if (EARLY_FILTERING && minimalLength > 1) { // nothing can be gained from minimalLength 0 or 1. 
00044     endx -= minimalLength - 1; 
00045     endy -= minimalLength - 1;
00046   }
00047 
00048   // 2. initialize loop
00049   SparseBitvector::iterator minimalResult = result.beginUnbounded() + minimalLength;
00050 
00051 
00052   // 3. loop over all elements
00053 #ifndef BALAZS 
00054   SparseBitvector::iterator iterResult = result.beginUnbounded();
00055   SparseBitvector::const_iterator iterx = x.begin(), itery = y.begin();
00056   int itemx = *iterx;
00057   int itemy = *itery;
00058   while (true) {
00059     if (itemx < itemy) { // miss in x
00060       ++iterx; if (iterx == endx) break;
00061       itemx = *iterx;
00062     } else if (itemx > itemy) { // miss in y
00063       ++itery; if (itery == endy) break;
00064       itemy = *itery;
00065     } else { // if (itemx == itemy) { // match
00066       *iterResult++ = itemx; 
00067       if (EARLY_FILTERING && iterResult < minimalResult) {
00068         ++endx;
00069         ++endy;
00070       } 
00071       ++iterx; if (iterx == endx) break;
00072       ++itery; if (itery == endy) break;
00073       itemx = *iterx; itemy = *itery;
00074       }
00075   }
00076 #else
00077 #if 0 //BALAZS==1
00078   register SparseBitvector::iterator iterResult  asm("ebx");
00079   iterResult = result.beginUnbounded();
00080   register SparseBitvector::const_iterator iterx asm("esi");
00081   iterx = x.begin();
00082   register SparseBitvector::const_iterator itery asm("edi");
00083   itery = y.begin();
00084   register int itemx=*iterx;
00085   register int itemy=*itery;
00086   //  __builtin_prefetch(iterx);
00087   //  __builtin_prefetch(iterx+32);
00088   //  __builtin_prefetch(iterx+64);
00089   //__builtin_prefetch(itery);
00090   //__builtin_prefetch(itery+32);
00091   //  __builtin_prefetch(itery+64);
00092   while (true) {
00093     //    numint++;
00094     //    itemx=*iterx;
00095     //__builtin_prefetch(iterx+128);
00096     // *iterResult=itemx;
00097     if (itemx==itemy) { //this is infrequent
00098       *iterResult++ = itemx;
00099       if (EARLY_FILTERING) {
00100         endx += (iterResult < minimalResult);
00101         endy += (iterResult < minimalResult);
00102       }
00103       iterx++;
00104       itery++;
00105       if (iterx == endx) break;
00106       if (itery == endy) break;
00107       itemx=*iterx;
00108       itemy=*itery;
00109     } else {
00110       //register unsigned char req asm ("cl");
00111       //register unsigned char rle asm ("al");
00112       //register unsigned char rge asm ("ah");
00113       // register unsigned int ia, ib;
00114       asm("leal 4(%[xref]),%%eax \n"
00115           "leal 4(%[yref]),%%edx \n"
00116           "cmpl %[yvalue],%[xvalue]\n"
00117           //          "movle %[xvalue],%[output] \n"
00118         //        "sete %[req] \n"
00119           // "setge %[rle] \n"
00120           //"setle %[rge] \n"
00121           "cmovle %%eax,%[xref] \n"
00122           "cmovge %%edx,%[yref] \n"
00123           "cmovle (%%eax),%[xvalue] \n"
00124           "cmovge (%%edx),%[yvalue] \n"
00125           : /*[req] "=q"(req),*/ /*[rle] "=q"(rle), [rge] "=q"(rge),*/ [xvalue]"+r" (itemx), [yvalue] "+r" (itemy), [xref] "+r" (iterx), [yref] "+r" (itery) : : "eax","edx");
00126       if (iterx == endx) break;
00127       if (itery == endy) break;
00128     }
00129     /*    *iterResult=itemx;
00130     iterResult+=(itemx==itemy);
00131     if (EARLY_FILTERING) {
00132       int t=(itemx==itemy)&&(iterResult<minimalResult);
00133       endx+=t;
00134       endy+=t;
00135     }
00136     iterx+=(itemx<=itemy);
00137     if (iterx == endx) break;
00138     itery+=(itemy<=itemx);
00139     if (itery == endy) break;
00140     itemx=*iterx;
00141     itemy=*itery;*/
00142   }
00143 #else
00144   register SparseBitvector::iterator iterResult  asm("ebx");
00145   iterResult = result.beginUnbounded();
00146   register SparseBitvector::const_iterator iterx asm("esi");
00147   iterx = x.begin();
00148   register SparseBitvector::const_iterator itery asm("edi");
00149   itery = y.begin();
00150   register int itemx=*iterx;
00151   register int itemy=*itery;
00152   while (true) {
00153     while (itemx < itemy) { // miss in x
00154       ++iterx; if (iterx == endx) goto exit;
00155       itemx = *iterx;
00156     }
00157     while (itemx==itemy) { // if (itemx == itemy) { // match
00158       *iterResult++ = itemx; 
00159       if (EARLY_FILTERING && iterResult < minimalResult) {
00160         ++endx;
00161         ++endy;
00162       } 
00163       ++iterx; if (iterx == endx) goto exit;
00164       ++itery; if (itery == endy) goto exit;
00165       itemx = *iterx; itemy = *itery;
00166     }
00167     while (itemx > itemy) { // miss in y
00168       ++itery; if (itery == endy) goto exit;
00169       itemy = *itery;
00170     }
00171     while (itemx==itemy) { // if (itemx == itemy) { // match
00172       *iterResult++ = itemx; 
00173       if (EARLY_FILTERING && iterResult < minimalResult) {
00174         ++endx;
00175         ++endy;
00176       } 
00177       ++iterx; if (iterx == endx) goto exit;
00178       ++itery; if (itery == endy) goto exit;
00179       itemx = *iterx; itemy = *itery;
00180     }
00181   }
00182 exit:
00183 #endif
00184 #endif
00185 
00186   result.resizeToEndOf(iterResult);
00187 
00188   return result.length() >= minimalLength;
00189 }
00190 
00200 template <bool EARLY_FILTERING>
00201 inline 
00202 int cardinalityOfIntersection(const SparseBitvector& x, const SparseBitvector& y, const int minimalLength) {
00203   assert(x.length() > 0);
00204   assert(y.length() > 0);
00205 
00206   // It is a bad idea to perform rowswapping here as this prevents inlining. Now done in the caller.
00207 
00208   // 1. setup stopping criteria.
00209   SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00210   if (EARLY_FILTERING && minimalLength > 1) { // nothing can be gained from minimalLength 0 or 1. 
00211     endx -= minimalLength - 1; 
00212     endy -= minimalLength - 1;
00213   }
00214 
00215   // 2. initialize loop
00216   SparseBitvector::const_iterator iterx = x.begin(), itery = y.begin();
00217   int itemx = *iterx;
00218   int itemy = *itery;
00219   int resultLength = 0;
00220 
00221   // 3. loop over all elements
00222 
00223 
00224   while (true) {
00225 #ifndef BALAZS
00226     if (itemx < itemy) { // miss in x
00227       ++iterx; if (iterx == endx) break;
00228       itemx = *iterx;
00229     } else if (itemx > itemy) { // miss in y
00230       ++itery; if (itery == endy) break;
00231       itemy = *itery;
00232     } else { // if (itemx == itemy) { // match
00233       ++resultLength;
00234       if (EARLY_FILTERING && resultLength < minimalLength) {
00235         ++endx;
00236         ++endy;
00237       } 
00238       ++iterx; if (iterx == endx) break;
00239       ++itery; if (itery == endy) break;
00240       itemx = *iterx; itemy = *itery;
00241       }
00242 
00243 #else
00244     //*iterResult=itemx;
00245     numlen++;
00246     resultLength+=(itemx==itemy);
00247     if (EARLY_FILTERING) {
00248       int t=(itemx==itemy)&&(resultLength<minimalLength);
00249       endx+=t;
00250       endy+=t;
00251     }
00252     iterx+=(itemx<=itemy);
00253     if (iterx == endx) break;
00254     itery+=(itemy<=itemx);
00255     if (itery == endy) break;
00256     itemx=*iterx;
00257     itemy=*itery;
00258 #endif
00259   }
00260 
00261   if (resultLength < minimalLength) // due to early filtering resultLength might not be correct if it is < minimalLength; so set it to 0.
00262     resultLength = 0;
00263 
00264   return resultLength;
00265 }
00266 
00267 
00268 #endif

Generated on Sun Sep 17 17:50:40 2006 for FIM environment by  doxygen 1.4.4