diff options
Diffstat (limited to '3rdparty/clucene/src/CLucene/search/RangeFilter.cpp')
-rw-r--r-- | 3rdparty/clucene/src/CLucene/search/RangeFilter.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp b/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp new file mode 100644 index 000000000..66ee5ce55 --- /dev/null +++ b/3rdparty/clucene/src/CLucene/search/RangeFilter.cpp @@ -0,0 +1,150 @@ +/*------------------------------------------------------------------------------ +* Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team +* +* Distributable under the terms of either the Apache License (Version 2.0) or +* the GNU Lesser General Public License, as specified in the COPYING file. +------------------------------------------------------------------------------*/ +#include "CLucene/StdHeader.h" +#include "RangeFilter.h" + +CL_NS_DEF(search) +CL_NS_USE(index) +CL_NS_USE(util) +CL_NS_USE(document) + + +RangeFilter::RangeFilter( const TCHAR* fieldName, const TCHAR* lowerTerm, const TCHAR* upperTerm, bool includeLower, bool includeUpper ) +{ + this->field = STRDUP_TtoT(fieldName); + if ( lowerTerm != NULL ) + this->lowerValue = STRDUP_TtoT(lowerTerm); + else + this->lowerValue = NULL; + if ( upperTerm != NULL ) + this->upperValue = STRDUP_TtoT(upperTerm); + else + this->upperValue = NULL; + this->includeLower = includeLower; + this->includeUpper = includeUpper; +} + + +/** + * Constructs a filter for field <code>fieldName</code> matching + * less than or equal to <code>upperTerm</code>. + */ +RangeFilter* RangeFilter::Less( TCHAR* fieldName, TCHAR* upperTerm ) { + return new RangeFilter( fieldName, NULL, upperTerm, false, true ); +} + + +/** +* Constructs a filter for field <code>fieldName</code> matching +* more than or equal to <code>lowerTerm</code>. +*/ +RangeFilter* RangeFilter::More( TCHAR* fieldName, TCHAR* lowerTerm ) { + return new RangeFilter( fieldName, lowerTerm, NULL, true, false ); +} + + +RangeFilter::~RangeFilter() +{ + _CLDELETE_CARRAY( lowerValue ); + _CLDELETE_CARRAY( field ); + _CLDELETE_CARRAY( upperValue ); +} + + +RangeFilter::RangeFilter( const RangeFilter& copy ) : + field( STRDUP_TtoT(copy.field) ), + lowerValue( STRDUP_TtoT(copy.lowerValue) ), + upperValue( STRDUP_TtoT(copy.upperValue) ), + includeLower( copy.includeLower ), + includeUpper( copy.includeUpper ) +{ +} + + +Filter* RangeFilter::clone() const { + return _CLNEW RangeFilter(*this ); +} + + +TCHAR* RangeFilter::toString() +{ + size_t len = (field ? _tcslen(field) : 0) + (lowerValue ? _tcslen(lowerValue) : 0) + (upperValue ? _tcslen(upperValue) : 0) + 8; + TCHAR* ret = _CL_NEWARRAY( TCHAR, len ); + ret[0] = 0; + _sntprintf( ret, len, _T("%s: [%s-%s]"), field, (lowerValue?lowerValue:_T("")), (upperValue?upperValue:_T("")) ); + + return ret; +} + + +/** Returns a BitSet with true for documents which should be permitted in +search results, and false for those that should not. */ +BitSet* RangeFilter::bits( IndexReader* reader ) +{ + BitSet* bts = _CLNEW BitSet( reader->maxDoc() ); + Term* term = NULL; + + Term* t = _CLNEW Term( field, (lowerValue ? lowerValue : _T("")), false ); + TermEnum* enumerator = reader->terms( t ); // get enumeration of all terms after lowerValue + _CLDECDELETE( t ); + + if( enumerator->term(false) == NULL ) { + _CLDELETE( enumerator ); + return bts; + } + + bool checkLower = false; + if( !includeLower ) // make adjustments to set to exclusive + checkLower = true; + + TermDocs* termDocs = reader->termDocs(); + + try + { + do + { + term = enumerator->term(); + + if( term == NULL || _tcscmp(term->field(), field) ) + break; + + if( !checkLower || lowerValue == NULL || _tcscmp(term->text(), lowerValue) > 0 ) + { + checkLower = false; + if( upperValue != NULL ) + { + int compare = _tcscmp( upperValue, term->text() ); + + /* if beyond the upper term, or is exclusive and + * this is equal to the upper term, break out */ + if( (compare < 0) || (!includeUpper && compare == 0) ) + break; + } + + termDocs->seek( enumerator->term(false) ); + while( termDocs->next() ) { + bts->set( termDocs->doc() ); + } + } + + _CLDECDELETE( term ); + } + while( enumerator->next() ); + } + _CLFINALLY + ( + _CLDECDELETE( term ); + termDocs->close(); + _CLVDELETE( termDocs ); + enumerator->close(); + _CLDELETE( enumerator ); + ); + + return bts; +} + +CL_NS_END |