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

LightVector_set_intersection.hpp

Go to the documentation of this file.
00001 
00008 #ifndef __LIGHT_VECTOR_SET_INTERSECTION__
00009 #define __LIGHT_VECTOR_SET_INTERSECTION__ t
00010 
00011 #include "common/debug.hpp"
00012 #include "LightVector.hpp"
00013 
00026 template <bool EARLY_FILTERING, class TYPE>
00027 inline 
00028 bool set_intersection(LightVector<TYPE>& result, const LightVector<TYPE>& x, const LightVector<TYPE>& y, const int minimalSize = 0) {
00029   assert(x.size() > 0); // 1. make sure inputs are not trivial.
00030   assert(y.size() > 0);
00031   assert(minimalSize <= x.size()); // otherwise outcome never can be true.
00032   assert(minimalSize <= y.size()); // otherwise outcome never can be true.
00033   assert(! EARLY_FILTERING || minimalSize >= 2); // otherwise EARLY_FILTERING is turned on in vain.
00034 
00035   assert(&result != &x); // 2. make sure output and inputs are not intermingled.
00036   assert(&result != &y);
00037 
00038   assert(result.capacity() >= minimalSize || result.capacity() >= x.size() || result.capacity() >= y.size()); // 3. make sure output capacity is sufficient. 
00039   assert(EARLY_FILTERING || result.capacity() >= x.size() || result.capacity() >= y.size());
00040 
00041   // It is a bad idea to perform rowswapping here as this prevents inlining. Now done in the caller.
00042 
00043   // 0. actually we almost only work on iterators: (but for resizeToEndOf we need the object)
00044   typename LightVector<TYPE>::const_iterator iterx = x.begin(), itery = y.begin(), endx = x.end(), endy = y.end();
00045   typename LightVector<TYPE>::iterator iterResult = result.beginUnbounded();
00046 
00047   // 1. setup stopping criteria.
00048   if (EARLY_FILTERING && minimalSize > 1) { // nothing can be gained from minimalSize 0 or 1. 
00049     endx -= minimalSize - 1; 
00050     endy -= minimalSize - 1;
00051   }
00052 
00053   // 2. initialize loop
00054   typename LightVector<TYPE>::iterator minimalResult = iterResult + minimalSize;
00055   int itemx = *iterx;
00056   int itemy = *itery;
00057 
00058   // 3. loop over all elements
00059   while (true) {
00060     if (itemx < itemy) { // miss in x
00061       ++iterx; if (iterx == endx) break;
00062       itemx = *iterx;
00063     } else if (itemx > itemy) { // miss in y
00064       ++itery; if (itery == endy) break;
00065       itemy = *itery;
00066     } else { // if (itemx == itemy) { // match
00067       *iterResult++ = itemx; 
00068       if (EARLY_FILTERING && iterResult < minimalResult) {
00069         ++endx;
00070         ++endy;
00071       } 
00072       ++iterx; if (iterx == endx) break;
00073       ++itery; if (itery == endy) break;
00074       itemx = *iterx; itemy = *itery;
00075     }
00076   }
00077 
00078   result.resizeToEndOf(iterResult);
00079 
00080   return result.size() >= minimalSize;
00081 }
00082 
00092 template <bool EARLY_FILTERING, class TYPE>
00093 inline 
00094 int cardinality_of_set_intersection(const LightVector<TYPE>& x, const LightVector<TYPE>& y, const int minimalSize = 0) {
00095   assert(x.size() > 0); // make sure inputs are not trivial.
00096   assert(y.size() > 0);
00097   assert(minimalSize <= x.size()); // otherwise outcome never can be true.
00098   assert(minimalSize <= y.size()); // otherwise outcome never can be true.
00099   assert(! EARLY_FILTERING || minimalSize >= 2); // otherwise EARLY_FILTERING is turned on in vain.
00100 
00101   // It is a bad idea to perform rowswapping here as this prevents inlining. Now done in the caller.
00102 
00103   // 0. actually we only work on iterators: 
00104   typename LightVector<TYPE>::const_iterator iterx = x.begin(), itery = y.begin(), endx = x.end(), endy = y.end();
00105 
00106   // 1. setup stopping criteria.
00107   if (EARLY_FILTERING && minimalSize > 1) { // nothing can be gained from minimalSize 0 or 1. 
00108     endx -= minimalSize - 1; 
00109     endy -= minimalSize - 1;
00110   }
00111 
00112   // 2. initialize loop
00113   int itemx = *iterx;
00114   int itemy = *itery;
00115   int resultSize = 0;
00116 
00117   // 3. loop over all elements
00118   while (true) {
00119     if (itemx < itemy) { // miss in x
00120       ++iterx; if (iterx == endx) break;
00121       itemx = *iterx;
00122     } else if (itemx > itemy) { // miss in y
00123       ++itery; if (itery == endy) break;
00124       itemy = *itery;
00125     } else { // if (itemx == itemy) { // match
00126       ++resultSize;
00127       if (EARLY_FILTERING && resultSize < minimalSize) {
00128         ++endx;
00129         ++endy;
00130       } 
00131       ++iterx; if (iterx == endx) break;
00132       ++itery; if (itery == endy) break;
00133       itemx = *iterx; itemy = *itery;
00134     }
00135   }
00136 
00137   if (resultSize < minimalSize) // due to early filtering resultSize might not be correct if it is < minimalSize; so set it to 0.
00138     resultSize = 0;
00139 
00140   return resultSize;
00141 }
00142 
00143 
00144 #endif

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