00001
00002
00003
00004
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
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
00040
00041
00042 SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00043 if (EARLY_FILTERING && minimalLength > 1) {
00044 endx -= minimalLength - 1;
00045 endy -= minimalLength - 1;
00046 }
00047
00048
00049 SparseBitvector::iterator minimalResult = result.beginUnbounded() + minimalLength;
00050
00051
00052
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) {
00060 ++iterx; if (iterx == endx) break;
00061 itemx = *iterx;
00062 } else if (itemx > itemy) {
00063 ++itery; if (itery == endy) break;
00064 itemy = *itery;
00065 } else {
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
00087
00088
00089
00090
00091
00092 while (true) {
00093
00094
00095
00096
00097 if (itemx==itemy) {
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
00111
00112
00113
00114 asm("leal 4(%[xref]),%%eax \n"
00115 "leal 4(%[yref]),%%edx \n"
00116 "cmpl %[yvalue],%[xvalue]\n"
00117
00118
00119
00120
00121 "cmovle %%eax,%[xref] \n"
00122 "cmovge %%edx,%[yref] \n"
00123 "cmovle (%%eax),%[xvalue] \n"
00124 "cmovge (%%edx),%[yvalue] \n"
00125 : [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
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
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) {
00154 ++iterx; if (iterx == endx) goto exit;
00155 itemx = *iterx;
00156 }
00157 while (itemx==itemy) {
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) {
00168 ++itery; if (itery == endy) goto exit;
00169 itemy = *itery;
00170 }
00171 while (itemx==itemy) {
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
00207
00208
00209 SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00210 if (EARLY_FILTERING && minimalLength > 1) {
00211 endx -= minimalLength - 1;
00212 endy -= minimalLength - 1;
00213 }
00214
00215
00216 SparseBitvector::const_iterator iterx = x.begin(), itery = y.begin();
00217 int itemx = *iterx;
00218 int itemy = *itery;
00219 int resultLength = 0;
00220
00221
00222
00223
00224 while (true) {
00225 #ifndef BALAZS
00226 if (itemx < itemy) {
00227 ++iterx; if (iterx == endx) break;
00228 itemx = *iterx;
00229 } else if (itemx > itemy) {
00230 ++itery; if (itery == endy) break;
00231 itemy = *itery;
00232 } else {
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
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)
00262 resultLength = 0;
00263
00264 return resultLength;
00265 }
00266
00267
00268 #endif