commit 82ace7c7584e07463ce831b827aeb49c25b0e3ce
Author: dprunier <dominique.prunier@watch4net.com>
Date:   Wed Mar 21 16:46:48 2012

    limitate the number of calls to bitevector::cnt() in query evaluation methods

diff --git a/src/category.cpp b/src/category.cpp
index 48176d3..1b14ca5 100644
--- a/src/category.cpp
+++ b/src/category.cpp
@@ -726,7 +726,6 @@ long ibis::category::patternSearch(const char *pat,
     LOGGER(ibis::gVerbose > 5)
 	<< "category[" << (thePart != 0 ? thePart->name() : "??") << '.'
 	<< m_name << "]::patternSearch starting to match pattern " << pat;
-    long est = 0;
     uint32_t cnt = 0;
     ibis::array_t<uint32_t> tmp;
     dic.patternSearch(pat, tmp);
@@ -734,20 +733,15 @@ long ibis::category::patternSearch(const char *pat,
 	const ibis::bitvector *bv = rlc->getBitvector(tmp[j]);
 	if (bv != 0) {
 	    ++ cnt;
-	    est += bv->cnt();
 	    if (hits.empty()) {
 		hits.copy(*bv);
 	    }
 	    else {
-		if (cnt > 32 || (j > 3 && cnt*16 > j))
-		    hits.decompress();
 		hits |= *bv;
 	    }
 	}
     }
-    if (est > static_cast<long>(hits.size() >> 7))
-	hits.compress();
-    return est;
+    return cnt;
 } // ibis::category::patternSearch
 
 /// Return the string at the <code>i</code>th row.  If the .int file is
diff --git a/src/query.cpp b/src/query.cpp
index e27c8bd..40b8dab 100755
--- a/src/query.cpp
+++ b/src/query.cpp
@@ -2958,6 +2958,7 @@ long ibis::query::getExpandedHits(ibis::bitvector& res) const {
 } // ibis::query::getExpandedHits
 
 /// Perform a sequential scan.
+/// TODO: skip calls to bitevector::cnt()
 int ibis::query::doScan(const ibis::qExpr* term,
 			ibis::bitvector& ht) const {
     int ierr = 0;
@@ -3108,6 +3109,7 @@ int ibis::query::doScan(const ibis::qExpr* term,
 } // ibis::query::doScan
 
 /// Masked sequential scan.
+/// TODO: skip calls to bitevector::cnt()
 int ibis::query::doScan(const ibis::qExpr* term, const ibis::bitvector& mask,
 			ibis::bitvector& ht) const {
     int ierr = 0;
@@ -3528,7 +3530,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 			    ibis::bitvector& ht) const {
     if (term == 0) { // match everything
 	ht.set(1, mypart->nRows());
-	return 0;
+	return mypart->nRows();
     }
     LOGGER(ibis::gVerbose > 5)
 	<< "query[" << myID << "]::doEvaluate -- starting to evaluate "
@@ -3540,7 +3542,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	ierr = doEvaluate(term->getLeft(), ht);
 	if (ierr >= 0) {
 	    ht.flip();
-	    ierr = ht.cnt();
+	    ierr = 1;
 	}
 	break;
     }
@@ -3559,13 +3561,15 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	if (ierr >= 0) {
 	    ibis::bitvector b1;
 	    ierr = doEvaluate(term->getRight(), b1);
-	    if (ierr >= 0)
+	    if (ierr >= 0) {
 		ht |= b1;
-	    ierr = ht.cnt();
+		ierr = 1;
+	    }
 	}
 	break;
     }
     case ibis::qExpr::LOGICAL_XOR: {
+	// TODO: skip calls to bitevector::cnt()
 	ierr = doEvaluate(term->getLeft(), ht);
 	if (ierr >= 0) {
 	    ibis::bitvector b1;
@@ -3577,6 +3581,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::LOGICAL_MINUS: {
+	// TODO: skip calls to bitevector::cnt()
 	ierr = doEvaluate(term->getLeft(), ht);
 	if (ierr > 0) {
 	    ibis::bitvector b1;
@@ -3588,6 +3593,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::RANGE: {
+	// TODO: skip calls to bitevector::cnt()
 	ibis::bitvector tmp;
 	tmp.set(1, mypart->nRows());
 	ierr = mypart->evaluateRange
@@ -3613,6 +3619,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::DRANGE: { // call evalauteRange, use doScan on failure
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qDiscreteRange*>(term)),
 	     mypart->getNullMask(), ht);
@@ -3637,12 +3644,14 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::INTHOD: { // call evalauteRange, use doScan on failure
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qIntHod*>(term)),
 	     mypart->getNullMask(), ht);
 	break;
     }
     case ibis::qExpr::UINTHOD: { // call evalauteRange, use doScan on failure
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qUIntHod*>(term)),
 	     mypart->getNullMask(), ht);
@@ -3677,6 +3686,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::MATHTERM: {
+	// TODO: skip calls to bitevector::cnt()
 	const ibis::math::term &mt =
 	    *(reinterpret_cast<const ibis::math::term*>(term));
 	if (mt.isConstant()) {
@@ -3697,6 +3707,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::ANYANY: {
+	// TODO: skip calls to bitevector::cnt()
 	const ibis::qAnyAny *tmp =
 	    reinterpret_cast<const ibis::qAnyAny*>(term);
 	ibis::bitvector more;
@@ -3749,26 +3760,26 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 int ibis::query::doEvaluate(const ibis::qExpr* term,
 			    const ibis::bitvector& mask,
 			    ibis::bitvector& ht) const {
-    int ierr = 0;
     if (term == 0) { // all hits
-	ht.set(1, mypart->nRows());
-	return ierr;
+	ht.copy(mask);
+	return mypart->nRows();
     }
     if (mask.cnt() == 0) { // no hits
 	ht.set(0, mask.size());
-	return ierr;
+	return 0;
     }
     LOGGER(ibis::gVerbose > 7)
 	<< "query[" << myID << "]::doEvaluate -- starting to evaluate "
 	<< *term;
 
+    int ierr = 0;
     switch (term->getType()) {
     case ibis::qExpr::LOGICAL_NOT: {
 	ierr = doEvaluate(term->getLeft(), mask, ht);
 	if (ierr >= 0) {
 	    ht.flip();
 	    ht &= mask;
-	    ierr = ht.cnt();
+	    ierr = 1;
 	}
 	break;
     }
@@ -3784,22 +3795,18 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
     }
     case ibis::qExpr::LOGICAL_OR: {
 	ierr = doEvaluate(term->getLeft(), mask, ht);
-	if (ierr >= 0 && ht.cnt() < mask.cnt()) {
+	if (ierr >= 0) {
 	    ibis::bitvector b1;
-	    if (ht.cnt() > mask.bytes() + ht.bytes()) {
-		std::auto_ptr<ibis::bitvector> newmask(mask - ht);
-		ierr = doEvaluate(term->getRight(), *newmask, b1);
-	    }
-	    else {
-		ierr = doEvaluate(term->getRight(), mask, b1);
-	    }
-	    if (ierr >= 0)
+	    ierr = doEvaluate(term->getRight(), mask, b1);
+	    if (ierr >= 0) {
 		ht |= b1;
-	    ierr = ht.cnt();
+		ierr = 1;
+	    }
 	}
 	break;
     }
     case ibis::qExpr::LOGICAL_XOR: {
+	// TODO: skip calls to bitevector::cnt()
 	ierr = doEvaluate(term->getLeft(), mask, ht);
 	if (ierr >= 0) {
 	    ibis::bitvector b1;
@@ -3812,6 +3819,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::LOGICAL_MINUS: {
+	// TODO: skip calls to bitevector::cnt()
 	ierr = doEvaluate(term->getLeft(), mask, ht);
 	if (ierr > 0) {
 	    ibis::bitvector b1;
@@ -3823,6 +3831,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::RANGE: {
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qContinuousRange*>(term)),
 	     mask, ht);
@@ -3854,6 +3863,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::DRANGE: { // try evaluateRange, then doScan
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qDiscreteRange*>(term)), mask, ht);
 	if (ierr < 0) { // revert to estimate and scan
@@ -3884,6 +3894,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::INTHOD: { // try evaluateRange, then doScan
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qIntHod*>(term)), mask, ht);
 	if (ierr < 0) { // revert to estimate and scan
@@ -3914,6 +3925,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::UINTHOD: { // try evaluateRange, then doScan
+	// TODO: skip calls to bitevector::cnt()
 	ierr = mypart->evaluateRange
 	    (*(reinterpret_cast<const ibis::qUIntHod*>(term)), mask, ht);
 	if (ierr < 0) { // revert to estimate and scan
@@ -3946,18 +3958,16 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
     case ibis::qExpr::STRING: {
 	ierr = mypart->lookforString
 	    (*(reinterpret_cast<const ibis::qString*>(term)), ht);
-	if (ierr >= 0) {
+	if (ierr > 0) {
 	    ht &= mask;
-	    ierr = ht.cnt();
 	}
 	break;
     }
     case ibis::qExpr::LIKE: {
 	ierr = mypart->patternSearch
 	    (*(reinterpret_cast<const ibis::qLike*>(term)), ht);
-	if (ierr >= 0) {
+	if (ierr > 0) {
 	    ht &= mask;
-	    ierr = ht.cnt();
 	}
 	break;
     }
@@ -3967,7 +3977,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	if (cr.isConstant()) {
 	    if (cr.inRange()) {
 		ht.copy(mask);
-		ierr = mask.cnt();
+		ierr = 1;
 	    }
 	    else {
 		ht.set(0, mask.size());
@@ -3980,6 +3990,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::MATHTERM: {
+	// TODO: skip calls to bitevector::cnt()
 	const ibis::math::term &mt =
 	    *(reinterpret_cast<const ibis::math::term*>(term));
 	if (mt.isConstant()) {
@@ -3998,6 +4009,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
 	break;
     }
     case ibis::qExpr::ANYANY: {
+	// TODO: skip calls to bitevector::cnt()
 	const ibis::qAnyAny *tmp =
 	    reinterpret_cast<const ibis::qAnyAny*>(term);
 	ibis::bitvector more;
@@ -4018,7 +4030,7 @@ int ibis::query::doEvaluate(const ibis::qExpr* term,
     case ibis::qExpr::TOPK:
     case ibis::qExpr::DEPRECATEDJOIN: { // pretend every row qualifies
 	ht.copy(mask);
-	ierr = ht.cnt();
+	ierr = 1;
 	break;
     }
     default:
