summaryrefslogtreecommitdiffstats
path: root/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp')
-rw-r--r--3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp b/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp
new file mode 100644
index 000000000..4b6389c0f
--- /dev/null
+++ b/3rdparty/clucene/src/CLucene/search/ChainedFilter.cpp
@@ -0,0 +1,213 @@
+/*------------------------------------------------------------------------------
+* 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 <CLucene/util/Misc.h>
+#include "ChainedFilter.h"
+
+CL_NS_DEF(search)
+CL_NS_USE(index)
+CL_NS_USE(util)
+CL_NS_USE(document)
+
+
+ChainedFilter::ChainedFilter( Filter ** _filters, int _op ):
+ filters(_filters),
+ logicArray(NULL),
+ logic(_op)
+{
+}
+ChainedFilter::ChainedFilter( Filter** _filters, int* _array ):
+ filters(_filters),
+ logicArray(_array),
+ logic(-1)
+{
+}
+ChainedFilter::ChainedFilter( const ChainedFilter& copy ) :
+ logicArray( copy.logicArray ),
+ logic( copy.logic )
+{
+ filters = copy.filters;
+}
+ChainedFilter::~ChainedFilter(void)
+{
+
+}
+
+Filter* ChainedFilter::clone() const {
+ return _CLNEW ChainedFilter(*this );
+}
+
+const TCHAR* ChainedFilter::getLogicString(int logic){
+ if ( logic == ChainedFilter::OR )
+ return _T("OR");
+ else if ( logic == ChainedFilter::AND )
+ return _T("AND");
+ else if ( logic == ChainedFilter::ANDNOT )
+ return _T("ANDNOT");
+ else if ( logic == ChainedFilter::XOR )
+ return _T("XOR");
+ else if ( logic >= ChainedFilter::USER ){
+ return _T("USER");
+ }
+ return _T("");
+}
+
+TCHAR* ChainedFilter::toString()
+{
+
+ Filter** filter = filters;
+
+ StringBuffer buf(_T("ChainedFilter: ["));
+ int* la = logicArray;
+ while(*filter )
+ {
+ if ( filter != filters )
+ buf.appendChar(' ');
+ buf.append(getLogicString(logic==-1?*la:logic));
+ buf.appendChar(' ');
+
+ TCHAR* filterstr = (*filter)->toString();
+ buf.append(filterstr);
+ _CLDELETE_ARRAY( filterstr );
+
+ filter++;
+ if ( logic == -1 )
+ la++;
+ }
+
+ buf.appendChar(']');
+
+ return buf.toString();
+}
+
+
+/** Returns a BitSet with true for documents which should be permitted in
+search results, and false for those that should not. */
+BitSet* ChainedFilter::bits( IndexReader* reader )
+{
+ if( logic != -1 )
+ return bits( reader, logic );
+ else if( logicArray != NULL )
+ return bits( reader, logicArray );
+ else
+ return bits( reader, DEFAULT );
+}
+
+
+BitSet* ChainedFilter::bits( IndexReader* reader, int logic )
+{
+ BitSet* bts = NULL;
+
+ Filter** filter = filters;
+
+ // see discussion at top of file
+ if( *filter ) {
+ BitSet* tmp = (*filter)->bits( reader );
+ if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then
+ bts = tmp; //we can safely call it our own
+ else if ( tmp == NULL ){
+ int32_t len = reader->maxDoc();
+ bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_
+ for (int32_t i=0;i<len;i++ )
+ bts->set(i);
+ }else{
+ bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it.
+ }
+ filter++;
+ }
+ else
+ bts = _CLNEW BitSet( reader->maxDoc() );
+
+ while( *filter ) {
+ doChain( bts, reader, logic, *filter );
+ filter++;
+ }
+
+ return bts;
+}
+
+
+BitSet* ChainedFilter::bits( IndexReader* reader, int* _logicArray )
+{
+ BitSet* bts = NULL;
+
+ Filter** filter = filters;
+ int* logic = _logicArray;
+
+ // see discussion at top of file
+ if( *filter ) {
+ BitSet* tmp = (*filter)->bits( reader );
+ if ( (*filter)->shouldDeleteBitSet(tmp) ) //if we are supposed to delete this BitSet, then
+ bts = tmp; //we can safely call it our own
+ else if ( tmp == NULL ){
+ int32_t len = reader->maxDoc();
+ bts = _CLNEW BitSet( len ); //bitset returned null, which means match _all_
+ for (int32_t i=0;i<len;i++ )
+ bts->set(i); //todo: this could mean that we can skip certain types of filters
+ }
+ else
+ {
+ bts = tmp->clone(); //else it is probably cached, so we need to copy it before using it.
+ }
+ filter++;
+ logic++;
+ }
+ else
+ bts = _CLNEW BitSet( reader->maxDoc() );
+
+ while( *filter ) {
+ doChain( bts, reader, *logic, *filter );
+ filter++;
+ logic++;
+ }
+
+ return bts;
+}
+
+void ChainedFilter::doUserChain( CL_NS(util)::BitSet* chain, CL_NS(util)::BitSet* filter, int logic ){
+ _CLTHROWA(CL_ERR_Runtime,"User chain logic not implemented by superclass");
+}
+
+BitSet* ChainedFilter::doChain( BitSet* resultset, IndexReader* reader, int logic, Filter* filter )
+{
+ BitSet* filterbits = filter->bits( reader );
+ int32_t maxDoc = reader->maxDoc();
+ int32_t i=0;
+ if ( logic >= ChainedFilter::USER ){
+ doUserChain(resultset,filterbits,logic);
+ }else{
+ switch( logic )
+ {
+ case OR:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) || (filterbits==NULL || filterbits->get(i) ))?1:0 );
+ break;
+ case AND:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i) ))?1:0 );
+ break;
+ case ANDNOT:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, (resultset->get(i) && (filterbits==NULL || filterbits->get(i)))?0:1 );
+ break;
+ case XOR:
+ for( i=0; i < maxDoc; i++ )
+ resultset->set( i, resultset->get(i) ^ ((filterbits==NULL || filterbits->get(i) )?1:0) );
+ break;
+ default:
+ doChain( resultset, reader, DEFAULT, filter );
+ }
+ }
+
+ if ( filter->shouldDeleteBitSet(filterbits) )
+ _CLDELETE( filterbits );
+
+ return resultset;
+}
+
+CL_NS_END