00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SPARSE_BITVECTOR_SETDIFFERENCE__
00009 #define __SPARSE_BITVECTOR_SETDIFFERENCE__ t
00010
00011 #include <iostream>
00012 using namespace std;
00013
00014 #include "common/debug.hpp"
00015 #include "SparseBitvector.hpp"
00016
00028 template <bool EARLY_FILTERING>
00029 inline
00030 bool setdifference(SparseBitvector& result, const SparseBitvector& x, const SparseBitvector& y,
00031 const int maximalLength) {
00032 assert(x.length() > 0);
00033 assert(y.length() > 0);
00034 assert(&result != &x);
00035 assert(&result != &y);
00036 assert(!EARLY_FILTERING || maximalLength <= x.length());
00037 assert(result.capacity() >= maximalLength || result.capacity() >= x.length());
00038
00039
00040 SparseBitvector::iterator maximalResult = result.beginUnbounded(),
00041 iterResult = result.beginUnbounded();
00042 if (EARLY_FILTERING)
00043 maximalResult += maximalLength;
00044
00045 SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00046
00047 #ifndef BALAZS
00048 SparseBitvector::const_iterator iterx = x.begin(), itery = y.begin();
00049 int itemx = *iterx;
00050 int itemy = *itery;
00051
00052 while (true) {
00053 if (itemx < itemy) {
00054 if (EARLY_FILTERING && iterResult >= maximalResult) { return false; }
00055 *iterResult++ = itemx;
00056 ++iterx; if (iterx == endx) break;
00057 itemx = *iterx;
00058 } else if (itemx > itemy) {
00059 ++itery; if (itery == endy) break;
00060 itemy = *itery;
00061 } else {
00062 ++iterx; if (iterx == endx) break;
00063 ++itery; if (itery == endy) break;
00064 itemx = *iterx;
00065 itemy = *itery;
00066 }
00067 }
00068 #else
00069
00070 register SparseBitvector::const_iterator iterx = x.begin();
00071 register SparseBitvector::const_iterator itery = y.begin();
00072 register int itemx = *iterx;
00073 register int itemy = *itery;
00074
00075 while (true) {
00076 if (itemx < itemy) {
00077 do {
00078 if (EARLY_FILTERING && iterResult >= maximalResult) { return false; }
00079 *iterResult++ = itemx;
00080 ++iterx; if (iterx == endx) goto exit;
00081 itemx = *iterx;
00082 } while (itemx<itemy);
00083 } else {
00084 ++itery;
00085 asm("leal 4(%[xref]),%%eax \n"
00086 "cmpl %[yvalue],%[xvalue]\n"
00087 "cmove %%eax,%[xref] \n"
00088 "cmove (%%eax),%[xvalue] \n"
00089 : [xvalue]"+r" (itemx) ,[xref] "+r" (iterx) : [yvalue] "r" (itemy) : "eax");
00090 if (itery == endy) break;
00091 if (iterx == endx) break;
00092 itemy = *itery;
00093 }
00094 }
00095 exit:
00096 #endif
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 for ( ; iterx != endx; ++iterx)
00110 *iterResult++ = *iterx;
00111
00112 result.resizeToEndOf(iterResult);
00113
00114 return result.length() <= maximalLength;
00115 }
00116
00117
00127 template <bool EARLY_FILTERING>
00128 inline
00129 int cardinalityOfSetdifference(const SparseBitvector& x, const SparseBitvector& y, const int maximalLength) {
00130 assert(x.length() > 0);
00131 assert(y.length() > 0);
00132
00133
00134 int resultLength = 0;
00135 SparseBitvector::const_iterator endx = x.end(), endy = y.end();
00136 SparseBitvector::const_iterator iterx = x.begin(), itery = y.begin();
00137 int itemx = *iterx;
00138 int itemy = *itery;
00139
00140
00141 while (true) {
00142 if (itemx < itemy) {
00143 if (EARLY_FILTERING && resultLength >= maximalLength) { return maximalLength+1; }
00144 ++resultLength;
00145 ++iterx; if (iterx == endx) break;
00146 itemx = *iterx;
00147 } else if (itemx > itemy) {
00148 ++itery; if (itery == endy) break;
00149 itemy = *itery;
00150 } else {
00151 ++iterx; if (iterx == endx) break;
00152 ++itery; if (itery == endy) break;
00153 itemx = *iterx;
00154 itemy = *itery;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 }
00167
00168
00169 resultLength += endx - iterx;
00170
00171 return resultLength;
00172 }
00173
00174 #endif