You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by bu...@apache.org on 2008/05/23 21:25:05 UTC

svn commit: r659635 - in /lucene/java/trunk: ./ contrib/miscellaneous/src/java/org/apache/lucene/misc/ contrib/miscellaneous/src/test/org/apache/lucene/misc/ contrib/queries/src/java/org/apache/lucene/search/ contrib/queries/src/test/org/apache/lucene/...

Author: buschmi
Date: Fri May 23 12:25:05 2008
New Revision: 659635

URL: http://svn.apache.org/viewvc?rev=659635&view=rev
Log:
LUCENE-1187: ChainedFilter and BooleanFilter now work with new Filter API and DocIdSetIterator-based filters.

Added:
    lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
    lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java
Modified:
    lucene/java/trunk/CHANGES.txt
    lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java
    lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java
    lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java
    lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java
    lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java
    lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java
    lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java
    lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
    lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java

Modified: lucene/java/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/CHANGES.txt (original)
+++ lucene/java/trunk/CHANGES.txt Fri May 23 12:25:05 2008
@@ -163,6 +163,10 @@
 
 13. LUCENE-1166: Decomposition tokenfilter for languages like German and Swedish (Thomas Peuss via Grant Ingersoll)
 
+14. LUCENE-1187: ChainedFilter and BooleanFilter now work with new Filter API
+    and DocIdSetIterator-based filters. Backwards-compatibility with old 
+    BitSet-based filters is ensured. (Paul Elschot via Michael Busch)
+
 Optimizations
 
  1. LUCENE-705: When building a compound file, use

Modified: lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java (original)
+++ lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java Fri May 23 12:25:05 2008
@@ -58,7 +58,11 @@
 import org.apache.lucene.search.Filter;
 
 import java.io.IOException;
-import java.util.BitSet;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.util.OpenBitSet;
+import org.apache.lucene.util.OpenBitSetDISI;
+import org.apache.lucene.util.SortedVIntList;
 
 /**
  * <p>
@@ -79,29 +83,13 @@
  */
 public class ChainedFilter extends Filter
 {
-    /**
-     * {@link BitSet#or}.
-     */
     public static final int OR = 0;
-
-    /**
-     * {@link BitSet#and}.
-     */
     public static final int AND = 1;
-
-    /**
-     * {@link BitSet#andNot}.
-     */
     public static final int ANDNOT = 2;
-
-    /**
-     * {@link BitSet#xor}.
-     */
     public static final int XOR = 3;
-
     /**
      * Logical operation when none is declared. Defaults to
-     * {@link BitSet#or}.
+     * OR.
      */
     public static int DEFAULT = OR;
 
@@ -144,96 +132,95 @@
     }
 
     /**
-     * {@link Filter#bits}.
+     * {@link Filter#getDocIdSet}.
      */
-    public BitSet bits(IndexReader reader) throws IOException
+    public DocIdSet getDocIdSet(IndexReader reader) throws IOException
     {
+        int[] index = new int[1]; // use array as reference to modifiable int; 
+        index[0] = 0;             // an object attribute would not be thread safe.
         if (logic != -1)
-            return bits(reader, logic);
+            return getDocIdSet(reader, logic, index);
         else if (logicArray != null)
-            return bits(reader, logicArray);
+            return getDocIdSet(reader, logicArray, index);
         else
-            return bits(reader, DEFAULT);
+            return getDocIdSet(reader, DEFAULT, index);
     }
 
-    /**
-     * Delegates to each filter in the chain.
-     * @param reader IndexReader
-     * @param logic Logical operation
-     * @return BitSet
-     */
-    private BitSet bits(IndexReader reader, int logic) throws IOException
+    private DocIdSetIterator getDISI(Filter filter, IndexReader reader)
+    throws IOException
     {
-        BitSet result;
-        int i = 0;
+        return filter.getDocIdSet(reader).iterator();
+    }
 
+    private OpenBitSetDISI initialResult(IndexReader reader, int logic, int[] index)
+    throws IOException
+    {
+        OpenBitSetDISI result;
         /**
          * First AND operation takes place against a completely false
-         * bitset and will always return zero results. Thanks to
-         * Daniel Armbrust for pointing this out and suggesting workaround.
+         * bitset and will always return zero results.
          */
         if (logic == AND)
         {
-            result = (BitSet) chain[i].bits(reader).clone();
-            ++i;
+            result = new OpenBitSetDISI(getDISI(chain[index[0]], reader), reader.maxDoc());
+            ++index[0];
         }
         else if (logic == ANDNOT)
         {
-            result = (BitSet) chain[i].bits(reader).clone();
-            result.flip(0,reader.maxDoc());
-            ++i;
+            result = new OpenBitSetDISI(getDISI(chain[index[0]], reader), reader.maxDoc());
+            result.flip(0,reader.maxDoc()); // NOTE: may set bits for deleted docs.
+            ++index[0];
         }
         else
         {
-            result = new BitSet(reader.maxDoc());
+            result = new OpenBitSetDISI(reader.maxDoc());
         }
+        return result;
+    }
+    
+    /** Provide a SortedVIntList when it is definitely smaller than an OpenBitSet */
+    protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
+        return (result.cardinality() < (maxDocs / 9))
+              ? (DocIdSet) new SortedVIntList(result)
+              : (DocIdSet) result;
+    }
+        
 
-        for (; i < chain.length; i++)
+    /**
+     * Delegates to each filter in the chain.
+     * @param reader IndexReader
+     * @param logic Logical operation
+     * @return DocIdSet
+     */
+    private DocIdSet getDocIdSet(IndexReader reader, int logic, int[] index)
+    throws IOException
+    {
+        OpenBitSetDISI result = initialResult(reader, logic, index);
+        for (; index[0] < chain.length; index[0]++)
         {
-            doChain(result, reader, logic, chain[i]);
+            doChain(result, logic, chain[index[0]].getDocIdSet(reader));
         }
-        return result;
+        return finalResult(result, reader.maxDoc());
     }
 
     /**
      * Delegates to each filter in the chain.
      * @param reader IndexReader
      * @param logic Logical operation
-     * @return BitSet
+     * @return DocIdSet
      */
-    private BitSet bits(IndexReader reader, int[] logic) throws IOException
+    private DocIdSet getDocIdSet(IndexReader reader, int[] logic, int[] index)
+    throws IOException
     {
         if (logic.length != chain.length)
             throw new IllegalArgumentException("Invalid number of elements in logic array");
-        BitSet result;
-        int i = 0;
-
-        /**
-         * First AND operation takes place against a completely false
-         * bitset and will always return zero results. Thanks to
-         * Daniel Armbrust for pointing this out and suggesting workaround.
-         */
-        if (logic[0] == AND)
-        {
-            result = (BitSet) chain[i].bits(reader).clone();
-            ++i;
-        }
-        else if (logic[0] == ANDNOT)
-        {
-            result = (BitSet) chain[i].bits(reader).clone();
-            result.flip(0,reader.maxDoc());
-            ++i;
-        }
-        else
-        {
-            result = new BitSet(reader.maxDoc());
-        }
 
-        for (; i < chain.length; i++)
+        OpenBitSetDISI result = initialResult(reader, logic[0], index);
+        for (; index[0] < chain.length; index[0]++)
         {
-            doChain(result, reader, logic[i], chain[i]);
+            doChain(result, logic[index[0]], chain[index[0]].getDocIdSet(reader));
         }
-        return result;
+        return finalResult(result, reader.maxDoc());
     }
 
     public String toString()
@@ -249,26 +236,51 @@
         return sb.toString();
     }
 
-    private void doChain(BitSet result, IndexReader reader,
-                         int logic, Filter filter) throws IOException
+    private void doChain(OpenBitSetDISI result, int logic, DocIdSet dis)
+    throws IOException
     {
+      
+      if (dis instanceof OpenBitSet) {
+        // optimized case for OpenBitSets
         switch (logic)
         {
             case OR:
-                result.or(filter.bits(reader));
+                result.or((OpenBitSet) dis);
                 break;
             case AND:
-                result.and(filter.bits(reader));
+                result.and((OpenBitSet) dis);
                 break;
             case ANDNOT:
-                result.andNot(filter.bits(reader));
+                result.andNot((OpenBitSet) dis);
                 break;
             case XOR:
-                result.xor(filter.bits(reader));
+                result.xor((OpenBitSet) dis);
                 break;
             default:
-                doChain(result, reader, DEFAULT, filter);
+                doChain(result, DEFAULT, dis);
                 break;
         }
+      } else {
+        DocIdSetIterator disi = dis.iterator();      
+        switch (logic)
+        {
+            case OR:
+                result.inPlaceOr(disi);
+                break;
+            case AND:
+                result.inPlaceAnd(disi);
+                break;
+            case ANDNOT:
+                result.inPlaceNot(disi);
+                break;
+            case XOR:
+                result.inPlaceXor(disi);
+                break;
+            default:
+                doChain(result, DEFAULT, dis);
+                break;
+        }
+      }
     }
+
 }

Modified: lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java (original)
+++ lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java Fri May 23 12:25:05 2008
@@ -19,11 +19,17 @@
 
 import junit.framework.TestCase;
 import java.util.*;
+import java.io.IOException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.index.IndexWriter.MaxFieldLength;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.NoLockFactory;
 import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.WhitespaceAnalyzer;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -80,76 +86,149 @@
         new TermQuery(new Term("owner", "sue")));
   }
 
-  public void testSingleFilter() throws Exception {
-    ChainedFilter chain = new ChainedFilter(
-        new Filter[] {dateFilter});
-
-    Hits hits = searcher.search(query, chain);
-    assertEquals(MAX, hits.length());
-
-    chain = new ChainedFilter(new Filter[] {bobFilter});
-    hits = searcher.search(query, chain);
-    assertEquals(MAX / 2, hits.length());
+  private Filter[] getChainWithOldFilters(Filter[] chain) {
+    Filter[] oldFilters = new Filter[chain.length];
+    for (int i = 0; i < chain.length; i++) {
+      oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
+    }
+    return oldFilters;
+  }
+  
+  private ChainedFilter getChainedFilter(Filter[] chain, int[] logic, boolean old) {
+    if (old) {
+      chain = getChainWithOldFilters(chain);
+    }
     
-    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.AND});
-    hits = searcher.search(query, chain);
-    assertEquals(MAX / 2, hits.length());
-    assertEquals("bob", hits.doc(0).get("owner"));
+    if (logic == null) {
+      return new ChainedFilter(chain);
+    } else {
+      return new ChainedFilter(chain, logic);
+    }
+  }
+
+  private ChainedFilter getChainedFilter(Filter[] chain, int logic, boolean old) {
+    if (old) {
+      chain = getChainWithOldFilters(chain);
+    }
     
-    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.ANDNOT});
-    hits = searcher.search(query, chain);
-    assertEquals(MAX / 2, hits.length());
-    assertEquals("sue", hits.doc(0).get("owner"));
+    return new ChainedFilter(chain, logic);
   }
 
-  public void testOR() throws Exception {
-    ChainedFilter chain = new ChainedFilter(
-      new Filter[] {sueFilter, bobFilter});
+  
+  public void testSingleFilter() throws Exception {
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      
+      ChainedFilter chain = getChainedFilter(new Filter[] {dateFilter}, null, old);
+  
+      Hits hits = searcher.search(query, chain);
+      assertEquals(MAX, hits.length());
+  
+      chain = new ChainedFilter(new Filter[] {bobFilter});
+      hits = searcher.search(query, chain);
+      assertEquals(MAX / 2, hits.length());
+      
+      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.AND}, old);
+      hits = searcher.search(query, chain);
+      assertEquals(MAX / 2, hits.length());
+      assertEquals("bob", hits.doc(0).get("owner"));
+      
+      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] {ChainedFilter.ANDNOT}, old);
+      hits = searcher.search(query, chain);
+      assertEquals(MAX / 2, hits.length());
+      assertEquals("sue", hits.doc(0).get("owner"));
+    }
+  }
 
-    Hits hits = searcher.search(query, chain);
-    assertEquals("OR matches all", MAX, hits.length());
+  public void testOR() throws Exception {
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      ChainedFilter chain = getChainedFilter(
+        new Filter[] {sueFilter, bobFilter}, null, old);
+  
+      Hits hits = searcher.search(query, chain);
+      assertEquals("OR matches all", MAX, hits.length());
+    }
   }
 
   public void testAND() throws Exception {
-    ChainedFilter chain = new ChainedFilter(
-      new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND);
-
-    Hits hits = searcher.search(query, chain);
-    assertEquals("AND matches just bob", MAX / 2, hits.length());
-    assertEquals("bob", hits.doc(0).get("owner"));
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      ChainedFilter chain = getChainedFilter(
+        new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND, old);
+  
+      Hits hits = searcher.search(query, chain);
+      assertEquals("AND matches just bob", MAX / 2, hits.length());
+      assertEquals("bob", hits.doc(0).get("owner"));
+    }
   }
 
   public void testXOR() throws Exception {
-    ChainedFilter chain = new ChainedFilter(
-      new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR);
-
-    Hits hits = searcher.search(query, chain);
-    assertEquals("XOR matches sue", MAX / 2, hits.length());
-    assertEquals("sue", hits.doc(0).get("owner"));
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      ChainedFilter chain = getChainedFilter(
+        new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR, old);
+  
+      Hits hits = searcher.search(query, chain);
+      assertEquals("XOR matches sue", MAX / 2, hits.length());
+      assertEquals("sue", hits.doc(0).get("owner"));
+    }
   }
 
   public void testANDNOT() throws Exception {
-    ChainedFilter chain = new ChainedFilter(
-      new Filter[]{dateFilter, sueFilter},
-        new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT});
-
-    Hits hits = searcher.search(query, chain);
-    assertEquals("ANDNOT matches just bob",
-        MAX / 2, hits.length());
-    assertEquals("bob", hits.doc(0).get("owner"));
-    
-    chain = new ChainedFilter(
-        new Filter[]{bobFilter, bobFilter},
-          new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT});
-
-      hits = searcher.search(query, chain);
-      assertEquals("ANDNOT bob ANDNOT bob matches all sues",
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      ChainedFilter chain = getChainedFilter(
+        new Filter[]{dateFilter, sueFilter},
+          new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT}, old);
+  
+      Hits hits = searcher.search(query, chain);
+      assertEquals("ANDNOT matches just bob",
           MAX / 2, hits.length());
-      assertEquals("sue", hits.doc(0).get("owner"));
+      assertEquals("bob", hits.doc(0).get("owner"));
+      
+      chain = getChainedFilter(
+          new Filter[]{bobFilter, bobFilter},
+            new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT}, old);
+  
+        hits = searcher.search(query, chain);
+        assertEquals("ANDNOT bob ANDNOT bob matches all sues",
+            MAX / 2, hits.length());
+        assertEquals("sue", hits.doc(0).get("owner"));
+    }
   }
 
   private Date parseDate(String s) throws ParseException {
     return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
   }
+  
+  public void testWithCachingFilter() throws Exception {
+    for (int mode = 0; mode < 2; mode++) {
+      boolean old = (mode==0);
+      Directory dir = new RAMDirectory();
+      Analyzer analyzer = new WhitespaceAnalyzer();
+  
+      IndexWriter writer = new IndexWriter(dir, analyzer, true, MaxFieldLength.LIMITED);
+      writer.close();
+  
+      Searcher searcher = new IndexSearcher(dir);
+  
+      Query query = new TermQuery(new Term("none", "none"));
+  
+      QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
+      CachingWrapperFilter cachingFilter = new CachingWrapperFilter(queryFilter);
+  
+      searcher.search(query, cachingFilter, 1);
+  
+      CachingWrapperFilter cachingFilter2 = new CachingWrapperFilter(queryFilter);
+      Filter[] chain = new Filter[2];
+      chain[0] = cachingFilter;
+      chain[1] = cachingFilter2;
+      ChainedFilter cf = new ChainedFilter(chain);
+  
+      // throws java.lang.ClassCastException: org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
+      searcher.search(new MatchAllDocsQuery(), cf, 1);
+    }
+  }
 
 }

Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java (original)
+++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java Fri May 23 12:25:05 2008
@@ -23,6 +23,10 @@
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.util.DocIdBitSet;
+import org.apache.lucene.util.OpenBitSet;
+import org.apache.lucene.util.OpenBitSetDISI;
+import org.apache.lucene.util.SortedVIntList;
 
 /**
  * A container Filter that allows Boolean composition of Filters.
@@ -37,184 +41,167 @@
 
 public class BooleanFilter extends Filter
 {
-	//ArrayList of SHOULD filters
-	ArrayList shouldFilters = null;
-	//ArrayList of NOT filters
-	ArrayList notFilters = null;
-	//ArrayList of MUST filters
-	ArrayList mustFilters = null;
-
-	/**
-	 * Returns the a BitSet representing the Boolean composition
-	 * of the filters that have been added.
-	 */
-	
-	public BitSet bits(IndexReader reader) throws IOException
-	{
-		//create a new bitSet
-		BitSet returnBits = null;
-		
-		//SHOULD filters
-		if (shouldFilters!=null)
-		{
-			returnBits = ((Filter)shouldFilters.get(0)).bits(reader);
-//			avoid changing the original bitset - it may be cached
-			returnBits=(BitSet) returnBits.clone(); 
-			if (shouldFilters.size() > 1)
-			{
-				for (int i = 1; i < shouldFilters.size(); i++)
-				{
-					returnBits.or(((Filter)shouldFilters.get(i)).bits(reader));
-				}
-			}
-		}
-		
-		//NOT filters
-		if (notFilters!=null)
-		{
-			for (int i = 0; i < notFilters.size(); i++)
-			{
-				BitSet notBits=((Filter)notFilters.get(i)).bits(reader);
-				if(returnBits==null)
-				{
-					returnBits=(BitSet) notBits.clone();					
-					returnBits.flip(0,reader.maxDoc());
-				}
-				else
-				{
-					returnBits.andNot(notBits);
-				}
-			}
-		}
-		
-		//MUST filters
-		if (mustFilters!=null)
-		{
-			for (int i = 0; i < mustFilters.size(); i++)
-			{
-				BitSet mustBits=((Filter)mustFilters.get(i)).bits(reader);
-				if(returnBits==null)
-				{
-					if(mustFilters.size()==1)
-					{
-						returnBits=mustBits;
-						
-					}
-					else
-					{
-						//don't mangle the bitset
-						returnBits=(BitSet) mustBits.clone();						
-					}
-				}
-				else
-				{
-					returnBits.and(mustBits);
-				}
-			}
-		}
-		if(returnBits==null)
-		{
-			returnBits=new BitSet(reader.maxDoc());
-		}
-		return returnBits;
-	}
-	
-	/**
-	 * Adds a new FilterClause to the Boolean Filter container
-	 * @param filterClause A FilterClause object containing a Filter and an Occur parameter
-	 */
-	
-	public void add(FilterClause filterClause)
-	{
-		if (filterClause.getOccur().equals(Occur.MUST))
-		{
-			if(mustFilters==null)
-			{
-				mustFilters=new ArrayList();
-			}
-			mustFilters.add(filterClause.getFilter());
-		}
-		if (filterClause.getOccur().equals(Occur.SHOULD))
-		{
-			if(shouldFilters==null)
-			{
-				shouldFilters=new ArrayList();
-			}
-			shouldFilters.add(filterClause.getFilter());
-		}
-		if (filterClause.getOccur().equals(Occur.MUST_NOT))
-		{
-			if(notFilters==null)
-			{
-				notFilters=new ArrayList();
-			}
-			notFilters.add(filterClause.getFilter());
-		}
-	}
-
-	public boolean equals(Object obj)
-	{
-		if(this == obj)
-			return true;
-		if((obj == null) || (obj.getClass() != this.getClass()))
-				return false;
-		BooleanFilter test = (BooleanFilter)obj;
-		return (notFilters == test.notFilters|| 
-					 (notFilters!= null && notFilters.equals(test.notFilters)))
-				&&
-			   (mustFilters == test.mustFilters|| 
-					 (mustFilters!= null && mustFilters.equals(test.mustFilters)))				 
-					 &&
-			   (shouldFilters == test.shouldFilters|| 
-					 (shouldFilters!= null && shouldFilters.equals(test.shouldFilters)));
-	}
-
-	public int hashCode()
-	{
-		int hash=7;
-		hash = 31 * hash + (null == mustFilters ? 0 : mustFilters.hashCode());
-		hash = 31 * hash + (null == notFilters ? 0 : notFilters.hashCode());
-		hash = 31 * hash + (null == shouldFilters ? 0 : shouldFilters.hashCode());
-		return hash;
-	}
-	
-	
-		/** Prints a user-readable version of this query. */
-	public String toString()
-	{
-		StringBuffer buffer = new StringBuffer();
-
-		buffer.append("BooleanFilter(");
-
-		appendFilters(shouldFilters, null, buffer);
-		appendFilters(mustFilters, "+", buffer);
-		appendFilters(notFilters, "-", buffer);
-
-		buffer.append(")");
-
-		return buffer.toString();
-	}
-	
-	private void appendFilters(ArrayList filters, String occurString,
-			StringBuffer buffer)
-	{
-		if (filters == null)
-			return;
-
-		for (int i = 0; i < filters.size(); i++)
-		{
-			Filter filter = (Filter) filters.get(i);
-			if (occurString != null)
-			{
-				buffer.append(occurString);
-			}
-
-			buffer.append(filter);
-
-			if (i < filters.size() - 1)
-			{
-				buffer.append(' ');
-			}
-		}
-	}		
+  ArrayList shouldFilters = null;
+  ArrayList notFilters = null;
+  ArrayList mustFilters = null;
+  
+  private DocIdSetIterator getDISI(ArrayList filters, int index, IndexReader reader)
+  throws IOException
+  {
+    return ((Filter)filters.get(index)).getDocIdSet(reader).iterator();
+  }
+
+  /**
+   * Returns the a DocIdSetIterator representing the Boolean composition
+   * of the filters that have been added.
+   */
+  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
+  {
+    OpenBitSetDISI res = null;
+  
+    if (shouldFilters != null) {
+      for (int i = 0; i < shouldFilters.size(); i++) {
+        if (res == null) {
+          res = new OpenBitSetDISI(getDISI(shouldFilters, i, reader), reader.maxDoc());
+        } else { 
+          DocIdSet dis = ((Filter)shouldFilters.get(i)).getDocIdSet(reader);
+          if(dis instanceof OpenBitSet) {
+            // optimized case for OpenBitSets
+            res.or((OpenBitSet) dis);
+          } else {
+            res.inPlaceOr(getDISI(shouldFilters, i, reader));
+          }
+        }
+      }
+    }
+    
+    if (notFilters!=null) {
+      for (int i = 0; i < notFilters.size(); i++) {
+        if (res == null) {
+          res = new OpenBitSetDISI(getDISI(notFilters, i, reader), reader.maxDoc());
+          res.flip(0, reader.maxDoc()); // NOTE: may set bits on deleted docs
+        } else {
+          DocIdSet dis = ((Filter)notFilters.get(i)).getDocIdSet(reader);
+          if(dis instanceof OpenBitSet) {
+            // optimized case for OpenBitSets
+            res.andNot((OpenBitSet) dis);
+          } else {
+            res.inPlaceNot(getDISI(notFilters, i, reader));
+          }
+        }
+      }
+    }
+    
+    if (mustFilters!=null) {
+      for (int i = 0; i < mustFilters.size(); i++) {
+        if (res == null) {
+          res = new OpenBitSetDISI(getDISI(mustFilters, i, reader), reader.maxDoc());
+        } else {
+          DocIdSet dis = ((Filter)mustFilters.get(i)).getDocIdSet(reader);
+          if(dis instanceof OpenBitSet) {
+            // optimized case for OpenBitSets
+            res.and((OpenBitSet) dis);
+          } else {
+            res.inPlaceAnd(getDISI(mustFilters, i, reader));
+          }
+        }
+      }
+    }
+    
+    if (res !=null)
+      return finalResult(res, reader.maxDoc());
+
+    if (emptyDocIdSet == null)
+      emptyDocIdSet = new OpenBitSetDISI(1);
+
+    return emptyDocIdSet;
+  }
+
+  /** Provide a SortedVIntList when it is definitely smaller than an OpenBitSet */
+  protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
+    return (result.cardinality() < (maxDocs / 9))
+      ? (DocIdSet) new SortedVIntList(result)
+      : (DocIdSet) result;
+  }
+
+  private static DocIdSet emptyDocIdSet = null;
+
+  /**
+  * Adds a new FilterClause to the Boolean Filter container
+  * @param filterClause A FilterClause object containing a Filter and an Occur parameter
+  */
+  
+  public void add(FilterClause filterClause)
+  {
+    if (filterClause.getOccur().equals(Occur.MUST)) {
+      if (mustFilters==null) {
+        mustFilters=new ArrayList();
+      }
+      mustFilters.add(filterClause.getFilter());
+    }
+    if (filterClause.getOccur().equals(Occur.SHOULD)) {
+      if (shouldFilters==null) {
+        shouldFilters=new ArrayList();
+      }
+      shouldFilters.add(filterClause.getFilter());
+    }
+    if (filterClause.getOccur().equals(Occur.MUST_NOT)) {
+      if (notFilters==null) {
+        notFilters=new ArrayList();
+      }
+      notFilters.add(filterClause.getFilter());
+    }
+  }
+
+  private boolean equalFilters(ArrayList filters1, ArrayList filters2)
+  {
+     return (filters1 == filters2) ||
+              ((filters1 != null) && filters1.equals(filters2));
+  }
+  
+  public boolean equals(Object obj)
+  {
+    if (this == obj)
+      return true;
+
+    if ((obj == null) || (obj.getClass() != this.getClass()))
+      return false;
+
+    BooleanFilter other = (BooleanFilter)obj;
+    return equalFilters(notFilters, other.notFilters)
+        && equalFilters(mustFilters, other.mustFilters)
+        && equalFilters(shouldFilters, other.shouldFilters);
+  }
+
+  public int hashCode()
+  {
+    int hash=7;
+    hash = 31 * hash + (null == mustFilters ? 0 : mustFilters.hashCode());
+    hash = 31 * hash + (null == notFilters ? 0 : notFilters.hashCode());
+    hash = 31 * hash + (null == shouldFilters ? 0 : shouldFilters.hashCode());
+    return hash;
+  }
+  
+  /** Prints a user-readable version of this query. */
+  public String toString()
+  {
+    StringBuffer buffer = new StringBuffer();
+    buffer.append("BooleanFilter(");
+    appendFilters(shouldFilters, "", buffer);
+    appendFilters(mustFilters, "+", buffer);
+    appendFilters(notFilters, "-", buffer);
+    buffer.append(")");
+    return buffer.toString();
+  }
+  
+  private void appendFilters(ArrayList filters, String occurString, StringBuffer buffer)
+  {
+    if (filters != null) {
+      for (int i = 0; i < filters.size(); i++) {
+        buffer.append(' ');
+        buffer.append(occurString);
+        buffer.append(filters.get(i).toString());
+      }
+    }
+  }    
 }

Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java (original)
+++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java Fri May 23 12:25:05 2008
@@ -22,6 +22,7 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermDocs;
 import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.util.OpenBitSet;
 
 public class DuplicateFilter extends Filter
 {
@@ -66,7 +67,7 @@
 		this.processingMode = processingMode;
 	}
 
-	public BitSet bits(IndexReader reader) throws IOException
+  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
 	{
 		if(processingMode==PM_FAST_INVALIDATION)
 		{
@@ -78,10 +79,10 @@
 		}
 	}
 	
-	private BitSet correctBits(IndexReader reader) throws IOException
+  private OpenBitSet correctBits(IndexReader reader) throws IOException
 	{
 		
-		BitSet bits=new BitSet(reader.maxDoc()); //assume all are INvalid
+    OpenBitSet bits=new OpenBitSet(reader.maxDoc()); //assume all are INvalid
 		Term startTerm=new Term(fieldName,"");
 		TermEnum te = reader.terms(startTerm);
 		if(te!=null)
@@ -117,10 +118,10 @@
 		return bits;
 	}
 	
-	private BitSet fastBits(IndexReader reader) throws IOException
+  private OpenBitSet fastBits(IndexReader reader) throws IOException
 	{
 		
-		BitSet bits=new BitSet(reader.maxDoc());
+    OpenBitSet bits=new OpenBitSet(reader.maxDoc());
 		bits.set(0,reader.maxDoc()); //assume all are valid
 		Term startTerm=new Term(fieldName,"");
 		TermEnum te = reader.terms(startTerm);
@@ -143,7 +144,7 @@
 					do
 					{
 						lastDoc=td.doc();
-						bits.set(lastDoc,false);
+            bits.clear(lastDoc);
 					}while(td.next());
 					if(keepMode==KM_USE_LAST_OCCURRENCE)
 					{

Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java (original)
+++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java Fri May 23 12:25:05 2008
@@ -26,6 +26,7 @@
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.util.OpenBitSet;
 
 /**
  * Constructs a filter for docs matching any of the terms added to this class. 
@@ -50,11 +51,11 @@
 	}
 
 	/* (non-Javadoc)
-	 * @see org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader)
+   * @see org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader)
 	 */
-	public BitSet bits(IndexReader reader) throws IOException
+  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
 	{
-		BitSet result=new BitSet(reader.maxDoc());
+    OpenBitSet result=new OpenBitSet(reader.maxDoc());
         TermDocs td = reader.termDocs();
         try
         {

Modified: lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java (original)
+++ lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java Fri May 23 12:25:05 2008
@@ -32,6 +32,7 @@
 import org.apache.lucene.search.FilterClause;
 import org.apache.lucene.search.RangeFilter;
 import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.DocIdBitSet;
 
 import junit.framework.TestCase;
 
@@ -66,100 +67,141 @@
 		writer.addDocument(doc);
 	}
 	
-	private Filter getRangeFilter(String field,String lowerPrice, String upperPrice)
+  private Filter getRangeFilter(String field,String lowerPrice, String upperPrice, boolean old)
 	{
-		return new RangeFilter(field,lowerPrice,upperPrice,true,true);
+    Filter f = new RangeFilter(field,lowerPrice,upperPrice,true,true);
+    if (old) {
+      return new OldBitSetFilterWrapper(f);
+    }
+    
+    return f;
 	}
-	private TermsFilter getTermsFilter(String field,String text)
+  private Filter getTermsFilter(String field,String text, boolean old)
 	{
 		TermsFilter tf=new TermsFilter();
 		tf.addTerm(new Term(field,text));
+    if (old) {
+      return new OldBitSetFilterWrapper(tf);
+    }
+    
 		return tf;
 	}
+        
+        private void tstFilterCard(String mes, int expected, Filter filt)
+        throws Throwable
+        {
+          DocIdSetIterator disi = filt.getDocIdSet(reader).iterator();
+          int actual = 0;
+          while (disi.next()) {
+            actual++;
+          }
+          assertEquals(mes, expected, actual);
+        }
+          
 		
 	public void testShould() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.SHOULD));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Should retrieves only 1 doc",1,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getTermsFilter("price","030", old),BooleanClause.Occur.SHOULD));
+      tstFilterCard("Should retrieves only 1 doc",1,booleanFilter);
+    }
 	}
 	
 	public void testShoulds() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030"),BooleanClause.Occur.SHOULD));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds are Ored together",5,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030", old),BooleanClause.Occur.SHOULD));
+      tstFilterCard("Shoulds are Ored together",5,booleanFilter);
+    }
 	}
 	public void testShouldsAndMustNot() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getTermsFilter("inStock", "N"),BooleanClause.Occur.MUST_NOT));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds Ored but AndNot",4,bits.cardinality());
-
-		booleanFilter.add(new FilterClause(getTermsFilter("inStock", "Maybe"),BooleanClause.Occur.MUST_NOT));
-		bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds Ored but AndNots",3,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getTermsFilter("inStock", "N", old),BooleanClause.Occur.MUST_NOT));
+      tstFilterCard("Shoulds Ored but AndNot",4,booleanFilter);
+  
+      booleanFilter.add(new FilterClause(getTermsFilter("inStock", "Maybe", old),BooleanClause.Occur.MUST_NOT));
+      tstFilterCard("Shoulds Ored but AndNots",3,booleanFilter);
+    }
 		
 	}
 	public void testShouldsAndMust() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin"),BooleanClause.Occur.MUST));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds Ored but MUST",3,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin", old),BooleanClause.Occur.MUST));
+      tstFilterCard("Shoulds Ored but MUST",3,booleanFilter);
+    }
 	}
 	public void testShouldsAndMusts() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin"),BooleanClause.Occur.MUST));
-		booleanFilter.add(new FilterClause(getRangeFilter("date","20040101", "20041231"),BooleanClause.Occur.MUST));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds Ored but MUSTs ANDED",1,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getRangeFilter("price","010", "020", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getRangeFilter("price","020", "030", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin", old),BooleanClause.Occur.MUST));
+      booleanFilter.add(new FilterClause(getRangeFilter("date","20040101", "20041231", old),BooleanClause.Occur.MUST));
+      tstFilterCard("Shoulds Ored but MUSTs ANDED",1,booleanFilter);
+    }
 	}
 	public void testShouldsAndMustsAndMustNot() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getRangeFilter("price","030", "040"),BooleanClause.Occur.SHOULD));
-		booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin"),BooleanClause.Occur.MUST));
-		booleanFilter.add(new FilterClause(getRangeFilter("date","20050101", "20051231"),BooleanClause.Occur.MUST));
-		booleanFilter.add(new FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("Shoulds Ored but MUSTs ANDED and MustNot",0,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getRangeFilter("price","030", "040", old),BooleanClause.Occur.SHOULD));
+      booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin", old),BooleanClause.Occur.MUST));
+      booleanFilter.add(new FilterClause(getRangeFilter("date","20050101", "20051231", old),BooleanClause.Occur.MUST));
+      booleanFilter.add(new FilterClause(getTermsFilter("inStock","N", old),BooleanClause.Occur.MUST_NOT));
+      tstFilterCard("Shoulds Ored but MUSTs ANDED and MustNot",0,booleanFilter);
+    }
 	}
 	
 	public void testJustMust() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin"),BooleanClause.Occur.MUST));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("MUST",3,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getTermsFilter("accessRights", "admin", old),BooleanClause.Occur.MUST));
+      tstFilterCard("MUST",3,booleanFilter);
+    }
 	}
 	public void testJustMustNot() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("MUST_NOT",4,bits.cardinality());
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
+
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getTermsFilter("inStock","N", old),BooleanClause.Occur.MUST_NOT));
+      tstFilterCard("MUST_NOT",4,booleanFilter);
+    }
 	}
 	public void testMustAndMustNot() throws Throwable
 	{
-		BooleanFilter booleanFilter = new BooleanFilter();
-		booleanFilter.add(new FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST));
-		booleanFilter.add(new FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.MUST_NOT));
-		BitSet bits = booleanFilter.bits(reader);
-		assertEquals("MUST_NOT wins over MUST for same docs",0,bits.cardinality());
-	}
+    for (int i = 0; i < 2; i++) {
+      boolean old = (i==0);
 
-	
-	
+      BooleanFilter booleanFilter = new BooleanFilter();
+      booleanFilter.add(new FilterClause(getTermsFilter("inStock","N", old),BooleanClause.Occur.MUST));
+      booleanFilter.add(new FilterClause(getTermsFilter("price","030", old),BooleanClause.Occur.MUST_NOT));
+      tstFilterCard("MUST_NOT wins over MUST for same docs",0,booleanFilter);
+    }
+	}
 }

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java Fri May 23 12:25:05 2008
@@ -150,8 +150,8 @@
 
   /** Lower-level search API.
    *
-   * <p>{@link HitCollector#collect(int,float)} is called for every non-zero
-   * scoring document.
+   * <p>{@link HitCollector#collect(int,float)} is called for every matching
+   * document.
    *
    * <p>Applications should only use this if they need <i>all</i> of the
    * matching documents.  The high-level search API ({@link

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java Fri May 23 12:25:05 2008
@@ -33,7 +33,7 @@
  *
  * <p>Queries, filters and sort criteria are designed to be compact so that
  * they may be efficiently passed to a remote index, with only the top-scoring
- * hits being returned, rather than every non-zero scoring hit.
+ * hits being returned, rather than every matching hit.
  */
 public interface Searchable extends java.rmi.Remote {
   /** Lower-level search API.

Modified: lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java?rev=659635&r1=659634&r2=659635&view=diff
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java (original)
+++ lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java Fri May 23 12:25:05 2008
@@ -88,8 +88,8 @@
 
   /** Lower-level search API.
    *
-   * <p>{@link HitCollector#collect(int,float)} is called for every non-zero
-   * scoring document.
+   * <p>{@link HitCollector#collect(int,float)} is called for every matching
+   * document.
    *
    * <p>Applications should only use this if they need <i>all</i> of the
    * matching documents.  The high-level search API ({@link
@@ -107,8 +107,8 @@
 
   /** Lower-level search API.
    *
-   * <p>{@link HitCollector#collect(int,float)} is called for every non-zero
-   * scoring document.
+   * <p>{@link HitCollector#collect(int,float)} is called for every matching
+   * document.
    * <br>HitCollector-based access to remote indexes is discouraged.
    *
    * <p>Applications should only use this if they need <i>all</i> of the

Added: lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java?rev=659635&view=auto
==============================================================================
--- lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java (added)
+++ lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java Fri May 23 12:25:05 2008
@@ -0,0 +1,101 @@
+package org.apache.lucene.util;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import org.apache.lucene.search.DocIdSetIterator;
+ 
+public class OpenBitSetDISI extends OpenBitSet {
+
+  /** Construct an OpenBitSetDISI with its bits set
+   * from the doc ids of the given DocIdSetIterator.
+   * Also give a maximum size one larger than the largest doc id for which a
+   * bit may ever be set on this OpenBitSetDISI.
+   */
+  public OpenBitSetDISI(DocIdSetIterator disi, int maxSize) throws IOException {
+    super(maxSize);
+    inPlaceOr(disi);
+  }
+
+  /** Construct an OpenBitSetDISI with no bits set, and a given maximum size
+   * one larger than the largest doc id for which a bit may ever be set
+   * on this OpenBitSetDISI.
+   */
+  public OpenBitSetDISI(int maxSize) {
+    super(maxSize);
+  }
+
+  /**
+   * Perform an inplace OR with the doc ids from a given DocIdSetIterator,
+   * setting the bit for each such doc id.
+   * These doc ids should be smaller than the maximum size passed to the
+   * constructor.
+   */   
+  public void inPlaceOr(DocIdSetIterator disi) throws IOException {
+    while (disi.next() && (disi.doc() < size())) {
+      fastSet(disi.doc());
+    }
+  }
+
+  /**
+   * Perform an inplace AND with the doc ids from a given DocIdSetIterator,
+   * leaving only the bits set for which the doc ids are in common.
+   * These doc ids should be smaller than the maximum size passed to the
+   * constructor.
+   */   
+  public void inPlaceAnd(DocIdSetIterator disi) throws IOException {
+    int index = nextSetBit(0);
+    int lastNotCleared = -1;
+    while ((index != -1) && disi.skipTo(index)) {
+      while ((index != -1) && (index < disi.doc())) {
+        fastClear(index);
+        index = nextSetBit(index + 1);
+      }
+      if (index == disi.doc()) {
+        lastNotCleared = index;
+        index++;
+      }
+      assert (index == -1) || (index > disi.doc());
+    }
+    clear(lastNotCleared+1, size());
+  }
+
+  /**
+   * Perform an inplace NOT with the doc ids from a given DocIdSetIterator,
+   * clearing all the bits for each such doc id.
+   * These doc ids should be smaller than the maximum size passed to the
+   * constructor.
+   */   
+  public void inPlaceNot(DocIdSetIterator disi) throws IOException {
+    while (disi.next() && (disi.doc() < size())) {
+      fastClear(disi.doc());
+    }
+  }
+
+  /**
+   * Perform an inplace XOR with the doc ids from a given DocIdSetIterator,
+   * flipping all the bits for each such doc id.
+   * These doc ids should be smaller than the maximum size passed to the
+   * constructor.
+   */   
+  public void inPlaceXor(DocIdSetIterator disi) throws IOException {
+    while (disi.next() && (disi.doc() < size())) {
+      fastFlip(disi.doc());
+    }
+  }
+}

Added: lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java?rev=659635&view=auto
==============================================================================
--- lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java (added)
+++ lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java Fri May 23 12:25:05 2008
@@ -0,0 +1,48 @@
+package org.apache.lucene.search;
+
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.util.BitSet;
+
+import org.apache.lucene.index.IndexReader;
+
+  /**
+   *  Helper class used for testing compatibility with old BitSet-based filters.
+   *  Does not override {@link Filter#getDocIdSet(IndexReader)} and thus ensures
+   *  that {@link #bits(IndexReader)} is called.
+   *  
+   *  @deprecated This class will be removed together with the 
+   *  {@link Filter#bits(IndexReader)} method in Lucene 3.0.
+   */
+  public class OldBitSetFilterWrapper extends Filter {
+    private Filter filter;
+    
+    public OldBitSetFilterWrapper(Filter filter) {
+      this.filter = filter;
+    }
+    
+    public BitSet bits(IndexReader reader) throws IOException {
+      BitSet bits = new BitSet(reader.maxDoc());
+      DocIdSetIterator it = filter.getDocIdSet(reader).iterator();
+      while(it.next()) {
+        bits.set(it.doc());
+      }
+      return bits;
+    }
+  }



Re: svn commit: r659635 - in /lucene/java/trunk: ./ contrib/miscellaneous/src/java/org/apache/lucene/misc/ contrib/miscellaneous/src/test/org/apache/lucene/misc/ contrib/queries/src/java/org/apache/lucene/search/ contrib/queries/src/test/org/apache/lucene/...

Posted by Michael Busch <bu...@gmail.com>.
Hmm, I'm looking at it now...

-Michael

Grant Ingersoll wrote:
> I'm getting:
> 
> common.compile-test:
>    [javac] Compiling 5 source files to 
> /lucene-clean/build/contrib/misc/classes/test
>    [javac] 
> .../lucene-clean/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java:92: 
> cannot find symbol
>    [javac] symbol  : class OldBitSetFilterWrapper
>    [javac] location: class org.apache.lucene.misc.ChainedFilterTest
>    [javac]       oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
>    [javac]                           ^
>    [javac] Note: Some input files use or override a deprecated API.
>    [javac] Note: Recompile with -Xlint:deprecation for details.
>    [javac] 1 error
> 
> 
> 
> When trying to run ant dist from the top.
> 
> svn info
> Path: .
> URL: 
> https://svn.apache.org/repos/asf/lucene/java/trunk/contrib/miscellaneous
> Repository Root: https://svn.apache.org/repos/asf
> Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
> Revision: 659700
> Node Kind: directory
> Schedule: normal
> Last Changed Author: buschmi
> Last Changed Rev: 659635
> Last Changed Date: 2008-05-23 15:25:05 -0400 (Fri, 23 May 2008)
> 
> 
> I'm up to date and I did a clean first.
> 
> 
> -Grant
> 
> On May 23, 2008, at 3:25 PM, buschmi@apache.org wrote:
> 
>> Author: buschmi
>> Date: Fri May 23 12:25:05 2008
>> New Revision: 659635
>>
>> URL: http://svn.apache.org/viewvc?rev=659635&view=rev
>> Log:
>> LUCENE-1187: ChainedFilter and BooleanFilter now work with new Filter 
>> API and DocIdSetIterator-based filters.
>>
>> Added:
>>   lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
>>   
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>>
>> Modified:
>>   lucene/java/trunk/CHANGES.txt
>>   
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>>
>>   
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>>
>>   lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
>>   lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
>>
>> Modified: lucene/java/trunk/CHANGES.txt
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- lucene/java/trunk/CHANGES.txt (original)
>> +++ lucene/java/trunk/CHANGES.txt Fri May 23 12:25:05 2008
>> @@ -163,6 +163,10 @@
>>
>> 13. LUCENE-1166: Decomposition tokenfilter for languages like German 
>> and Swedish (Thomas Peuss via Grant Ingersoll)
>>
>> +14. LUCENE-1187: ChainedFilter and BooleanFilter now work with new 
>> Filter API
>> +    and DocIdSetIterator-based filters. Backwards-compatibility with old
>> +    BitSet-based filters is ensured. (Paul Elschot via Michael Busch)
>> +
>> Optimizations
>>
>> 1. LUCENE-705: When building a compound file, use
>>
>> Modified: 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -58,7 +58,11 @@
>> import org.apache.lucene.search.Filter;
>>
>> import java.io.IOException;
>> -import java.util.BitSet;
>> +import org.apache.lucene.search.DocIdSet;
>> +import org.apache.lucene.search.DocIdSetIterator;
>> +import org.apache.lucene.util.OpenBitSet;
>> +import org.apache.lucene.util.OpenBitSetDISI;
>> +import org.apache.lucene.util.SortedVIntList;
>>
>> /**
>> * <p>
>> @@ -79,29 +83,13 @@
>> */
>> public class ChainedFilter extends Filter
>> {
>> -    /**
>> -     * {@link BitSet#or}.
>> -     */
>>    public static final int OR = 0;
>> -
>> -    /**
>> -     * {@link BitSet#and}.
>> -     */
>>    public static final int AND = 1;
>> -
>> -    /**
>> -     * {@link BitSet#andNot}.
>> -     */
>>    public static final int ANDNOT = 2;
>> -
>> -    /**
>> -     * {@link BitSet#xor}.
>> -     */
>>    public static final int XOR = 3;
>> -
>>    /**
>>     * Logical operation when none is declared. Defaults to
>> -     * {@link BitSet#or}.
>> +     * OR.
>>     */
>>    public static int DEFAULT = OR;
>>
>> @@ -144,96 +132,95 @@
>>    }
>>
>>    /**
>> -     * {@link Filter#bits}.
>> +     * {@link Filter#getDocIdSet}.
>>     */
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +    public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>    {
>> +        int[] index = new int[1]; // use array as reference to 
>> modifiable int;
>> +        index[0] = 0;             // an object attribute would not be 
>> thread safe.
>>        if (logic != -1)
>> -            return bits(reader, logic);
>> +            return getDocIdSet(reader, logic, index);
>>        else if (logicArray != null)
>> -            return bits(reader, logicArray);
>> +            return getDocIdSet(reader, logicArray, index);
>>        else
>> -            return bits(reader, DEFAULT);
>> +            return getDocIdSet(reader, DEFAULT, index);
>>    }
>>
>> -    /**
>> -     * Delegates to each filter in the chain.
>> -     * @param reader IndexReader
>> -     * @param logic Logical operation
>> -     * @return BitSet
>> -     */
>> -    private BitSet bits(IndexReader reader, int logic) throws 
>> IOException
>> +    private DocIdSetIterator getDISI(Filter filter, IndexReader reader)
>> +    throws IOException
>>    {
>> -        BitSet result;
>> -        int i = 0;
>> +        return filter.getDocIdSet(reader).iterator();
>> +    }
>>
>> +    private OpenBitSetDISI initialResult(IndexReader reader, int 
>> logic, int[] index)
>> +    throws IOException
>> +    {
>> +        OpenBitSetDISI result;
>>        /**
>>         * First AND operation takes place against a completely false
>> -         * bitset and will always return zero results. Thanks to
>> -         * Daniel Armbrust for pointing this out and suggesting 
>> workaround.
>> +         * bitset and will always return zero results.
>>         */
>>        if (logic == AND)
>>        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            ++i;
>> +            result = new OpenBitSetDISI(getDISI(chain[index[0]], 
>> reader), reader.maxDoc());
>> +            ++index[0];
>>        }
>>        else if (logic == ANDNOT)
>>        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            result.flip(0,reader.maxDoc());
>> -            ++i;
>> +            result = new OpenBitSetDISI(getDISI(chain[index[0]], 
>> reader), reader.maxDoc());
>> +            result.flip(0,reader.maxDoc()); // NOTE: may set bits for 
>> deleted docs.
>> +            ++index[0];
>>        }
>>        else
>>        {
>> -            result = new BitSet(reader.maxDoc());
>> +            result = new OpenBitSetDISI(reader.maxDoc());
>>        }
>> +        return result;
>> +    }
>> +
>> +    /** Provide a SortedVIntList when it is definitely smaller than 
>> an OpenBitSet */
>> +    protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
>> +        return (result.cardinality() < (maxDocs / 9))
>> +              ? (DocIdSet) new SortedVIntList(result)
>> +              : (DocIdSet) result;
>> +    }
>> +
>>
>> -        for (; i < chain.length; i++)
>> +    /**
>> +     * Delegates to each filter in the chain.
>> +     * @param reader IndexReader
>> +     * @param logic Logical operation
>> +     * @return DocIdSet
>> +     */
>> +    private DocIdSet getDocIdSet(IndexReader reader, int logic, int[] 
>> index)
>> +    throws IOException
>> +    {
>> +        OpenBitSetDISI result = initialResult(reader, logic, index);
>> +        for (; index[0] < chain.length; index[0]++)
>>        {
>> -            doChain(result, reader, logic, chain[i]);
>> +            doChain(result, logic, chain[index[0]].getDocIdSet(reader));
>>        }
>> -        return result;
>> +        return finalResult(result, reader.maxDoc());
>>    }
>>
>>    /**
>>     * Delegates to each filter in the chain.
>>     * @param reader IndexReader
>>     * @param logic Logical operation
>> -     * @return BitSet
>> +     * @return DocIdSet
>>     */
>> -    private BitSet bits(IndexReader reader, int[] logic) throws 
>> IOException
>> +    private DocIdSet getDocIdSet(IndexReader reader, int[] logic, 
>> int[] index)
>> +    throws IOException
>>    {
>>        if (logic.length != chain.length)
>>            throw new IllegalArgumentException("Invalid number of 
>> elements in logic array");
>> -        BitSet result;
>> -        int i = 0;
>> -
>> -        /**
>> -         * First AND operation takes place against a completely false
>> -         * bitset and will always return zero results. Thanks to
>> -         * Daniel Armbrust for pointing this out and suggesting 
>> workaround.
>> -         */
>> -        if (logic[0] == AND)
>> -        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            ++i;
>> -        }
>> -        else if (logic[0] == ANDNOT)
>> -        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            result.flip(0,reader.maxDoc());
>> -            ++i;
>> -        }
>> -        else
>> -        {
>> -            result = new BitSet(reader.maxDoc());
>> -        }
>>
>> -        for (; i < chain.length; i++)
>> +        OpenBitSetDISI result = initialResult(reader, logic[0], index);
>> +        for (; index[0] < chain.length; index[0]++)
>>        {
>> -            doChain(result, reader, logic[i], chain[i]);
>> +            doChain(result, logic[index[0]], 
>> chain[index[0]].getDocIdSet(reader));
>>        }
>> -        return result;
>> +        return finalResult(result, reader.maxDoc());
>>    }
>>
>>    public String toString()
>> @@ -249,26 +236,51 @@
>>        return sb.toString();
>>    }
>>
>> -    private void doChain(BitSet result, IndexReader reader,
>> -                         int logic, Filter filter) throws IOException
>> +    private void doChain(OpenBitSetDISI result, int logic, DocIdSet dis)
>> +    throws IOException
>>    {
>> +
>> +      if (dis instanceof OpenBitSet) {
>> +        // optimized case for OpenBitSets
>>        switch (logic)
>>        {
>>            case OR:
>> -                result.or(filter.bits(reader));
>> +                result.or((OpenBitSet) dis);
>>                break;
>>            case AND:
>> -                result.and(filter.bits(reader));
>> +                result.and((OpenBitSet) dis);
>>                break;
>>            case ANDNOT:
>> -                result.andNot(filter.bits(reader));
>> +                result.andNot((OpenBitSet) dis);
>>                break;
>>            case XOR:
>> -                result.xor(filter.bits(reader));
>> +                result.xor((OpenBitSet) dis);
>>                break;
>>            default:
>> -                doChain(result, reader, DEFAULT, filter);
>> +                doChain(result, DEFAULT, dis);
>>                break;
>>        }
>> +      } else {
>> +        DocIdSetIterator disi = dis.iterator();
>> +        switch (logic)
>> +        {
>> +            case OR:
>> +                result.inPlaceOr(disi);
>> +                break;
>> +            case AND:
>> +                result.inPlaceAnd(disi);
>> +                break;
>> +            case ANDNOT:
>> +                result.inPlaceNot(disi);
>> +                break;
>> +            case XOR:
>> +                result.inPlaceXor(disi);
>> +                break;
>> +            default:
>> +                doChain(result, DEFAULT, dis);
>> +                break;
>> +        }
>> +      }
>>    }
>> +
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>> Fri May 23 12:25:05 2008
>> @@ -19,11 +19,17 @@
>>
>> import junit.framework.TestCase;
>> import java.util.*;
>> +import java.io.IOException;
>> import java.text.ParseException;
>> import java.text.SimpleDateFormat;
>> import org.apache.lucene.index.IndexWriter;
>> import org.apache.lucene.index.Term;
>> +import org.apache.lucene.index.IndexWriter.MaxFieldLength;
>> +import org.apache.lucene.store.Directory;
>> +import org.apache.lucene.store.FSDirectory;
>> +import org.apache.lucene.store.NoLockFactory;
>> import org.apache.lucene.store.RAMDirectory;
>> +import org.apache.lucene.analysis.Analyzer;
>> import org.apache.lucene.analysis.WhitespaceAnalyzer;
>> import org.apache.lucene.document.Document;
>> import org.apache.lucene.document.Field;
>> @@ -80,76 +86,149 @@
>>        new TermQuery(new Term("owner", "sue")));
>>  }
>>
>> -  public void testSingleFilter() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -        new Filter[] {dateFilter});
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals(MAX, hits.length());
>> -
>> -    chain = new ChainedFilter(new Filter[] {bobFilter});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> +  private Filter[] getChainWithOldFilters(Filter[] chain) {
>> +    Filter[] oldFilters = new Filter[chain.length];
>> +    for (int i = 0; i < chain.length; i++) {
>> +      oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
>> +    }
>> +    return oldFilters;
>> +  }
>> +
>> +  private ChainedFilter getChainedFilter(Filter[] chain, int[] logic, 
>> boolean old) {
>> +    if (old) {
>> +      chain = getChainWithOldFilters(chain);
>> +    }
>>
>> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.AND});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> +    if (logic == null) {
>> +      return new ChainedFilter(chain);
>> +    } else {
>> +      return new ChainedFilter(chain, logic);
>> +    }
>> +  }
>> +
>> +  private ChainedFilter getChainedFilter(Filter[] chain, int logic, 
>> boolean old) {
>> +    if (old) {
>> +      chain = getChainWithOldFilters(chain);
>> +    }
>>
>> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.ANDNOT});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> -    assertEquals("sue", hits.doc(0).get("owner"));
>> +    return new ChainedFilter(chain, logic);
>>  }
>>
>> -  public void testOR() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[] {sueFilter, bobFilter});
>> +
>> +  public void testSingleFilter() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +
>> +      ChainedFilter chain = getChainedFilter(new Filter[] 
>> {dateFilter}, null, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals(MAX, hits.length());
>> +
>> +      chain = new ChainedFilter(new Filter[] {bobFilter});
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +
>> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.AND}, old);
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +
>> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.ANDNOT}, old);
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +      assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>> +  }
>>
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("OR matches all", MAX, hits.length());
>> +  public void testOR() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[] {sueFilter, bobFilter}, null, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("OR matches all", MAX, hits.length());
>> +    }
>>  }
>>
>>  public void testAND() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND);
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("AND matches just bob", MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("AND matches just bob", MAX / 2, hits.length());
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  public void testXOR() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR);
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("XOR matches sue", MAX / 2, hits.length());
>> -    assertEquals("sue", hits.doc(0).get("owner"));
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("XOR matches sue", MAX / 2, hits.length());
>> +      assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  public void testANDNOT() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[]{dateFilter, sueFilter},
>> -        new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT});
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("ANDNOT matches just bob",
>> -        MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> -
>> -    chain = new ChainedFilter(
>> -        new Filter[]{bobFilter, bobFilter},
>> -          new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT});
>> -
>> -      hits = searcher.search(query, chain);
>> -      assertEquals("ANDNOT bob ANDNOT bob matches all sues",
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[]{dateFilter, sueFilter},
>> +          new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT}, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("ANDNOT matches just bob",
>>          MAX / 2, hits.length());
>> -      assertEquals("sue", hits.doc(0).get("owner"));
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +
>> +      chain = getChainedFilter(
>> +          new Filter[]{bobFilter, bobFilter},
>> +            new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT}, 
>> old);
>> +
>> +        hits = searcher.search(query, chain);
>> +        assertEquals("ANDNOT bob ANDNOT bob matches all sues",
>> +            MAX / 2, hits.length());
>> +        assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  private Date parseDate(String s) throws ParseException {
>>    return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
>>  }
>> +
>> +  public void testWithCachingFilter() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      Directory dir = new RAMDirectory();
>> +      Analyzer analyzer = new WhitespaceAnalyzer();
>> +
>> +      IndexWriter writer = new IndexWriter(dir, analyzer, true, 
>> MaxFieldLength.LIMITED);
>> +      writer.close();
>> +
>> +      Searcher searcher = new IndexSearcher(dir);
>> +
>> +      Query query = new TermQuery(new Term("none", "none"));
>> +
>> +      QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
>> +      CachingWrapperFilter cachingFilter = new 
>> CachingWrapperFilter(queryFilter);
>> +
>> +      searcher.search(query, cachingFilter, 1);
>> +
>> +      CachingWrapperFilter cachingFilter2 = new 
>> CachingWrapperFilter(queryFilter);
>> +      Filter[] chain = new Filter[2];
>> +      chain[0] = cachingFilter;
>> +      chain[1] = cachingFilter2;
>> +      ChainedFilter cf = new ChainedFilter(chain);
>> +
>> +      // throws java.lang.ClassCastException: 
>> org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
>> +      searcher.search(new MatchAllDocsQuery(), cf, 1);
>> +    }
>> +  }
>>
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -23,6 +23,10 @@
>>
>> import org.apache.lucene.index.IndexReader;
>> import org.apache.lucene.search.BooleanClause.Occur;
>> +import org.apache.lucene.util.DocIdBitSet;
>> +import org.apache.lucene.util.OpenBitSet;
>> +import org.apache.lucene.util.OpenBitSetDISI;
>> +import org.apache.lucene.util.SortedVIntList;
>>
>> /**
>> * A container Filter that allows Boolean composition of Filters.
>> @@ -37,184 +41,167 @@
>>
>> public class BooleanFilter extends Filter
>> {
>> -    //ArrayList of SHOULD filters
>> -    ArrayList shouldFilters = null;
>> -    //ArrayList of NOT filters
>> -    ArrayList notFilters = null;
>> -    //ArrayList of MUST filters
>> -    ArrayList mustFilters = null;
>> -
>> -    /**
>> -     * Returns the a BitSet representing the Boolean composition
>> -     * of the filters that have been added.
>> -     */
>> -   
>> -    public BitSet bits(IndexReader reader) throws IOException
>> -    {
>> -        //create a new bitSet
>> -        BitSet returnBits = null;
>> -       
>> -        //SHOULD filters
>> -        if (shouldFilters!=null)
>> -        {
>> -            returnBits = ((Filter)shouldFilters.get(0)).bits(reader);
>> -//            avoid changing the original bitset - it may be cached
>> -            returnBits=(BitSet) returnBits.clone();
>> -            if (shouldFilters.size() > 1)
>> -            {
>> -                for (int i = 1; i < shouldFilters.size(); i++)
>> -                {
>> -                    
>> returnBits.or(((Filter)shouldFilters.get(i)).bits(reader));
>> -                }
>> -            }
>> -        }
>> -       
>> -        //NOT filters
>> -        if (notFilters!=null)
>> -        {
>> -            for (int i = 0; i < notFilters.size(); i++)
>> -            {
>> -                BitSet notBits=((Filter)notFilters.get(i)).bits(reader);
>> -                if(returnBits==null)
>> -                {
>> -                    returnBits=(BitSet) 
>> notBits.clone();                   
>> -                    returnBits.flip(0,reader.maxDoc());
>> -                }
>> -                else
>> -                {
>> -                    returnBits.andNot(notBits);
>> -                }
>> -            }
>> -        }
>> -       
>> -        //MUST filters
>> -        if (mustFilters!=null)
>> -        {
>> -            for (int i = 0; i < mustFilters.size(); i++)
>> -            {
>> -                BitSet 
>> mustBits=((Filter)mustFilters.get(i)).bits(reader);
>> -                if(returnBits==null)
>> -                {
>> -                    if(mustFilters.size()==1)
>> -                    {
>> -                        returnBits=mustBits;
>> -                       
>> -                    }
>> -                    else
>> -                    {
>> -                        //don't mangle the bitset
>> -                        returnBits=(BitSet) 
>> mustBits.clone();                       
>> -                    }
>> -                }
>> -                else
>> -                {
>> -                    returnBits.and(mustBits);
>> -                }
>> -            }
>> -        }
>> -        if(returnBits==null)
>> -        {
>> -            returnBits=new BitSet(reader.maxDoc());
>> -        }
>> -        return returnBits;
>> -    }
>> -   
>> -    /**
>> -     * Adds a new FilterClause to the Boolean Filter container
>> -     * @param filterClause A FilterClause object containing a Filter 
>> and an Occur parameter
>> -     */
>> -   
>> -    public void add(FilterClause filterClause)
>> -    {
>> -        if (filterClause.getOccur().equals(Occur.MUST))
>> -        {
>> -            if(mustFilters==null)
>> -            {
>> -                mustFilters=new ArrayList();
>> -            }
>> -            mustFilters.add(filterClause.getFilter());
>> -        }
>> -        if (filterClause.getOccur().equals(Occur.SHOULD))
>> -        {
>> -            if(shouldFilters==null)
>> -            {
>> -                shouldFilters=new ArrayList();
>> -            }
>> -            shouldFilters.add(filterClause.getFilter());
>> -        }
>> -        if (filterClause.getOccur().equals(Occur.MUST_NOT))
>> -        {
>> -            if(notFilters==null)
>> -            {
>> -                notFilters=new ArrayList();
>> -            }
>> -            notFilters.add(filterClause.getFilter());
>> -        }
>> -    }
>> -
>> -    public boolean equals(Object obj)
>> -    {
>> -        if(this == obj)
>> -            return true;
>> -        if((obj == null) || (obj.getClass() != this.getClass()))
>> -                return false;
>> -        BooleanFilter test = (BooleanFilter)obj;
>> -        return (notFilters == test.notFilters||
>> -                     (notFilters!= null && 
>> notFilters.equals(test.notFilters)))
>> -                &&
>> -               (mustFilters == test.mustFilters||
>> -                     (mustFilters!= null && 
>> mustFilters.equals(test.mustFilters)))               
>> -                     &&
>> -               (shouldFilters == test.shouldFilters||
>> -                     (shouldFilters!= null && 
>> shouldFilters.equals(test.shouldFilters)));
>> -    }
>> -
>> -    public int hashCode()
>> -    {
>> -        int hash=7;
>> -        hash = 31 * hash + (null == mustFilters ? 0 : 
>> mustFilters.hashCode());
>> -        hash = 31 * hash + (null == notFilters ? 0 : 
>> notFilters.hashCode());
>> -        hash = 31 * hash + (null == shouldFilters ? 0 : 
>> shouldFilters.hashCode());
>> -        return hash;
>> -    }
>> -   
>> -   
>> -        /** Prints a user-readable version of this query. */
>> -    public String toString()
>> -    {
>> -        StringBuffer buffer = new StringBuffer();
>> -
>> -        buffer.append("BooleanFilter(");
>> -
>> -        appendFilters(shouldFilters, null, buffer);
>> -        appendFilters(mustFilters, "+", buffer);
>> -        appendFilters(notFilters, "-", buffer);
>> -
>> -        buffer.append(")");
>> -
>> -        return buffer.toString();
>> -    }
>> -   
>> -    private void appendFilters(ArrayList filters, String occurString,
>> -            StringBuffer buffer)
>> -    {
>> -        if (filters == null)
>> -            return;
>> -
>> -        for (int i = 0; i < filters.size(); i++)
>> -        {
>> -            Filter filter = (Filter) filters.get(i);
>> -            if (occurString != null)
>> -            {
>> -                buffer.append(occurString);
>> -            }
>> -
>> -            buffer.append(filter);
>> -
>> -            if (i < filters.size() - 1)
>> -            {
>> -                buffer.append(' ');
>> -            }
>> -        }
>> -    }       
>> +  ArrayList shouldFilters = null;
>> +  ArrayList notFilters = null;
>> +  ArrayList mustFilters = null;
>> +
>> +  private DocIdSetIterator getDISI(ArrayList filters, int index, 
>> IndexReader reader)
>> +  throws IOException
>> +  {
>> +    return ((Filter)filters.get(index)).getDocIdSet(reader).iterator();
>> +  }
>> +
>> +  /**
>> +   * Returns the a DocIdSetIterator representing the Boolean composition
>> +   * of the filters that have been added.
>> +   */
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>> +  {
>> +    OpenBitSetDISI res = null;
>> +
>> +    if (shouldFilters != null) {
>> +      for (int i = 0; i < shouldFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(shouldFilters, i, reader), 
>> reader.maxDoc());
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)shouldFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.or((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceOr(getDISI(shouldFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (notFilters!=null) {
>> +      for (int i = 0; i < notFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(notFilters, i, reader), 
>> reader.maxDoc());
>> +          res.flip(0, reader.maxDoc()); // NOTE: may set bits on 
>> deleted docs
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)notFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.andNot((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceNot(getDISI(notFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (mustFilters!=null) {
>> +      for (int i = 0; i < mustFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(mustFilters, i, reader), 
>> reader.maxDoc());
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)mustFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.and((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceAnd(getDISI(mustFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (res !=null)
>> +      return finalResult(res, reader.maxDoc());
>> +
>> +    if (emptyDocIdSet == null)
>> +      emptyDocIdSet = new OpenBitSetDISI(1);
>> +
>> +    return emptyDocIdSet;
>> +  }
>> +
>> +  /** Provide a SortedVIntList when it is definitely smaller than an 
>> OpenBitSet */
>> +  protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
>> +    return (result.cardinality() < (maxDocs / 9))
>> +      ? (DocIdSet) new SortedVIntList(result)
>> +      : (DocIdSet) result;
>> +  }
>> +
>> +  private static DocIdSet emptyDocIdSet = null;
>> +
>> +  /**
>> +  * Adds a new FilterClause to the Boolean Filter container
>> +  * @param filterClause A FilterClause object containing a Filter and 
>> an Occur parameter
>> +  */
>> +
>> +  public void add(FilterClause filterClause)
>> +  {
>> +    if (filterClause.getOccur().equals(Occur.MUST)) {
>> +      if (mustFilters==null) {
>> +        mustFilters=new ArrayList();
>> +      }
>> +      mustFilters.add(filterClause.getFilter());
>> +    }
>> +    if (filterClause.getOccur().equals(Occur.SHOULD)) {
>> +      if (shouldFilters==null) {
>> +        shouldFilters=new ArrayList();
>> +      }
>> +      shouldFilters.add(filterClause.getFilter());
>> +    }
>> +    if (filterClause.getOccur().equals(Occur.MUST_NOT)) {
>> +      if (notFilters==null) {
>> +        notFilters=new ArrayList();
>> +      }
>> +      notFilters.add(filterClause.getFilter());
>> +    }
>> +  }
>> +
>> +  private boolean equalFilters(ArrayList filters1, ArrayList filters2)
>> +  {
>> +     return (filters1 == filters2) ||
>> +              ((filters1 != null) && filters1.equals(filters2));
>> +  }
>> +
>> +  public boolean equals(Object obj)
>> +  {
>> +    if (this == obj)
>> +      return true;
>> +
>> +    if ((obj == null) || (obj.getClass() != this.getClass()))
>> +      return false;
>> +
>> +    BooleanFilter other = (BooleanFilter)obj;
>> +    return equalFilters(notFilters, other.notFilters)
>> +        && equalFilters(mustFilters, other.mustFilters)
>> +        && equalFilters(shouldFilters, other.shouldFilters);
>> +  }
>> +
>> +  public int hashCode()
>> +  {
>> +    int hash=7;
>> +    hash = 31 * hash + (null == mustFilters ? 0 : 
>> mustFilters.hashCode());
>> +    hash = 31 * hash + (null == notFilters ? 0 : notFilters.hashCode());
>> +    hash = 31 * hash + (null == shouldFilters ? 0 : 
>> shouldFilters.hashCode());
>> +    return hash;
>> +  }
>> +
>> +  /** Prints a user-readable version of this query. */
>> +  public String toString()
>> +  {
>> +    StringBuffer buffer = new StringBuffer();
>> +    buffer.append("BooleanFilter(");
>> +    appendFilters(shouldFilters, "", buffer);
>> +    appendFilters(mustFilters, "+", buffer);
>> +    appendFilters(notFilters, "-", buffer);
>> +    buffer.append(")");
>> +    return buffer.toString();
>> +  }
>> +
>> +  private void appendFilters(ArrayList filters, String occurString, 
>> StringBuffer buffer)
>> +  {
>> +    if (filters != null) {
>> +      for (int i = 0; i < filters.size(); i++) {
>> +        buffer.append(' ');
>> +        buffer.append(occurString);
>> +        buffer.append(filters.get(i).toString());
>> +      }
>> +    }
>> +  }
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -22,6 +22,7 @@
>> import org.apache.lucene.index.Term;
>> import org.apache.lucene.index.TermDocs;
>> import org.apache.lucene.index.TermEnum;
>> +import org.apache.lucene.util.OpenBitSet;
>>
>> public class DuplicateFilter extends Filter
>> {
>> @@ -66,7 +67,7 @@
>>         this.processingMode = processingMode;
>>     }
>>
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>     {
>>         if(processingMode==PM_FAST_INVALIDATION)
>>         {
>> @@ -78,10 +79,10 @@
>>         }
>>     }
>>     
>> -    private BitSet correctBits(IndexReader reader) throws IOException
>> +  private OpenBitSet correctBits(IndexReader reader) throws IOException
>>     {
>>        
>> -        BitSet bits=new BitSet(reader.maxDoc()); //assume all are 
>> INvalid
>> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc()); //assume all are 
>> INvalid
>>         Term startTerm=new Term(fieldName,"");
>>         TermEnum te = reader.terms(startTerm);
>>         if(te!=null)
>> @@ -117,10 +118,10 @@
>>         return bits;
>>     }
>>     
>> -    private BitSet fastBits(IndexReader reader) throws IOException
>> +  private OpenBitSet fastBits(IndexReader reader) throws IOException
>>     {
>>        
>> -        BitSet bits=new BitSet(reader.maxDoc());
>> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc());
>>         bits.set(0,reader.maxDoc()); //assume all are valid
>>         Term startTerm=new Term(fieldName,"");
>>         TermEnum te = reader.terms(startTerm);
>> @@ -143,7 +144,7 @@
>>                     do
>>                     {
>>                         lastDoc=td.doc();
>> -                        bits.set(lastDoc,false);
>> +            bits.clear(lastDoc);
>>                     }while(td.next());
>>                     if(keepMode==KM_USE_LAST_OCCURRENCE)
>>                     {
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -26,6 +26,7 @@
>> import org.apache.lucene.index.IndexReader;
>> import org.apache.lucene.index.Term;
>> import org.apache.lucene.index.TermDocs;
>> +import org.apache.lucene.util.OpenBitSet;
>>
>> /**
>> * Constructs a filter for docs matching any of the terms added to this 
>> class.
>> @@ -50,11 +51,11 @@
>>     }
>>
>>     /* (non-Javadoc)
>> -     * @see 
>> org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader)
>> +   * @see 
>> org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader) 
>>
>>      */
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>     {
>> -        BitSet result=new BitSet(reader.maxDoc());
>> +    OpenBitSet result=new OpenBitSet(reader.maxDoc());
>>        TermDocs td = reader.termDocs();
>>        try
>>        {
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>> Fri May 23 12:25:05 2008
>> @@ -32,6 +32,7 @@
>> import org.apache.lucene.search.FilterClause;
>> import org.apache.lucene.search.RangeFilter;
>> import org.apache.lucene.store.RAMDirectory;
>> +import org.apache.lucene.util.DocIdBitSet;
>>
>> import junit.framework.TestCase;
>>
>> @@ -66,100 +67,141 @@
>>         writer.addDocument(doc);
>>     }
>>     
>> -    private Filter getRangeFilter(String field,String lowerPrice, 
>> String upperPrice)
>> +  private Filter getRangeFilter(String field,String lowerPrice, 
>> String upperPrice, boolean old)
>>     {
>> -        return new RangeFilter(field,lowerPrice,upperPrice,true,true);
>> +    Filter f = new RangeFilter(field,lowerPrice,upperPrice,true,true);
>> +    if (old) {
>> +      return new OldBitSetFilterWrapper(f);
>> +    }
>> +
>> +    return f;
>>     }
>> -    private TermsFilter getTermsFilter(String field,String text)
>> +  private Filter getTermsFilter(String field,String text, boolean old)
>>     {
>>         TermsFilter tf=new TermsFilter();
>>         tf.addTerm(new Term(field,text));
>> +    if (old) {
>> +      return new OldBitSetFilterWrapper(tf);
>> +    }
>> +
>>         return tf;
>>     }
>> +
>> +        private void tstFilterCard(String mes, int expected, Filter 
>> filt)
>> +        throws Throwable
>> +        {
>> +          DocIdSetIterator disi = filt.getDocIdSet(reader).iterator();
>> +          int actual = 0;
>> +          while (disi.next()) {
>> +            actual++;
>> +          }
>> +          assertEquals(mes, expected, actual);
>> +        }
>> +
>>        
>>     public void testShould() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.SHOULD));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Should retrieves only 1 
>> doc",1,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      tstFilterCard("Should retrieves only 1 doc",1,booleanFilter);
>> +    }
>>     }
>>     
>>     public void testShoulds() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds are Ored together",5,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      tstFilterCard("Shoulds are Ored together",5,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "N"),BooleanClause.Occur.MUST_NOT));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but AndNot",4,bits.cardinality());
>> -
>> -        booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "Maybe"),BooleanClause.Occur.MUST_NOT));
>> -        bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but AndNots",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "N", old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but AndNot",4,booleanFilter);
>> +
>> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "Maybe", old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but AndNots",3,booleanFilter);
>> +    }
>>        
>>     }
>>     public void testShouldsAndMust() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUST",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("Shoulds Ored but MUST",3,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMusts() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20040101", 
>> "20041231"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUSTs 
>> ANDED",1,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20040101", "20041231", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("Shoulds Ored but MUSTs ANDED",1,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMustsAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","030", 
>> "040"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20050101", 
>> "20051231"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUSTs ANDED and 
>> MustNot",0,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","030", "040", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20050101", "20051231", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but MUSTs ANDED and 
>> MustNot",0,booleanFilter);
>> +    }
>>     }
>>     
>>     public void testJustMust() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("MUST",3,booleanFilter);
>> +    }
>>     }
>>     public void testJustMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST_NOT",4,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("MUST_NOT",4,booleanFilter);
>> +    }
>>     }
>>     public void testMustAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST_NOT wins over MUST for same 
>> docs",0,bits.cardinality());
>> -    }
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>>
>> -   
>> -   
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("MUST_NOT wins over MUST for same 
>> docs",0,booleanFilter);
>> +    }
>> +    }
>> }
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>> (original)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>> Fri May 23 12:25:05 2008
>> @@ -150,8 +150,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>   * matching documents.  The high-level search API ({@link
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java 
>> (original)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java 
>> Fri May 23 12:25:05 2008
>> @@ -33,7 +33,7 @@
>> *
>> * <p>Queries, filters and sort criteria are designed to be compact so 
>> that
>> * they may be efficiently passed to a remote index, with only the 
>> top-scoring
>> - * hits being returned, rather than every non-zero scoring hit.
>> + * hits being returned, rather than every matching hit.
>> */
>> public interface Searchable extends java.rmi.Remote {
>>  /** Lower-level search API.
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java 
>> (original)
>> +++ lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java 
>> Fri May 23 12:25:05 2008
>> @@ -88,8 +88,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>   * matching documents.  The high-level search API ({@link
>> @@ -107,8 +107,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   * <br>HitCollector-based access to remote indexes is discouraged.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>
>> Added: 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java?rev=659635&view=auto 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java 
>> (added)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java 
>> Fri May 23 12:25:05 2008
>> @@ -0,0 +1,101 @@
>> +package org.apache.lucene.util;
>> +
>> +/**
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, 
>> Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +
>> +import java.io.IOException;
>> +import org.apache.lucene.search.DocIdSetIterator;
>> +
>> +public class OpenBitSetDISI extends OpenBitSet {
>> +
>> +  /** Construct an OpenBitSetDISI with its bits set
>> +   * from the doc ids of the given DocIdSetIterator.
>> +   * Also give a maximum size one larger than the largest doc id for 
>> which a
>> +   * bit may ever be set on this OpenBitSetDISI.
>> +   */
>> +  public OpenBitSetDISI(DocIdSetIterator disi, int maxSize) throws 
>> IOException {
>> +    super(maxSize);
>> +    inPlaceOr(disi);
>> +  }
>> +
>> +  /** Construct an OpenBitSetDISI with no bits set, and a given 
>> maximum size
>> +   * one larger than the largest doc id for which a bit may ever be set
>> +   * on this OpenBitSetDISI.
>> +   */
>> +  public OpenBitSetDISI(int maxSize) {
>> +    super(maxSize);
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace OR with the doc ids from a given 
>> DocIdSetIterator,
>> +   * setting the bit for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceOr(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastSet(disi.doc());
>> +    }
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace AND with the doc ids from a given 
>> DocIdSetIterator,
>> +   * leaving only the bits set for which the doc ids are in common.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceAnd(DocIdSetIterator disi) throws IOException {
>> +    int index = nextSetBit(0);
>> +    int lastNotCleared = -1;
>> +    while ((index != -1) && disi.skipTo(index)) {
>> +      while ((index != -1) && (index < disi.doc())) {
>> +        fastClear(index);
>> +        index = nextSetBit(index + 1);
>> +      }
>> +      if (index == disi.doc()) {
>> +        lastNotCleared = index;
>> +        index++;
>> +      }
>> +      assert (index == -1) || (index > disi.doc());
>> +    }
>> +    clear(lastNotCleared+1, size());
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace NOT with the doc ids from a given 
>> DocIdSetIterator,
>> +   * clearing all the bits for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceNot(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastClear(disi.doc());
>> +    }
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace XOR with the doc ids from a given 
>> DocIdSetIterator,
>> +   * flipping all the bits for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceXor(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastFlip(disi.doc());
>> +    }
>> +  }
>> +}
>>
>> Added: 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java?rev=659635&view=auto 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>> (added)
>> +++ 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>> Fri May 23 12:25:05 2008
>> @@ -0,0 +1,48 @@
>> +package org.apache.lucene.search;
>> +
>> +/**
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, 
>> Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +
>> +import java.io.IOException;
>> +import java.util.BitSet;
>> +
>> +import org.apache.lucene.index.IndexReader;
>> +
>> +  /**
>> +   *  Helper class used for testing compatibility with old 
>> BitSet-based filters.
>> +   *  Does not override {@link Filter#getDocIdSet(IndexReader)} and 
>> thus ensures
>> +   *  that {@link #bits(IndexReader)} is called.
>> +   *
>> +   *  @deprecated This class will be removed together with the
>> +   *  {@link Filter#bits(IndexReader)} method in Lucene 3.0.
>> +   */
>> +  public class OldBitSetFilterWrapper extends Filter {
>> +    private Filter filter;
>> +
>> +    public OldBitSetFilterWrapper(Filter filter) {
>> +      this.filter = filter;
>> +    }
>> +
>> +    public BitSet bits(IndexReader reader) throws IOException {
>> +      BitSet bits = new BitSet(reader.maxDoc());
>> +      DocIdSetIterator it = filter.getDocIdSet(reader).iterator();
>> +      while(it.next()) {
>> +        bits.set(it.doc());
>> +      }
>> +      return bits;
>> +    }
>> +  }
>>
>>
> 
> --------------------------
> Grant Ingersoll
> http://www.lucidimagination.com
> 
> Lucene Helpful Hints:
> http://wiki.apache.org/lucene-java/BasicsOfPerformance
> http://wiki.apache.org/lucene-java/LuceneFAQ
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-dev-help@lucene.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-dev-help@lucene.apache.org


Re: svn commit: r659635 - in /lucene/java/trunk: ./ contrib/miscellaneous/src/java/org/apache/lucene/misc/ contrib/miscellaneous/src/test/org/apache/lucene/misc/ contrib/queries/src/java/org/apache/lucene/search/ contrib/queries/src/test/org/apache/lucene/...

Posted by Michael Busch <bu...@gmail.com>.
OK this should be fixed now.

I didn't notice that I had different classpath settings in my eclipse 
project. Sorry about that.

-Michael


Grant Ingersoll wrote:
> I'm getting:
> 
> common.compile-test:
>    [javac] Compiling 5 source files to 
> /lucene-clean/build/contrib/misc/classes/test
>    [javac] 
> .../lucene-clean/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java:92: 
> cannot find symbol
>    [javac] symbol  : class OldBitSetFilterWrapper
>    [javac] location: class org.apache.lucene.misc.ChainedFilterTest
>    [javac]       oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
>    [javac]                           ^
>    [javac] Note: Some input files use or override a deprecated API.
>    [javac] Note: Recompile with -Xlint:deprecation for details.
>    [javac] 1 error
> 
> 
> 
> When trying to run ant dist from the top.
> 
> svn info
> Path: .
> URL: 
> https://svn.apache.org/repos/asf/lucene/java/trunk/contrib/miscellaneous
> Repository Root: https://svn.apache.org/repos/asf
> Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
> Revision: 659700
> Node Kind: directory
> Schedule: normal
> Last Changed Author: buschmi
> Last Changed Rev: 659635
> Last Changed Date: 2008-05-23 15:25:05 -0400 (Fri, 23 May 2008)
> 
> 
> I'm up to date and I did a clean first.
> 
> 
> -Grant
> 
> On May 23, 2008, at 3:25 PM, buschmi@apache.org wrote:
> 
>> Author: buschmi
>> Date: Fri May 23 12:25:05 2008
>> New Revision: 659635
>>
>> URL: http://svn.apache.org/viewvc?rev=659635&view=rev
>> Log:
>> LUCENE-1187: ChainedFilter and BooleanFilter now work with new Filter 
>> API and DocIdSetIterator-based filters.
>>
>> Added:
>>   lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
>>   
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>>
>> Modified:
>>   lucene/java/trunk/CHANGES.txt
>>   
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>>
>>   
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>>
>>   
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>>
>>   lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
>>   lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
>>
>> Modified: lucene/java/trunk/CHANGES.txt
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- lucene/java/trunk/CHANGES.txt (original)
>> +++ lucene/java/trunk/CHANGES.txt Fri May 23 12:25:05 2008
>> @@ -163,6 +163,10 @@
>>
>> 13. LUCENE-1166: Decomposition tokenfilter for languages like German 
>> and Swedish (Thomas Peuss via Grant Ingersoll)
>>
>> +14. LUCENE-1187: ChainedFilter and BooleanFilter now work with new 
>> Filter API
>> +    and DocIdSetIterator-based filters. Backwards-compatibility with old
>> +    BitSet-based filters is ensured. (Paul Elschot via Michael Busch)
>> +
>> Optimizations
>>
>> 1. LUCENE-705: When building a compound file, use
>>
>> Modified: 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -58,7 +58,11 @@
>> import org.apache.lucene.search.Filter;
>>
>> import java.io.IOException;
>> -import java.util.BitSet;
>> +import org.apache.lucene.search.DocIdSet;
>> +import org.apache.lucene.search.DocIdSetIterator;
>> +import org.apache.lucene.util.OpenBitSet;
>> +import org.apache.lucene.util.OpenBitSetDISI;
>> +import org.apache.lucene.util.SortedVIntList;
>>
>> /**
>> * <p>
>> @@ -79,29 +83,13 @@
>> */
>> public class ChainedFilter extends Filter
>> {
>> -    /**
>> -     * {@link BitSet#or}.
>> -     */
>>    public static final int OR = 0;
>> -
>> -    /**
>> -     * {@link BitSet#and}.
>> -     */
>>    public static final int AND = 1;
>> -
>> -    /**
>> -     * {@link BitSet#andNot}.
>> -     */
>>    public static final int ANDNOT = 2;
>> -
>> -    /**
>> -     * {@link BitSet#xor}.
>> -     */
>>    public static final int XOR = 3;
>> -
>>    /**
>>     * Logical operation when none is declared. Defaults to
>> -     * {@link BitSet#or}.
>> +     * OR.
>>     */
>>    public static int DEFAULT = OR;
>>
>> @@ -144,96 +132,95 @@
>>    }
>>
>>    /**
>> -     * {@link Filter#bits}.
>> +     * {@link Filter#getDocIdSet}.
>>     */
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +    public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>    {
>> +        int[] index = new int[1]; // use array as reference to 
>> modifiable int;
>> +        index[0] = 0;             // an object attribute would not be 
>> thread safe.
>>        if (logic != -1)
>> -            return bits(reader, logic);
>> +            return getDocIdSet(reader, logic, index);
>>        else if (logicArray != null)
>> -            return bits(reader, logicArray);
>> +            return getDocIdSet(reader, logicArray, index);
>>        else
>> -            return bits(reader, DEFAULT);
>> +            return getDocIdSet(reader, DEFAULT, index);
>>    }
>>
>> -    /**
>> -     * Delegates to each filter in the chain.
>> -     * @param reader IndexReader
>> -     * @param logic Logical operation
>> -     * @return BitSet
>> -     */
>> -    private BitSet bits(IndexReader reader, int logic) throws 
>> IOException
>> +    private DocIdSetIterator getDISI(Filter filter, IndexReader reader)
>> +    throws IOException
>>    {
>> -        BitSet result;
>> -        int i = 0;
>> +        return filter.getDocIdSet(reader).iterator();
>> +    }
>>
>> +    private OpenBitSetDISI initialResult(IndexReader reader, int 
>> logic, int[] index)
>> +    throws IOException
>> +    {
>> +        OpenBitSetDISI result;
>>        /**
>>         * First AND operation takes place against a completely false
>> -         * bitset and will always return zero results. Thanks to
>> -         * Daniel Armbrust for pointing this out and suggesting 
>> workaround.
>> +         * bitset and will always return zero results.
>>         */
>>        if (logic == AND)
>>        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            ++i;
>> +            result = new OpenBitSetDISI(getDISI(chain[index[0]], 
>> reader), reader.maxDoc());
>> +            ++index[0];
>>        }
>>        else if (logic == ANDNOT)
>>        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            result.flip(0,reader.maxDoc());
>> -            ++i;
>> +            result = new OpenBitSetDISI(getDISI(chain[index[0]], 
>> reader), reader.maxDoc());
>> +            result.flip(0,reader.maxDoc()); // NOTE: may set bits for 
>> deleted docs.
>> +            ++index[0];
>>        }
>>        else
>>        {
>> -            result = new BitSet(reader.maxDoc());
>> +            result = new OpenBitSetDISI(reader.maxDoc());
>>        }
>> +        return result;
>> +    }
>> +
>> +    /** Provide a SortedVIntList when it is definitely smaller than 
>> an OpenBitSet */
>> +    protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
>> +        return (result.cardinality() < (maxDocs / 9))
>> +              ? (DocIdSet) new SortedVIntList(result)
>> +              : (DocIdSet) result;
>> +    }
>> +
>>
>> -        for (; i < chain.length; i++)
>> +    /**
>> +     * Delegates to each filter in the chain.
>> +     * @param reader IndexReader
>> +     * @param logic Logical operation
>> +     * @return DocIdSet
>> +     */
>> +    private DocIdSet getDocIdSet(IndexReader reader, int logic, int[] 
>> index)
>> +    throws IOException
>> +    {
>> +        OpenBitSetDISI result = initialResult(reader, logic, index);
>> +        for (; index[0] < chain.length; index[0]++)
>>        {
>> -            doChain(result, reader, logic, chain[i]);
>> +            doChain(result, logic, chain[index[0]].getDocIdSet(reader));
>>        }
>> -        return result;
>> +        return finalResult(result, reader.maxDoc());
>>    }
>>
>>    /**
>>     * Delegates to each filter in the chain.
>>     * @param reader IndexReader
>>     * @param logic Logical operation
>> -     * @return BitSet
>> +     * @return DocIdSet
>>     */
>> -    private BitSet bits(IndexReader reader, int[] logic) throws 
>> IOException
>> +    private DocIdSet getDocIdSet(IndexReader reader, int[] logic, 
>> int[] index)
>> +    throws IOException
>>    {
>>        if (logic.length != chain.length)
>>            throw new IllegalArgumentException("Invalid number of 
>> elements in logic array");
>> -        BitSet result;
>> -        int i = 0;
>> -
>> -        /**
>> -         * First AND operation takes place against a completely false
>> -         * bitset and will always return zero results. Thanks to
>> -         * Daniel Armbrust for pointing this out and suggesting 
>> workaround.
>> -         */
>> -        if (logic[0] == AND)
>> -        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            ++i;
>> -        }
>> -        else if (logic[0] == ANDNOT)
>> -        {
>> -            result = (BitSet) chain[i].bits(reader).clone();
>> -            result.flip(0,reader.maxDoc());
>> -            ++i;
>> -        }
>> -        else
>> -        {
>> -            result = new BitSet(reader.maxDoc());
>> -        }
>>
>> -        for (; i < chain.length; i++)
>> +        OpenBitSetDISI result = initialResult(reader, logic[0], index);
>> +        for (; index[0] < chain.length; index[0]++)
>>        {
>> -            doChain(result, reader, logic[i], chain[i]);
>> +            doChain(result, logic[index[0]], 
>> chain[index[0]].getDocIdSet(reader));
>>        }
>> -        return result;
>> +        return finalResult(result, reader.maxDoc());
>>    }
>>
>>    public String toString()
>> @@ -249,26 +236,51 @@
>>        return sb.toString();
>>    }
>>
>> -    private void doChain(BitSet result, IndexReader reader,
>> -                         int logic, Filter filter) throws IOException
>> +    private void doChain(OpenBitSetDISI result, int logic, DocIdSet dis)
>> +    throws IOException
>>    {
>> +
>> +      if (dis instanceof OpenBitSet) {
>> +        // optimized case for OpenBitSets
>>        switch (logic)
>>        {
>>            case OR:
>> -                result.or(filter.bits(reader));
>> +                result.or((OpenBitSet) dis);
>>                break;
>>            case AND:
>> -                result.and(filter.bits(reader));
>> +                result.and((OpenBitSet) dis);
>>                break;
>>            case ANDNOT:
>> -                result.andNot(filter.bits(reader));
>> +                result.andNot((OpenBitSet) dis);
>>                break;
>>            case XOR:
>> -                result.xor(filter.bits(reader));
>> +                result.xor((OpenBitSet) dis);
>>                break;
>>            default:
>> -                doChain(result, reader, DEFAULT, filter);
>> +                doChain(result, DEFAULT, dis);
>>                break;
>>        }
>> +      } else {
>> +        DocIdSetIterator disi = dis.iterator();
>> +        switch (logic)
>> +        {
>> +            case OR:
>> +                result.inPlaceOr(disi);
>> +                break;
>> +            case AND:
>> +                result.inPlaceAnd(disi);
>> +                break;
>> +            case ANDNOT:
>> +                result.inPlaceNot(disi);
>> +                break;
>> +            case XOR:
>> +                result.inPlaceXor(disi);
>> +                break;
>> +            default:
>> +                doChain(result, DEFAULT, dis);
>> +                break;
>> +        }
>> +      }
>>    }
>> +
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java 
>> Fri May 23 12:25:05 2008
>> @@ -19,11 +19,17 @@
>>
>> import junit.framework.TestCase;
>> import java.util.*;
>> +import java.io.IOException;
>> import java.text.ParseException;
>> import java.text.SimpleDateFormat;
>> import org.apache.lucene.index.IndexWriter;
>> import org.apache.lucene.index.Term;
>> +import org.apache.lucene.index.IndexWriter.MaxFieldLength;
>> +import org.apache.lucene.store.Directory;
>> +import org.apache.lucene.store.FSDirectory;
>> +import org.apache.lucene.store.NoLockFactory;
>> import org.apache.lucene.store.RAMDirectory;
>> +import org.apache.lucene.analysis.Analyzer;
>> import org.apache.lucene.analysis.WhitespaceAnalyzer;
>> import org.apache.lucene.document.Document;
>> import org.apache.lucene.document.Field;
>> @@ -80,76 +86,149 @@
>>        new TermQuery(new Term("owner", "sue")));
>>  }
>>
>> -  public void testSingleFilter() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -        new Filter[] {dateFilter});
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals(MAX, hits.length());
>> -
>> -    chain = new ChainedFilter(new Filter[] {bobFilter});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> +  private Filter[] getChainWithOldFilters(Filter[] chain) {
>> +    Filter[] oldFilters = new Filter[chain.length];
>> +    for (int i = 0; i < chain.length; i++) {
>> +      oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
>> +    }
>> +    return oldFilters;
>> +  }
>> +
>> +  private ChainedFilter getChainedFilter(Filter[] chain, int[] logic, 
>> boolean old) {
>> +    if (old) {
>> +      chain = getChainWithOldFilters(chain);
>> +    }
>>
>> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.AND});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> +    if (logic == null) {
>> +      return new ChainedFilter(chain);
>> +    } else {
>> +      return new ChainedFilter(chain, logic);
>> +    }
>> +  }
>> +
>> +  private ChainedFilter getChainedFilter(Filter[] chain, int logic, 
>> boolean old) {
>> +    if (old) {
>> +      chain = getChainWithOldFilters(chain);
>> +    }
>>
>> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.ANDNOT});
>> -    hits = searcher.search(query, chain);
>> -    assertEquals(MAX / 2, hits.length());
>> -    assertEquals("sue", hits.doc(0).get("owner"));
>> +    return new ChainedFilter(chain, logic);
>>  }
>>
>> -  public void testOR() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[] {sueFilter, bobFilter});
>> +
>> +  public void testSingleFilter() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +
>> +      ChainedFilter chain = getChainedFilter(new Filter[] 
>> {dateFilter}, null, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals(MAX, hits.length());
>> +
>> +      chain = new ChainedFilter(new Filter[] {bobFilter});
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +
>> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.AND}, old);
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +
>> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[] 
>> {ChainedFilter.ANDNOT}, old);
>> +      hits = searcher.search(query, chain);
>> +      assertEquals(MAX / 2, hits.length());
>> +      assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>> +  }
>>
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("OR matches all", MAX, hits.length());
>> +  public void testOR() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[] {sueFilter, bobFilter}, null, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("OR matches all", MAX, hits.length());
>> +    }
>>  }
>>
>>  public void testAND() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND);
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("AND matches just bob", MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("AND matches just bob", MAX / 2, hits.length());
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  public void testXOR() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR);
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("XOR matches sue", MAX / 2, hits.length());
>> -    assertEquals("sue", hits.doc(0).get("owner"));
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("XOR matches sue", MAX / 2, hits.length());
>> +      assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  public void testANDNOT() throws Exception {
>> -    ChainedFilter chain = new ChainedFilter(
>> -      new Filter[]{dateFilter, sueFilter},
>> -        new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT});
>> -
>> -    Hits hits = searcher.search(query, chain);
>> -    assertEquals("ANDNOT matches just bob",
>> -        MAX / 2, hits.length());
>> -    assertEquals("bob", hits.doc(0).get("owner"));
>> -
>> -    chain = new ChainedFilter(
>> -        new Filter[]{bobFilter, bobFilter},
>> -          new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT});
>> -
>> -      hits = searcher.search(query, chain);
>> -      assertEquals("ANDNOT bob ANDNOT bob matches all sues",
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      ChainedFilter chain = getChainedFilter(
>> +        new Filter[]{dateFilter, sueFilter},
>> +          new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT}, old);
>> +
>> +      Hits hits = searcher.search(query, chain);
>> +      assertEquals("ANDNOT matches just bob",
>>          MAX / 2, hits.length());
>> -      assertEquals("sue", hits.doc(0).get("owner"));
>> +      assertEquals("bob", hits.doc(0).get("owner"));
>> +
>> +      chain = getChainedFilter(
>> +          new Filter[]{bobFilter, bobFilter},
>> +            new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT}, 
>> old);
>> +
>> +        hits = searcher.search(query, chain);
>> +        assertEquals("ANDNOT bob ANDNOT bob matches all sues",
>> +            MAX / 2, hits.length());
>> +        assertEquals("sue", hits.doc(0).get("owner"));
>> +    }
>>  }
>>
>>  private Date parseDate(String s) throws ParseException {
>>    return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
>>  }
>> +
>> +  public void testWithCachingFilter() throws Exception {
>> +    for (int mode = 0; mode < 2; mode++) {
>> +      boolean old = (mode==0);
>> +      Directory dir = new RAMDirectory();
>> +      Analyzer analyzer = new WhitespaceAnalyzer();
>> +
>> +      IndexWriter writer = new IndexWriter(dir, analyzer, true, 
>> MaxFieldLength.LIMITED);
>> +      writer.close();
>> +
>> +      Searcher searcher = new IndexSearcher(dir);
>> +
>> +      Query query = new TermQuery(new Term("none", "none"));
>> +
>> +      QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
>> +      CachingWrapperFilter cachingFilter = new 
>> CachingWrapperFilter(queryFilter);
>> +
>> +      searcher.search(query, cachingFilter, 1);
>> +
>> +      CachingWrapperFilter cachingFilter2 = new 
>> CachingWrapperFilter(queryFilter);
>> +      Filter[] chain = new Filter[2];
>> +      chain[0] = cachingFilter;
>> +      chain[1] = cachingFilter2;
>> +      ChainedFilter cf = new ChainedFilter(chain);
>> +
>> +      // throws java.lang.ClassCastException: 
>> org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
>> +      searcher.search(new MatchAllDocsQuery(), cf, 1);
>> +    }
>> +  }
>>
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -23,6 +23,10 @@
>>
>> import org.apache.lucene.index.IndexReader;
>> import org.apache.lucene.search.BooleanClause.Occur;
>> +import org.apache.lucene.util.DocIdBitSet;
>> +import org.apache.lucene.util.OpenBitSet;
>> +import org.apache.lucene.util.OpenBitSetDISI;
>> +import org.apache.lucene.util.SortedVIntList;
>>
>> /**
>> * A container Filter that allows Boolean composition of Filters.
>> @@ -37,184 +41,167 @@
>>
>> public class BooleanFilter extends Filter
>> {
>> -    //ArrayList of SHOULD filters
>> -    ArrayList shouldFilters = null;
>> -    //ArrayList of NOT filters
>> -    ArrayList notFilters = null;
>> -    //ArrayList of MUST filters
>> -    ArrayList mustFilters = null;
>> -
>> -    /**
>> -     * Returns the a BitSet representing the Boolean composition
>> -     * of the filters that have been added.
>> -     */
>> -   
>> -    public BitSet bits(IndexReader reader) throws IOException
>> -    {
>> -        //create a new bitSet
>> -        BitSet returnBits = null;
>> -       
>> -        //SHOULD filters
>> -        if (shouldFilters!=null)
>> -        {
>> -            returnBits = ((Filter)shouldFilters.get(0)).bits(reader);
>> -//            avoid changing the original bitset - it may be cached
>> -            returnBits=(BitSet) returnBits.clone();
>> -            if (shouldFilters.size() > 1)
>> -            {
>> -                for (int i = 1; i < shouldFilters.size(); i++)
>> -                {
>> -                    
>> returnBits.or(((Filter)shouldFilters.get(i)).bits(reader));
>> -                }
>> -            }
>> -        }
>> -       
>> -        //NOT filters
>> -        if (notFilters!=null)
>> -        {
>> -            for (int i = 0; i < notFilters.size(); i++)
>> -            {
>> -                BitSet notBits=((Filter)notFilters.get(i)).bits(reader);
>> -                if(returnBits==null)
>> -                {
>> -                    returnBits=(BitSet) 
>> notBits.clone();                   
>> -                    returnBits.flip(0,reader.maxDoc());
>> -                }
>> -                else
>> -                {
>> -                    returnBits.andNot(notBits);
>> -                }
>> -            }
>> -        }
>> -       
>> -        //MUST filters
>> -        if (mustFilters!=null)
>> -        {
>> -            for (int i = 0; i < mustFilters.size(); i++)
>> -            {
>> -                BitSet 
>> mustBits=((Filter)mustFilters.get(i)).bits(reader);
>> -                if(returnBits==null)
>> -                {
>> -                    if(mustFilters.size()==1)
>> -                    {
>> -                        returnBits=mustBits;
>> -                       
>> -                    }
>> -                    else
>> -                    {
>> -                        //don't mangle the bitset
>> -                        returnBits=(BitSet) 
>> mustBits.clone();                       
>> -                    }
>> -                }
>> -                else
>> -                {
>> -                    returnBits.and(mustBits);
>> -                }
>> -            }
>> -        }
>> -        if(returnBits==null)
>> -        {
>> -            returnBits=new BitSet(reader.maxDoc());
>> -        }
>> -        return returnBits;
>> -    }
>> -   
>> -    /**
>> -     * Adds a new FilterClause to the Boolean Filter container
>> -     * @param filterClause A FilterClause object containing a Filter 
>> and an Occur parameter
>> -     */
>> -   
>> -    public void add(FilterClause filterClause)
>> -    {
>> -        if (filterClause.getOccur().equals(Occur.MUST))
>> -        {
>> -            if(mustFilters==null)
>> -            {
>> -                mustFilters=new ArrayList();
>> -            }
>> -            mustFilters.add(filterClause.getFilter());
>> -        }
>> -        if (filterClause.getOccur().equals(Occur.SHOULD))
>> -        {
>> -            if(shouldFilters==null)
>> -            {
>> -                shouldFilters=new ArrayList();
>> -            }
>> -            shouldFilters.add(filterClause.getFilter());
>> -        }
>> -        if (filterClause.getOccur().equals(Occur.MUST_NOT))
>> -        {
>> -            if(notFilters==null)
>> -            {
>> -                notFilters=new ArrayList();
>> -            }
>> -            notFilters.add(filterClause.getFilter());
>> -        }
>> -    }
>> -
>> -    public boolean equals(Object obj)
>> -    {
>> -        if(this == obj)
>> -            return true;
>> -        if((obj == null) || (obj.getClass() != this.getClass()))
>> -                return false;
>> -        BooleanFilter test = (BooleanFilter)obj;
>> -        return (notFilters == test.notFilters||
>> -                     (notFilters!= null && 
>> notFilters.equals(test.notFilters)))
>> -                &&
>> -               (mustFilters == test.mustFilters||
>> -                     (mustFilters!= null && 
>> mustFilters.equals(test.mustFilters)))               
>> -                     &&
>> -               (shouldFilters == test.shouldFilters||
>> -                     (shouldFilters!= null && 
>> shouldFilters.equals(test.shouldFilters)));
>> -    }
>> -
>> -    public int hashCode()
>> -    {
>> -        int hash=7;
>> -        hash = 31 * hash + (null == mustFilters ? 0 : 
>> mustFilters.hashCode());
>> -        hash = 31 * hash + (null == notFilters ? 0 : 
>> notFilters.hashCode());
>> -        hash = 31 * hash + (null == shouldFilters ? 0 : 
>> shouldFilters.hashCode());
>> -        return hash;
>> -    }
>> -   
>> -   
>> -        /** Prints a user-readable version of this query. */
>> -    public String toString()
>> -    {
>> -        StringBuffer buffer = new StringBuffer();
>> -
>> -        buffer.append("BooleanFilter(");
>> -
>> -        appendFilters(shouldFilters, null, buffer);
>> -        appendFilters(mustFilters, "+", buffer);
>> -        appendFilters(notFilters, "-", buffer);
>> -
>> -        buffer.append(")");
>> -
>> -        return buffer.toString();
>> -    }
>> -   
>> -    private void appendFilters(ArrayList filters, String occurString,
>> -            StringBuffer buffer)
>> -    {
>> -        if (filters == null)
>> -            return;
>> -
>> -        for (int i = 0; i < filters.size(); i++)
>> -        {
>> -            Filter filter = (Filter) filters.get(i);
>> -            if (occurString != null)
>> -            {
>> -                buffer.append(occurString);
>> -            }
>> -
>> -            buffer.append(filter);
>> -
>> -            if (i < filters.size() - 1)
>> -            {
>> -                buffer.append(' ');
>> -            }
>> -        }
>> -    }       
>> +  ArrayList shouldFilters = null;
>> +  ArrayList notFilters = null;
>> +  ArrayList mustFilters = null;
>> +
>> +  private DocIdSetIterator getDISI(ArrayList filters, int index, 
>> IndexReader reader)
>> +  throws IOException
>> +  {
>> +    return ((Filter)filters.get(index)).getDocIdSet(reader).iterator();
>> +  }
>> +
>> +  /**
>> +   * Returns the a DocIdSetIterator representing the Boolean composition
>> +   * of the filters that have been added.
>> +   */
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>> +  {
>> +    OpenBitSetDISI res = null;
>> +
>> +    if (shouldFilters != null) {
>> +      for (int i = 0; i < shouldFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(shouldFilters, i, reader), 
>> reader.maxDoc());
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)shouldFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.or((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceOr(getDISI(shouldFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (notFilters!=null) {
>> +      for (int i = 0; i < notFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(notFilters, i, reader), 
>> reader.maxDoc());
>> +          res.flip(0, reader.maxDoc()); // NOTE: may set bits on 
>> deleted docs
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)notFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.andNot((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceNot(getDISI(notFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (mustFilters!=null) {
>> +      for (int i = 0; i < mustFilters.size(); i++) {
>> +        if (res == null) {
>> +          res = new OpenBitSetDISI(getDISI(mustFilters, i, reader), 
>> reader.maxDoc());
>> +        } else {
>> +          DocIdSet dis = 
>> ((Filter)mustFilters.get(i)).getDocIdSet(reader);
>> +          if(dis instanceof OpenBitSet) {
>> +            // optimized case for OpenBitSets
>> +            res.and((OpenBitSet) dis);
>> +          } else {
>> +            res.inPlaceAnd(getDISI(mustFilters, i, reader));
>> +          }
>> +        }
>> +      }
>> +    }
>> +
>> +    if (res !=null)
>> +      return finalResult(res, reader.maxDoc());
>> +
>> +    if (emptyDocIdSet == null)
>> +      emptyDocIdSet = new OpenBitSetDISI(1);
>> +
>> +    return emptyDocIdSet;
>> +  }
>> +
>> +  /** Provide a SortedVIntList when it is definitely smaller than an 
>> OpenBitSet */
>> +  protected DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
>> +    return (result.cardinality() < (maxDocs / 9))
>> +      ? (DocIdSet) new SortedVIntList(result)
>> +      : (DocIdSet) result;
>> +  }
>> +
>> +  private static DocIdSet emptyDocIdSet = null;
>> +
>> +  /**
>> +  * Adds a new FilterClause to the Boolean Filter container
>> +  * @param filterClause A FilterClause object containing a Filter and 
>> an Occur parameter
>> +  */
>> +
>> +  public void add(FilterClause filterClause)
>> +  {
>> +    if (filterClause.getOccur().equals(Occur.MUST)) {
>> +      if (mustFilters==null) {
>> +        mustFilters=new ArrayList();
>> +      }
>> +      mustFilters.add(filterClause.getFilter());
>> +    }
>> +    if (filterClause.getOccur().equals(Occur.SHOULD)) {
>> +      if (shouldFilters==null) {
>> +        shouldFilters=new ArrayList();
>> +      }
>> +      shouldFilters.add(filterClause.getFilter());
>> +    }
>> +    if (filterClause.getOccur().equals(Occur.MUST_NOT)) {
>> +      if (notFilters==null) {
>> +        notFilters=new ArrayList();
>> +      }
>> +      notFilters.add(filterClause.getFilter());
>> +    }
>> +  }
>> +
>> +  private boolean equalFilters(ArrayList filters1, ArrayList filters2)
>> +  {
>> +     return (filters1 == filters2) ||
>> +              ((filters1 != null) && filters1.equals(filters2));
>> +  }
>> +
>> +  public boolean equals(Object obj)
>> +  {
>> +    if (this == obj)
>> +      return true;
>> +
>> +    if ((obj == null) || (obj.getClass() != this.getClass()))
>> +      return false;
>> +
>> +    BooleanFilter other = (BooleanFilter)obj;
>> +    return equalFilters(notFilters, other.notFilters)
>> +        && equalFilters(mustFilters, other.mustFilters)
>> +        && equalFilters(shouldFilters, other.shouldFilters);
>> +  }
>> +
>> +  public int hashCode()
>> +  {
>> +    int hash=7;
>> +    hash = 31 * hash + (null == mustFilters ? 0 : 
>> mustFilters.hashCode());
>> +    hash = 31 * hash + (null == notFilters ? 0 : notFilters.hashCode());
>> +    hash = 31 * hash + (null == shouldFilters ? 0 : 
>> shouldFilters.hashCode());
>> +    return hash;
>> +  }
>> +
>> +  /** Prints a user-readable version of this query. */
>> +  public String toString()
>> +  {
>> +    StringBuffer buffer = new StringBuffer();
>> +    buffer.append("BooleanFilter(");
>> +    appendFilters(shouldFilters, "", buffer);
>> +    appendFilters(mustFilters, "+", buffer);
>> +    appendFilters(notFilters, "-", buffer);
>> +    buffer.append(")");
>> +    return buffer.toString();
>> +  }
>> +
>> +  private void appendFilters(ArrayList filters, String occurString, 
>> StringBuffer buffer)
>> +  {
>> +    if (filters != null) {
>> +      for (int i = 0; i < filters.size(); i++) {
>> +        buffer.append(' ');
>> +        buffer.append(occurString);
>> +        buffer.append(filters.get(i).toString());
>> +      }
>> +    }
>> +  }
>> }
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -22,6 +22,7 @@
>> import org.apache.lucene.index.Term;
>> import org.apache.lucene.index.TermDocs;
>> import org.apache.lucene.index.TermEnum;
>> +import org.apache.lucene.util.OpenBitSet;
>>
>> public class DuplicateFilter extends Filter
>> {
>> @@ -66,7 +67,7 @@
>>         this.processingMode = processingMode;
>>     }
>>
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>     {
>>         if(processingMode==PM_FAST_INVALIDATION)
>>         {
>> @@ -78,10 +79,10 @@
>>         }
>>     }
>>     
>> -    private BitSet correctBits(IndexReader reader) throws IOException
>> +  private OpenBitSet correctBits(IndexReader reader) throws IOException
>>     {
>>        
>> -        BitSet bits=new BitSet(reader.maxDoc()); //assume all are 
>> INvalid
>> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc()); //assume all are 
>> INvalid
>>         Term startTerm=new Term(fieldName,"");
>>         TermEnum te = reader.terms(startTerm);
>>         if(te!=null)
>> @@ -117,10 +118,10 @@
>>         return bits;
>>     }
>>     
>> -    private BitSet fastBits(IndexReader reader) throws IOException
>> +  private OpenBitSet fastBits(IndexReader reader) throws IOException
>>     {
>>        
>> -        BitSet bits=new BitSet(reader.maxDoc());
>> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc());
>>         bits.set(0,reader.maxDoc()); //assume all are valid
>>         Term startTerm=new Term(fieldName,"");
>>         TermEnum te = reader.terms(startTerm);
>> @@ -143,7 +144,7 @@
>>                     do
>>                     {
>>                         lastDoc=td.doc();
>> -                        bits.set(lastDoc,false);
>> +            bits.clear(lastDoc);
>>                     }while(td.next());
>>                     if(keepMode==KM_USE_LAST_OCCURRENCE)
>>                     {
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java 
>> Fri May 23 12:25:05 2008
>> @@ -26,6 +26,7 @@
>> import org.apache.lucene.index.IndexReader;
>> import org.apache.lucene.index.Term;
>> import org.apache.lucene.index.TermDocs;
>> +import org.apache.lucene.util.OpenBitSet;
>>
>> /**
>> * Constructs a filter for docs matching any of the terms added to this 
>> class.
>> @@ -50,11 +51,11 @@
>>     }
>>
>>     /* (non-Javadoc)
>> -     * @see 
>> org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader)
>> +   * @see 
>> org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader) 
>>
>>      */
>> -    public BitSet bits(IndexReader reader) throws IOException
>> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
>>     {
>> -        BitSet result=new BitSet(reader.maxDoc());
>> +    OpenBitSet result=new OpenBitSet(reader.maxDoc());
>>        TermDocs td = reader.termDocs();
>>        try
>>        {
>>
>> Modified: 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>> (original)
>> +++ 
>> lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java 
>> Fri May 23 12:25:05 2008
>> @@ -32,6 +32,7 @@
>> import org.apache.lucene.search.FilterClause;
>> import org.apache.lucene.search.RangeFilter;
>> import org.apache.lucene.store.RAMDirectory;
>> +import org.apache.lucene.util.DocIdBitSet;
>>
>> import junit.framework.TestCase;
>>
>> @@ -66,100 +67,141 @@
>>         writer.addDocument(doc);
>>     }
>>     
>> -    private Filter getRangeFilter(String field,String lowerPrice, 
>> String upperPrice)
>> +  private Filter getRangeFilter(String field,String lowerPrice, 
>> String upperPrice, boolean old)
>>     {
>> -        return new RangeFilter(field,lowerPrice,upperPrice,true,true);
>> +    Filter f = new RangeFilter(field,lowerPrice,upperPrice,true,true);
>> +    if (old) {
>> +      return new OldBitSetFilterWrapper(f);
>> +    }
>> +
>> +    return f;
>>     }
>> -    private TermsFilter getTermsFilter(String field,String text)
>> +  private Filter getTermsFilter(String field,String text, boolean old)
>>     {
>>         TermsFilter tf=new TermsFilter();
>>         tf.addTerm(new Term(field,text));
>> +    if (old) {
>> +      return new OldBitSetFilterWrapper(tf);
>> +    }
>> +
>>         return tf;
>>     }
>> +
>> +        private void tstFilterCard(String mes, int expected, Filter 
>> filt)
>> +        throws Throwable
>> +        {
>> +          DocIdSetIterator disi = filt.getDocIdSet(reader).iterator();
>> +          int actual = 0;
>> +          while (disi.next()) {
>> +            actual++;
>> +          }
>> +          assertEquals(mes, expected, actual);
>> +        }
>> +
>>        
>>     public void testShould() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.SHOULD));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Should retrieves only 1 
>> doc",1,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      tstFilterCard("Should retrieves only 1 doc",1,booleanFilter);
>> +    }
>>     }
>>     
>>     public void testShoulds() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds are Ored together",5,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      tstFilterCard("Shoulds are Ored together",5,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "N"),BooleanClause.Occur.MUST_NOT));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but AndNot",4,bits.cardinality());
>> -
>> -        booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "Maybe"),BooleanClause.Occur.MUST_NOT));
>> -        bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but AndNots",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "N", old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but AndNot",4,booleanFilter);
>> +
>> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock", 
>> "Maybe", old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but AndNots",3,booleanFilter);
>> +    }
>>        
>>     }
>>     public void testShouldsAndMust() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUST",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("Shoulds Ored but MUST",3,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMusts() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", 
>> "020"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", 
>> "030"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20040101", 
>> "20041231"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUSTs 
>> ANDED",1,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","010", "020", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","020", "030", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20040101", "20041231", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("Shoulds Ored but MUSTs ANDED",1,booleanFilter);
>> +    }
>>     }
>>     public void testShouldsAndMustsAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","030", 
>> "040"),BooleanClause.Occur.SHOULD));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20050101", 
>> "20051231"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("Shoulds Ored but MUSTs ANDED and 
>> MustNot",0,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("price","030", "040", 
>> old),BooleanClause.Occur.SHOULD));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getRangeFilter("date","20050101", "20051231", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("Shoulds Ored but MUSTs ANDED and 
>> MustNot",0,booleanFilter);
>> +    }
>>     }
>>     
>>     public void testJustMust() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", 
>> "admin"),BooleanClause.Occur.MUST));
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST",3,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("accessRights", "admin", 
>> old),BooleanClause.Occur.MUST));
>> +      tstFilterCard("MUST",3,booleanFilter);
>> +    }
>>     }
>>     public void testJustMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST_NOT",4,bits.cardinality());
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>> +
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("MUST_NOT",4,booleanFilter);
>> +    }
>>     }
>>     public void testMustAndMustNot() throws Throwable
>>     {
>> -        BooleanFilter booleanFilter = new BooleanFilter();
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST));
>> -        booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030"),BooleanClause.Occur.MUST_NOT)); 
>>
>> -        BitSet bits = booleanFilter.bits(reader);
>> -        assertEquals("MUST_NOT wins over MUST for same 
>> docs",0,bits.cardinality());
>> -    }
>> +    for (int i = 0; i < 2; i++) {
>> +      boolean old = (i==0);
>>
>> -   
>> -   
>> +      BooleanFilter booleanFilter = new BooleanFilter();
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("inStock","N", 
>> old),BooleanClause.Occur.MUST));
>> +      booleanFilter.add(new 
>> FilterClause(getTermsFilter("price","030", 
>> old),BooleanClause.Occur.MUST_NOT));
>> +      tstFilterCard("MUST_NOT wins over MUST for same 
>> docs",0,booleanFilter);
>> +    }
>> +    }
>> }
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>> (original)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java 
>> Fri May 23 12:25:05 2008
>> @@ -150,8 +150,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>   * matching documents.  The high-level search API ({@link
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java 
>> (original)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java 
>> Fri May 23 12:25:05 2008
>> @@ -33,7 +33,7 @@
>> *
>> * <p>Queries, filters and sort criteria are designed to be compact so 
>> that
>> * they may be efficiently passed to a remote index, with only the 
>> top-scoring
>> - * hits being returned, rather than every non-zero scoring hit.
>> + * hits being returned, rather than every matching hit.
>> */
>> public interface Searchable extends java.rmi.Remote {
>>  /** Lower-level search API.
>>
>> Modified: 
>> lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java?rev=659635&r1=659634&r2=659635&view=diff 
>>
>> ============================================================================== 
>>
>> --- lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java 
>> (original)
>> +++ lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java 
>> Fri May 23 12:25:05 2008
>> @@ -88,8 +88,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>   * matching documents.  The high-level search API ({@link
>> @@ -107,8 +107,8 @@
>>
>>  /** Lower-level search API.
>>   *
>> -   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> non-zero
>> -   * scoring document.
>> +   * <p>{@link HitCollector#collect(int,float)} is called for every 
>> matching
>> +   * document.
>>   * <br>HitCollector-based access to remote indexes is discouraged.
>>   *
>>   * <p>Applications should only use this if they need <i>all</i> of the
>>
>> Added: 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java?rev=659635&view=auto 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java 
>> (added)
>> +++ 
>> lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java 
>> Fri May 23 12:25:05 2008
>> @@ -0,0 +1,101 @@
>> +package org.apache.lucene.util;
>> +
>> +/**
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, 
>> Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +
>> +import java.io.IOException;
>> +import org.apache.lucene.search.DocIdSetIterator;
>> +
>> +public class OpenBitSetDISI extends OpenBitSet {
>> +
>> +  /** Construct an OpenBitSetDISI with its bits set
>> +   * from the doc ids of the given DocIdSetIterator.
>> +   * Also give a maximum size one larger than the largest doc id for 
>> which a
>> +   * bit may ever be set on this OpenBitSetDISI.
>> +   */
>> +  public OpenBitSetDISI(DocIdSetIterator disi, int maxSize) throws 
>> IOException {
>> +    super(maxSize);
>> +    inPlaceOr(disi);
>> +  }
>> +
>> +  /** Construct an OpenBitSetDISI with no bits set, and a given 
>> maximum size
>> +   * one larger than the largest doc id for which a bit may ever be set
>> +   * on this OpenBitSetDISI.
>> +   */
>> +  public OpenBitSetDISI(int maxSize) {
>> +    super(maxSize);
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace OR with the doc ids from a given 
>> DocIdSetIterator,
>> +   * setting the bit for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceOr(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastSet(disi.doc());
>> +    }
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace AND with the doc ids from a given 
>> DocIdSetIterator,
>> +   * leaving only the bits set for which the doc ids are in common.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceAnd(DocIdSetIterator disi) throws IOException {
>> +    int index = nextSetBit(0);
>> +    int lastNotCleared = -1;
>> +    while ((index != -1) && disi.skipTo(index)) {
>> +      while ((index != -1) && (index < disi.doc())) {
>> +        fastClear(index);
>> +        index = nextSetBit(index + 1);
>> +      }
>> +      if (index == disi.doc()) {
>> +        lastNotCleared = index;
>> +        index++;
>> +      }
>> +      assert (index == -1) || (index > disi.doc());
>> +    }
>> +    clear(lastNotCleared+1, size());
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace NOT with the doc ids from a given 
>> DocIdSetIterator,
>> +   * clearing all the bits for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceNot(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastClear(disi.doc());
>> +    }
>> +  }
>> +
>> +  /**
>> +   * Perform an inplace XOR with the doc ids from a given 
>> DocIdSetIterator,
>> +   * flipping all the bits for each such doc id.
>> +   * These doc ids should be smaller than the maximum size passed to the
>> +   * constructor.
>> +   */
>> +  public void inPlaceXor(DocIdSetIterator disi) throws IOException {
>> +    while (disi.next() && (disi.doc() < size())) {
>> +      fastFlip(disi.doc());
>> +    }
>> +  }
>> +}
>>
>> Added: 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>>
>> URL: 
>> http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java?rev=659635&view=auto 
>>
>> ============================================================================== 
>>
>> --- 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>> (added)
>> +++ 
>> lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java 
>> Fri May 23 12:25:05 2008
>> @@ -0,0 +1,48 @@
>> +package org.apache.lucene.search;
>> +
>> +/**
>> + * Licensed to the Apache Software Foundation (ASF) under one or more
>> + * contributor license agreements.  See the NOTICE file distributed with
>> + * this work for additional information regarding copyright ownership.
>> + * The ASF licenses this file to You under the Apache License, 
>> Version 2.0
>> + * (the "License"); you may not use this file except in compliance with
>> + * the License.  You may obtain a copy of the License at
>> + *
>> + *     http://www.apache.org/licenses/LICENSE-2.0
>> + *
>> + * Unless required by applicable law or agreed to in writing, software
>> + * distributed under the License is distributed on an "AS IS" BASIS,
>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
>> implied.
>> + * See the License for the specific language governing permissions and
>> + * limitations under the License.
>> + */
>> +
>> +import java.io.IOException;
>> +import java.util.BitSet;
>> +
>> +import org.apache.lucene.index.IndexReader;
>> +
>> +  /**
>> +   *  Helper class used for testing compatibility with old 
>> BitSet-based filters.
>> +   *  Does not override {@link Filter#getDocIdSet(IndexReader)} and 
>> thus ensures
>> +   *  that {@link #bits(IndexReader)} is called.
>> +   *
>> +   *  @deprecated This class will be removed together with the
>> +   *  {@link Filter#bits(IndexReader)} method in Lucene 3.0.
>> +   */
>> +  public class OldBitSetFilterWrapper extends Filter {
>> +    private Filter filter;
>> +
>> +    public OldBitSetFilterWrapper(Filter filter) {
>> +      this.filter = filter;
>> +    }
>> +
>> +    public BitSet bits(IndexReader reader) throws IOException {
>> +      BitSet bits = new BitSet(reader.maxDoc());
>> +      DocIdSetIterator it = filter.getDocIdSet(reader).iterator();
>> +      while(it.next()) {
>> +        bits.set(it.doc());
>> +      }
>> +      return bits;
>> +    }
>> +  }
>>
>>
> 
> --------------------------
> Grant Ingersoll
> http://www.lucidimagination.com
> 
> Lucene Helpful Hints:
> http://wiki.apache.org/lucene-java/BasicsOfPerformance
> http://wiki.apache.org/lucene-java/LuceneFAQ
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-dev-help@lucene.apache.org
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-dev-help@lucene.apache.org


Re: svn commit: r659635 - in /lucene/java/trunk: ./ contrib/miscellaneous/src/java/org/apache/lucene/misc/ contrib/miscellaneous/src/test/org/apache/lucene/misc/ contrib/queries/src/java/org/apache/lucene/search/ contrib/queries/src/test/org/apache/lucene/...

Posted by Grant Ingersoll <gs...@apache.org>.
I'm getting:

common.compile-test:
    [javac] Compiling 5 source files to /lucene-clean/build/contrib/ 
misc/classes/test
    [javac] .../lucene-clean/contrib/miscellaneous/src/test/org/apache/ 
lucene/misc/ChainedFilterTest.java:92: cannot find symbol
    [javac] symbol  : class OldBitSetFilterWrapper
    [javac] location: class org.apache.lucene.misc.ChainedFilterTest
    [javac]       oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
    [javac]                           ^
    [javac] Note: Some input files use or override a deprecated API.
    [javac] Note: Recompile with -Xlint:deprecation for details.
    [javac] 1 error



When trying to run ant dist from the top.

svn info
Path: .
URL: https://svn.apache.org/repos/asf/lucene/java/trunk/contrib/miscellaneous
Repository Root: https://svn.apache.org/repos/asf
Repository UUID: 13f79535-47bb-0310-9956-ffa450edef68
Revision: 659700
Node Kind: directory
Schedule: normal
Last Changed Author: buschmi
Last Changed Rev: 659635
Last Changed Date: 2008-05-23 15:25:05 -0400 (Fri, 23 May 2008)


I'm up to date and I did a clean first.


-Grant

On May 23, 2008, at 3:25 PM, buschmi@apache.org wrote:

> Author: buschmi
> Date: Fri May 23 12:25:05 2008
> New Revision: 659635
>
> URL: http://svn.apache.org/viewvc?rev=659635&view=rev
> Log:
> LUCENE-1187: ChainedFilter and BooleanFilter now work with new  
> Filter API and DocIdSetIterator-based filters.
>
> Added:
>   lucene/java/trunk/src/java/org/apache/lucene/util/ 
> OpenBitSetDISI.java
>   lucene/java/trunk/src/test/org/apache/lucene/search/ 
> OldBitSetFilterWrapper.java
> Modified:
>   lucene/java/trunk/CHANGES.txt
>   lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/ 
> misc/ChainedFilter.java
>   lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/ 
> misc/ChainedFilterTest.java
>   lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/BooleanFilter.java
>   lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/DuplicateFilter.java
>   lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/TermsFilter.java
>   lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/ 
> search/BooleanFilterTest.java
>   lucene/java/trunk/src/java/org/apache/lucene/search/ 
> ParallelMultiSearcher.java
>   lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java
>   lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java
>
> Modified: lucene/java/trunk/CHANGES.txt
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/CHANGES.txt?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/CHANGES.txt (original)
> +++ lucene/java/trunk/CHANGES.txt Fri May 23 12:25:05 2008
> @@ -163,6 +163,10 @@
>
> 13. LUCENE-1166: Decomposition tokenfilter for languages like German  
> and Swedish (Thomas Peuss via Grant Ingersoll)
>
> +14. LUCENE-1187: ChainedFilter and BooleanFilter now work with new  
> Filter API
> +    and DocIdSetIterator-based filters. Backwards-compatibility  
> with old
> +    BitSet-based filters is ensured. (Paul Elschot via Michael Busch)
> +
> Optimizations
>
> 1. LUCENE-705: When building a compound file, use
>
> Modified: lucene/java/trunk/contrib/miscellaneous/src/java/org/ 
> apache/lucene/misc/ChainedFilter.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/lucene/misc/ChainedFilter.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/ 
> lucene/misc/ChainedFilter.java (original)
> +++ lucene/java/trunk/contrib/miscellaneous/src/java/org/apache/ 
> lucene/misc/ChainedFilter.java Fri May 23 12:25:05 2008
> @@ -58,7 +58,11 @@
> import org.apache.lucene.search.Filter;
>
> import java.io.IOException;
> -import java.util.BitSet;
> +import org.apache.lucene.search.DocIdSet;
> +import org.apache.lucene.search.DocIdSetIterator;
> +import org.apache.lucene.util.OpenBitSet;
> +import org.apache.lucene.util.OpenBitSetDISI;
> +import org.apache.lucene.util.SortedVIntList;
>
> /**
> * <p>
> @@ -79,29 +83,13 @@
> */
> public class ChainedFilter extends Filter
> {
> -    /**
> -     * {@link BitSet#or}.
> -     */
>    public static final int OR = 0;
> -
> -    /**
> -     * {@link BitSet#and}.
> -     */
>    public static final int AND = 1;
> -
> -    /**
> -     * {@link BitSet#andNot}.
> -     */
>    public static final int ANDNOT = 2;
> -
> -    /**
> -     * {@link BitSet#xor}.
> -     */
>    public static final int XOR = 3;
> -
>    /**
>     * Logical operation when none is declared. Defaults to
> -     * {@link BitSet#or}.
> +     * OR.
>     */
>    public static int DEFAULT = OR;
>
> @@ -144,96 +132,95 @@
>    }
>
>    /**
> -     * {@link Filter#bits}.
> +     * {@link Filter#getDocIdSet}.
>     */
> -    public BitSet bits(IndexReader reader) throws IOException
> +    public DocIdSet getDocIdSet(IndexReader reader) throws  
> IOException
>    {
> +        int[] index = new int[1]; // use array as reference to  
> modifiable int;
> +        index[0] = 0;             // an object attribute would not  
> be thread safe.
>        if (logic != -1)
> -            return bits(reader, logic);
> +            return getDocIdSet(reader, logic, index);
>        else if (logicArray != null)
> -            return bits(reader, logicArray);
> +            return getDocIdSet(reader, logicArray, index);
>        else
> -            return bits(reader, DEFAULT);
> +            return getDocIdSet(reader, DEFAULT, index);
>    }
>
> -    /**
> -     * Delegates to each filter in the chain.
> -     * @param reader IndexReader
> -     * @param logic Logical operation
> -     * @return BitSet
> -     */
> -    private BitSet bits(IndexReader reader, int logic) throws  
> IOException
> +    private DocIdSetIterator getDISI(Filter filter, IndexReader  
> reader)
> +    throws IOException
>    {
> -        BitSet result;
> -        int i = 0;
> +        return filter.getDocIdSet(reader).iterator();
> +    }
>
> +    private OpenBitSetDISI initialResult(IndexReader reader, int  
> logic, int[] index)
> +    throws IOException
> +    {
> +        OpenBitSetDISI result;
>        /**
>         * First AND operation takes place against a completely false
> -         * bitset and will always return zero results. Thanks to
> -         * Daniel Armbrust for pointing this out and suggesting  
> workaround.
> +         * bitset and will always return zero results.
>         */
>        if (logic == AND)
>        {
> -            result = (BitSet) chain[i].bits(reader).clone();
> -            ++i;
> +            result = new OpenBitSetDISI(getDISI(chain[index[0]],  
> reader), reader.maxDoc());
> +            ++index[0];
>        }
>        else if (logic == ANDNOT)
>        {
> -            result = (BitSet) chain[i].bits(reader).clone();
> -            result.flip(0,reader.maxDoc());
> -            ++i;
> +            result = new OpenBitSetDISI(getDISI(chain[index[0]],  
> reader), reader.maxDoc());
> +            result.flip(0,reader.maxDoc()); // NOTE: may set bits  
> for deleted docs.
> +            ++index[0];
>        }
>        else
>        {
> -            result = new BitSet(reader.maxDoc());
> +            result = new OpenBitSetDISI(reader.maxDoc());
>        }
> +        return result;
> +    }
> +
> +    /** Provide a SortedVIntList when it is definitely smaller than  
> an OpenBitSet */
> +    protected DocIdSet finalResult(OpenBitSetDISI result, int  
> maxDocs) {
> +        return (result.cardinality() < (maxDocs / 9))
> +              ? (DocIdSet) new SortedVIntList(result)
> +              : (DocIdSet) result;
> +    }
> +
>
> -        for (; i < chain.length; i++)
> +    /**
> +     * Delegates to each filter in the chain.
> +     * @param reader IndexReader
> +     * @param logic Logical operation
> +     * @return DocIdSet
> +     */
> +    private DocIdSet getDocIdSet(IndexReader reader, int logic,  
> int[] index)
> +    throws IOException
> +    {
> +        OpenBitSetDISI result = initialResult(reader, logic, index);
> +        for (; index[0] < chain.length; index[0]++)
>        {
> -            doChain(result, reader, logic, chain[i]);
> +            doChain(result, logic,  
> chain[index[0]].getDocIdSet(reader));
>        }
> -        return result;
> +        return finalResult(result, reader.maxDoc());
>    }
>
>    /**
>     * Delegates to each filter in the chain.
>     * @param reader IndexReader
>     * @param logic Logical operation
> -     * @return BitSet
> +     * @return DocIdSet
>     */
> -    private BitSet bits(IndexReader reader, int[] logic) throws  
> IOException
> +    private DocIdSet getDocIdSet(IndexReader reader, int[] logic,  
> int[] index)
> +    throws IOException
>    {
>        if (logic.length != chain.length)
>            throw new IllegalArgumentException("Invalid number of  
> elements in logic array");
> -        BitSet result;
> -        int i = 0;
> -
> -        /**
> -         * First AND operation takes place against a completely false
> -         * bitset and will always return zero results. Thanks to
> -         * Daniel Armbrust for pointing this out and suggesting  
> workaround.
> -         */
> -        if (logic[0] == AND)
> -        {
> -            result = (BitSet) chain[i].bits(reader).clone();
> -            ++i;
> -        }
> -        else if (logic[0] == ANDNOT)
> -        {
> -            result = (BitSet) chain[i].bits(reader).clone();
> -            result.flip(0,reader.maxDoc());
> -            ++i;
> -        }
> -        else
> -        {
> -            result = new BitSet(reader.maxDoc());
> -        }
>
> -        for (; i < chain.length; i++)
> +        OpenBitSetDISI result = initialResult(reader, logic[0],  
> index);
> +        for (; index[0] < chain.length; index[0]++)
>        {
> -            doChain(result, reader, logic[i], chain[i]);
> +            doChain(result, logic[index[0]],  
> chain[index[0]].getDocIdSet(reader));
>        }
> -        return result;
> +        return finalResult(result, reader.maxDoc());
>    }
>
>    public String toString()
> @@ -249,26 +236,51 @@
>        return sb.toString();
>    }
>
> -    private void doChain(BitSet result, IndexReader reader,
> -                         int logic, Filter filter) throws IOException
> +    private void doChain(OpenBitSetDISI result, int logic, DocIdSet  
> dis)
> +    throws IOException
>    {
> +
> +      if (dis instanceof OpenBitSet) {
> +        // optimized case for OpenBitSets
>        switch (logic)
>        {
>            case OR:
> -                result.or(filter.bits(reader));
> +                result.or((OpenBitSet) dis);
>                break;
>            case AND:
> -                result.and(filter.bits(reader));
> +                result.and((OpenBitSet) dis);
>                break;
>            case ANDNOT:
> -                result.andNot(filter.bits(reader));
> +                result.andNot((OpenBitSet) dis);
>                break;
>            case XOR:
> -                result.xor(filter.bits(reader));
> +                result.xor((OpenBitSet) dis);
>                break;
>            default:
> -                doChain(result, reader, DEFAULT, filter);
> +                doChain(result, DEFAULT, dis);
>                break;
>        }
> +      } else {
> +        DocIdSetIterator disi = dis.iterator();
> +        switch (logic)
> +        {
> +            case OR:
> +                result.inPlaceOr(disi);
> +                break;
> +            case AND:
> +                result.inPlaceAnd(disi);
> +                break;
> +            case ANDNOT:
> +                result.inPlaceNot(disi);
> +                break;
> +            case XOR:
> +                result.inPlaceXor(disi);
> +                break;
> +            default:
> +                doChain(result, DEFAULT, dis);
> +                break;
> +        }
> +      }
>    }
> +
> }
>
> Modified: lucene/java/trunk/contrib/miscellaneous/src/test/org/ 
> apache/lucene/misc/ChainedFilterTest.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/lucene/misc/ChainedFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/ 
> lucene/misc/ChainedFilterTest.java (original)
> +++ lucene/java/trunk/contrib/miscellaneous/src/test/org/apache/ 
> lucene/misc/ChainedFilterTest.java Fri May 23 12:25:05 2008
> @@ -19,11 +19,17 @@
>
> import junit.framework.TestCase;
> import java.util.*;
> +import java.io.IOException;
> import java.text.ParseException;
> import java.text.SimpleDateFormat;
> import org.apache.lucene.index.IndexWriter;
> import org.apache.lucene.index.Term;
> +import org.apache.lucene.index.IndexWriter.MaxFieldLength;
> +import org.apache.lucene.store.Directory;
> +import org.apache.lucene.store.FSDirectory;
> +import org.apache.lucene.store.NoLockFactory;
> import org.apache.lucene.store.RAMDirectory;
> +import org.apache.lucene.analysis.Analyzer;
> import org.apache.lucene.analysis.WhitespaceAnalyzer;
> import org.apache.lucene.document.Document;
> import org.apache.lucene.document.Field;
> @@ -80,76 +86,149 @@
>        new TermQuery(new Term("owner", "sue")));
>  }
>
> -  public void testSingleFilter() throws Exception {
> -    ChainedFilter chain = new ChainedFilter(
> -        new Filter[] {dateFilter});
> -
> -    Hits hits = searcher.search(query, chain);
> -    assertEquals(MAX, hits.length());
> -
> -    chain = new ChainedFilter(new Filter[] {bobFilter});
> -    hits = searcher.search(query, chain);
> -    assertEquals(MAX / 2, hits.length());
> +  private Filter[] getChainWithOldFilters(Filter[] chain) {
> +    Filter[] oldFilters = new Filter[chain.length];
> +    for (int i = 0; i < chain.length; i++) {
> +      oldFilters[i] = new OldBitSetFilterWrapper(chain[i]);
> +    }
> +    return oldFilters;
> +  }
> +
> +  private ChainedFilter getChainedFilter(Filter[] chain, int[]  
> logic, boolean old) {
> +    if (old) {
> +      chain = getChainWithOldFilters(chain);
> +    }
>
> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[]  
> {ChainedFilter.AND});
> -    hits = searcher.search(query, chain);
> -    assertEquals(MAX / 2, hits.length());
> -    assertEquals("bob", hits.doc(0).get("owner"));
> +    if (logic == null) {
> +      return new ChainedFilter(chain);
> +    } else {
> +      return new ChainedFilter(chain, logic);
> +    }
> +  }
> +
> +  private ChainedFilter getChainedFilter(Filter[] chain, int logic,  
> boolean old) {
> +    if (old) {
> +      chain = getChainWithOldFilters(chain);
> +    }
>
> -    chain = new ChainedFilter(new Filter[] {bobFilter}, new int[]  
> {ChainedFilter.ANDNOT});
> -    hits = searcher.search(query, chain);
> -    assertEquals(MAX / 2, hits.length());
> -    assertEquals("sue", hits.doc(0).get("owner"));
> +    return new ChainedFilter(chain, logic);
>  }
>
> -  public void testOR() throws Exception {
> -    ChainedFilter chain = new ChainedFilter(
> -      new Filter[] {sueFilter, bobFilter});
> +
> +  public void testSingleFilter() throws Exception {
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +
> +      ChainedFilter chain = getChainedFilter(new Filter[]  
> {dateFilter}, null, old);
> +
> +      Hits hits = searcher.search(query, chain);
> +      assertEquals(MAX, hits.length());
> +
> +      chain = new ChainedFilter(new Filter[] {bobFilter});
> +      hits = searcher.search(query, chain);
> +      assertEquals(MAX / 2, hits.length());
> +
> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[]  
> {ChainedFilter.AND}, old);
> +      hits = searcher.search(query, chain);
> +      assertEquals(MAX / 2, hits.length());
> +      assertEquals("bob", hits.doc(0).get("owner"));
> +
> +      chain = getChainedFilter(new Filter[] {bobFilter}, new int[]  
> {ChainedFilter.ANDNOT}, old);
> +      hits = searcher.search(query, chain);
> +      assertEquals(MAX / 2, hits.length());
> +      assertEquals("sue", hits.doc(0).get("owner"));
> +    }
> +  }
>
> -    Hits hits = searcher.search(query, chain);
> -    assertEquals("OR matches all", MAX, hits.length());
> +  public void testOR() throws Exception {
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +      ChainedFilter chain = getChainedFilter(
> +        new Filter[] {sueFilter, bobFilter}, null, old);
> +
> +      Hits hits = searcher.search(query, chain);
> +      assertEquals("OR matches all", MAX, hits.length());
> +    }
>  }
>
>  public void testAND() throws Exception {
> -    ChainedFilter chain = new ChainedFilter(
> -      new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND);
> -
> -    Hits hits = searcher.search(query, chain);
> -    assertEquals("AND matches just bob", MAX / 2, hits.length());
> -    assertEquals("bob", hits.doc(0).get("owner"));
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +      ChainedFilter chain = getChainedFilter(
> +        new Filter[] {dateFilter, bobFilter}, ChainedFilter.AND,  
> old);
> +
> +      Hits hits = searcher.search(query, chain);
> +      assertEquals("AND matches just bob", MAX / 2, hits.length());
> +      assertEquals("bob", hits.doc(0).get("owner"));
> +    }
>  }
>
>  public void testXOR() throws Exception {
> -    ChainedFilter chain = new ChainedFilter(
> -      new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR);
> -
> -    Hits hits = searcher.search(query, chain);
> -    assertEquals("XOR matches sue", MAX / 2, hits.length());
> -    assertEquals("sue", hits.doc(0).get("owner"));
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +      ChainedFilter chain = getChainedFilter(
> +        new Filter[]{dateFilter, bobFilter}, ChainedFilter.XOR, old);
> +
> +      Hits hits = searcher.search(query, chain);
> +      assertEquals("XOR matches sue", MAX / 2, hits.length());
> +      assertEquals("sue", hits.doc(0).get("owner"));
> +    }
>  }
>
>  public void testANDNOT() throws Exception {
> -    ChainedFilter chain = new ChainedFilter(
> -      new Filter[]{dateFilter, sueFilter},
> -        new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT});
> -
> -    Hits hits = searcher.search(query, chain);
> -    assertEquals("ANDNOT matches just bob",
> -        MAX / 2, hits.length());
> -    assertEquals("bob", hits.doc(0).get("owner"));
> -
> -    chain = new ChainedFilter(
> -        new Filter[]{bobFilter, bobFilter},
> -          new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT});
> -
> -      hits = searcher.search(query, chain);
> -      assertEquals("ANDNOT bob ANDNOT bob matches all sues",
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +      ChainedFilter chain = getChainedFilter(
> +        new Filter[]{dateFilter, sueFilter},
> +          new int[] {ChainedFilter.AND, ChainedFilter.ANDNOT}, old);
> +
> +      Hits hits = searcher.search(query, chain);
> +      assertEquals("ANDNOT matches just bob",
>          MAX / 2, hits.length());
> -      assertEquals("sue", hits.doc(0).get("owner"));
> +      assertEquals("bob", hits.doc(0).get("owner"));
> +
> +      chain = getChainedFilter(
> +          new Filter[]{bobFilter, bobFilter},
> +            new int[] {ChainedFilter.ANDNOT, ChainedFilter.ANDNOT},  
> old);
> +
> +        hits = searcher.search(query, chain);
> +        assertEquals("ANDNOT bob ANDNOT bob matches all sues",
> +            MAX / 2, hits.length());
> +        assertEquals("sue", hits.doc(0).get("owner"));
> +    }
>  }
>
>  private Date parseDate(String s) throws ParseException {
>    return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s);
>  }
> +
> +  public void testWithCachingFilter() throws Exception {
> +    for (int mode = 0; mode < 2; mode++) {
> +      boolean old = (mode==0);
> +      Directory dir = new RAMDirectory();
> +      Analyzer analyzer = new WhitespaceAnalyzer();
> +
> +      IndexWriter writer = new IndexWriter(dir, analyzer, true,  
> MaxFieldLength.LIMITED);
> +      writer.close();
> +
> +      Searcher searcher = new IndexSearcher(dir);
> +
> +      Query query = new TermQuery(new Term("none", "none"));
> +
> +      QueryWrapperFilter queryFilter = new QueryWrapperFilter(query);
> +      CachingWrapperFilter cachingFilter = new  
> CachingWrapperFilter(queryFilter);
> +
> +      searcher.search(query, cachingFilter, 1);
> +
> +      CachingWrapperFilter cachingFilter2 = new  
> CachingWrapperFilter(queryFilter);
> +      Filter[] chain = new Filter[2];
> +      chain[0] = cachingFilter;
> +      chain[1] = cachingFilter2;
> +      ChainedFilter cf = new ChainedFilter(chain);
> +
> +      // throws java.lang.ClassCastException:  
> org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet
> +      searcher.search(new MatchAllDocsQuery(), cf, 1);
> +    }
> +  }
>
> }
>
> Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/ 
> lucene/search/BooleanFilter.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/BooleanFilter.java (original)
> +++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/BooleanFilter.java Fri May 23 12:25:05 2008
> @@ -23,6 +23,10 @@
>
> import org.apache.lucene.index.IndexReader;
> import org.apache.lucene.search.BooleanClause.Occur;
> +import org.apache.lucene.util.DocIdBitSet;
> +import org.apache.lucene.util.OpenBitSet;
> +import org.apache.lucene.util.OpenBitSetDISI;
> +import org.apache.lucene.util.SortedVIntList;
>
> /**
> * A container Filter that allows Boolean composition of Filters.
> @@ -37,184 +41,167 @@
>
> public class BooleanFilter extends Filter
> {
> -	//ArrayList of SHOULD filters
> -	ArrayList shouldFilters = null;
> -	//ArrayList of NOT filters
> -	ArrayList notFilters = null;
> -	//ArrayList of MUST filters
> -	ArrayList mustFilters = null;
> -
> -	/**
> -	 * Returns the a BitSet representing the Boolean composition
> -	 * of the filters that have been added.
> -	 */
> -	
> -	public BitSet bits(IndexReader reader) throws IOException
> -	{
> -		//create a new bitSet
> -		BitSet returnBits = null;
> -		
> -		//SHOULD filters
> -		if (shouldFilters!=null)
> -		{
> -			returnBits = ((Filter)shouldFilters.get(0)).bits(reader);
> -//			avoid changing the original bitset - it may be cached
> -			returnBits=(BitSet) returnBits.clone();
> -			if (shouldFilters.size() > 1)
> -			{
> -				for (int i = 1; i < shouldFilters.size(); i++)
> -				{
> -					returnBits.or(((Filter)shouldFilters.get(i)).bits(reader));
> -				}
> -			}
> -		}
> -		
> -		//NOT filters
> -		if (notFilters!=null)
> -		{
> -			for (int i = 0; i < notFilters.size(); i++)
> -			{
> -				BitSet notBits=((Filter)notFilters.get(i)).bits(reader);
> -				if(returnBits==null)
> -				{
> -					returnBits=(BitSet) notBits.clone();					
> -					returnBits.flip(0,reader.maxDoc());
> -				}
> -				else
> -				{
> -					returnBits.andNot(notBits);
> -				}
> -			}
> -		}
> -		
> -		//MUST filters
> -		if (mustFilters!=null)
> -		{
> -			for (int i = 0; i < mustFilters.size(); i++)
> -			{
> -				BitSet mustBits=((Filter)mustFilters.get(i)).bits(reader);
> -				if(returnBits==null)
> -				{
> -					if(mustFilters.size()==1)
> -					{
> -						returnBits=mustBits;
> -						
> -					}
> -					else
> -					{
> -						//don't mangle the bitset
> -						returnBits=(BitSet) mustBits.clone();						
> -					}
> -				}
> -				else
> -				{
> -					returnBits.and(mustBits);
> -				}
> -			}
> -		}
> -		if(returnBits==null)
> -		{
> -			returnBits=new BitSet(reader.maxDoc());
> -		}
> -		return returnBits;
> -	}
> -	
> -	/**
> -	 * Adds a new FilterClause to the Boolean Filter container
> -	 * @param filterClause A FilterClause object containing a Filter  
> and an Occur parameter
> -	 */
> -	
> -	public void add(FilterClause filterClause)
> -	{
> -		if (filterClause.getOccur().equals(Occur.MUST))
> -		{
> -			if(mustFilters==null)
> -			{
> -				mustFilters=new ArrayList();
> -			}
> -			mustFilters.add(filterClause.getFilter());
> -		}
> -		if (filterClause.getOccur().equals(Occur.SHOULD))
> -		{
> -			if(shouldFilters==null)
> -			{
> -				shouldFilters=new ArrayList();
> -			}
> -			shouldFilters.add(filterClause.getFilter());
> -		}
> -		if (filterClause.getOccur().equals(Occur.MUST_NOT))
> -		{
> -			if(notFilters==null)
> -			{
> -				notFilters=new ArrayList();
> -			}
> -			notFilters.add(filterClause.getFilter());
> -		}
> -	}
> -
> -	public boolean equals(Object obj)
> -	{
> -		if(this == obj)
> -			return true;
> -		if((obj == null) || (obj.getClass() != this.getClass()))
> -				return false;
> -		BooleanFilter test = (BooleanFilter)obj;
> -		return (notFilters == test.notFilters||
> -					 (notFilters!= null && notFilters.equals(test.notFilters)))
> -				&&
> -			   (mustFilters == test.mustFilters||
> -					 (mustFilters!= null &&  
> mustFilters.equals(test.mustFilters)))				
> -					 &&
> -			   (shouldFilters == test.shouldFilters||
> -					 (shouldFilters!= null &&  
> shouldFilters.equals(test.shouldFilters)));
> -	}
> -
> -	public int hashCode()
> -	{
> -		int hash=7;
> -		hash = 31 * hash + (null == mustFilters ? 0 :  
> mustFilters.hashCode());
> -		hash = 31 * hash + (null == notFilters ? 0 :  
> notFilters.hashCode());
> -		hash = 31 * hash + (null == shouldFilters ? 0 :  
> shouldFilters.hashCode());
> -		return hash;
> -	}
> -	
> -	
> -		/** Prints a user-readable version of this query. */
> -	public String toString()
> -	{
> -		StringBuffer buffer = new StringBuffer();
> -
> -		buffer.append("BooleanFilter(");
> -
> -		appendFilters(shouldFilters, null, buffer);
> -		appendFilters(mustFilters, "+", buffer);
> -		appendFilters(notFilters, "-", buffer);
> -
> -		buffer.append(")");
> -
> -		return buffer.toString();
> -	}
> -	
> -	private void appendFilters(ArrayList filters, String occurString,
> -			StringBuffer buffer)
> -	{
> -		if (filters == null)
> -			return;
> -
> -		for (int i = 0; i < filters.size(); i++)
> -		{
> -			Filter filter = (Filter) filters.get(i);
> -			if (occurString != null)
> -			{
> -				buffer.append(occurString);
> -			}
> -
> -			buffer.append(filter);
> -
> -			if (i < filters.size() - 1)
> -			{
> -				buffer.append(' ');
> -			}
> -		}
> -	}		
> +  ArrayList shouldFilters = null;
> +  ArrayList notFilters = null;
> +  ArrayList mustFilters = null;
> +
> +  private DocIdSetIterator getDISI(ArrayList filters, int index,  
> IndexReader reader)
> +  throws IOException
> +  {
> +    return  
> ((Filter)filters.get(index)).getDocIdSet(reader).iterator();
> +  }
> +
> +  /**
> +   * Returns the a DocIdSetIterator representing the Boolean  
> composition
> +   * of the filters that have been added.
> +   */
> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
> +  {
> +    OpenBitSetDISI res = null;
> +
> +    if (shouldFilters != null) {
> +      for (int i = 0; i < shouldFilters.size(); i++) {
> +        if (res == null) {
> +          res = new OpenBitSetDISI(getDISI(shouldFilters, i,  
> reader), reader.maxDoc());
> +        } else {
> +          DocIdSet dis =  
> ((Filter)shouldFilters.get(i)).getDocIdSet(reader);
> +          if(dis instanceof OpenBitSet) {
> +            // optimized case for OpenBitSets
> +            res.or((OpenBitSet) dis);
> +          } else {
> +            res.inPlaceOr(getDISI(shouldFilters, i, reader));
> +          }
> +        }
> +      }
> +    }
> +
> +    if (notFilters!=null) {
> +      for (int i = 0; i < notFilters.size(); i++) {
> +        if (res == null) {
> +          res = new OpenBitSetDISI(getDISI(notFilters, i, reader),  
> reader.maxDoc());
> +          res.flip(0, reader.maxDoc()); // NOTE: may set bits on  
> deleted docs
> +        } else {
> +          DocIdSet dis =  
> ((Filter)notFilters.get(i)).getDocIdSet(reader);
> +          if(dis instanceof OpenBitSet) {
> +            // optimized case for OpenBitSets
> +            res.andNot((OpenBitSet) dis);
> +          } else {
> +            res.inPlaceNot(getDISI(notFilters, i, reader));
> +          }
> +        }
> +      }
> +    }
> +
> +    if (mustFilters!=null) {
> +      for (int i = 0; i < mustFilters.size(); i++) {
> +        if (res == null) {
> +          res = new OpenBitSetDISI(getDISI(mustFilters, i, reader),  
> reader.maxDoc());
> +        } else {
> +          DocIdSet dis =  
> ((Filter)mustFilters.get(i)).getDocIdSet(reader);
> +          if(dis instanceof OpenBitSet) {
> +            // optimized case for OpenBitSets
> +            res.and((OpenBitSet) dis);
> +          } else {
> +            res.inPlaceAnd(getDISI(mustFilters, i, reader));
> +          }
> +        }
> +      }
> +    }
> +
> +    if (res !=null)
> +      return finalResult(res, reader.maxDoc());
> +
> +    if (emptyDocIdSet == null)
> +      emptyDocIdSet = new OpenBitSetDISI(1);
> +
> +    return emptyDocIdSet;
> +  }
> +
> +  /** Provide a SortedVIntList when it is definitely smaller than  
> an OpenBitSet */
> +  protected DocIdSet finalResult(OpenBitSetDISI result, int  
> maxDocs) {
> +    return (result.cardinality() < (maxDocs / 9))
> +      ? (DocIdSet) new SortedVIntList(result)
> +      : (DocIdSet) result;
> +  }
> +
> +  private static DocIdSet emptyDocIdSet = null;
> +
> +  /**
> +  * Adds a new FilterClause to the Boolean Filter container
> +  * @param filterClause A FilterClause object containing a Filter  
> and an Occur parameter
> +  */
> +
> +  public void add(FilterClause filterClause)
> +  {
> +    if (filterClause.getOccur().equals(Occur.MUST)) {
> +      if (mustFilters==null) {
> +        mustFilters=new ArrayList();
> +      }
> +      mustFilters.add(filterClause.getFilter());
> +    }
> +    if (filterClause.getOccur().equals(Occur.SHOULD)) {
> +      if (shouldFilters==null) {
> +        shouldFilters=new ArrayList();
> +      }
> +      shouldFilters.add(filterClause.getFilter());
> +    }
> +    if (filterClause.getOccur().equals(Occur.MUST_NOT)) {
> +      if (notFilters==null) {
> +        notFilters=new ArrayList();
> +      }
> +      notFilters.add(filterClause.getFilter());
> +    }
> +  }
> +
> +  private boolean equalFilters(ArrayList filters1, ArrayList  
> filters2)
> +  {
> +     return (filters1 == filters2) ||
> +              ((filters1 != null) && filters1.equals(filters2));
> +  }
> +
> +  public boolean equals(Object obj)
> +  {
> +    if (this == obj)
> +      return true;
> +
> +    if ((obj == null) || (obj.getClass() != this.getClass()))
> +      return false;
> +
> +    BooleanFilter other = (BooleanFilter)obj;
> +    return equalFilters(notFilters, other.notFilters)
> +        && equalFilters(mustFilters, other.mustFilters)
> +        && equalFilters(shouldFilters, other.shouldFilters);
> +  }
> +
> +  public int hashCode()
> +  {
> +    int hash=7;
> +    hash = 31 * hash + (null == mustFilters ? 0 :  
> mustFilters.hashCode());
> +    hash = 31 * hash + (null == notFilters ? 0 :  
> notFilters.hashCode());
> +    hash = 31 * hash + (null == shouldFilters ? 0 :  
> shouldFilters.hashCode());
> +    return hash;
> +  }
> +
> +  /** Prints a user-readable version of this query. */
> +  public String toString()
> +  {
> +    StringBuffer buffer = new StringBuffer();
> +    buffer.append("BooleanFilter(");
> +    appendFilters(shouldFilters, "", buffer);
> +    appendFilters(mustFilters, "+", buffer);
> +    appendFilters(notFilters, "-", buffer);
> +    buffer.append(")");
> +    return buffer.toString();
> +  }
> +
> +  private void appendFilters(ArrayList filters, String occurString,  
> StringBuffer buffer)
> +  {
> +    if (filters != null) {
> +      for (int i = 0; i < filters.size(); i++) {
> +        buffer.append(' ');
> +        buffer.append(occurString);
> +        buffer.append(filters.get(i).toString());
> +      }
> +    }
> +  }
> }
>
> Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/ 
> lucene/search/DuplicateFilter.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/DuplicateFilter.java (original)
> +++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/DuplicateFilter.java Fri May 23 12:25:05 2008
> @@ -22,6 +22,7 @@
> import org.apache.lucene.index.Term;
> import org.apache.lucene.index.TermDocs;
> import org.apache.lucene.index.TermEnum;
> +import org.apache.lucene.util.OpenBitSet;
>
> public class DuplicateFilter extends Filter
> {
> @@ -66,7 +67,7 @@
> 		this.processingMode = processingMode;
> 	}
>
> -	public BitSet bits(IndexReader reader) throws IOException
> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
> 	{
> 		if(processingMode==PM_FAST_INVALIDATION)
> 		{
> @@ -78,10 +79,10 @@
> 		}
> 	}
> 	
> -	private BitSet correctBits(IndexReader reader) throws IOException
> +  private OpenBitSet correctBits(IndexReader reader) throws  
> IOException
> 	{
> 		
> -		BitSet bits=new BitSet(reader.maxDoc()); //assume all are INvalid
> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc()); //assume all  
> are INvalid
> 		Term startTerm=new Term(fieldName,"");
> 		TermEnum te = reader.terms(startTerm);
> 		if(te!=null)
> @@ -117,10 +118,10 @@
> 		return bits;
> 	}
> 	
> -	private BitSet fastBits(IndexReader reader) throws IOException
> +  private OpenBitSet fastBits(IndexReader reader) throws IOException
> 	{
> 		
> -		BitSet bits=new BitSet(reader.maxDoc());
> +    OpenBitSet bits=new OpenBitSet(reader.maxDoc());
> 		bits.set(0,reader.maxDoc()); //assume all are valid
> 		Term startTerm=new Term(fieldName,"");
> 		TermEnum te = reader.terms(startTerm);
> @@ -143,7 +144,7 @@
> 					do
> 					{
> 						lastDoc=td.doc();
> -						bits.set(lastDoc,false);
> +            bits.clear(lastDoc);
> 					}while(td.next());
> 					if(keepMode==KM_USE_LAST_OCCURRENCE)
> 					{
>
> Modified: lucene/java/trunk/contrib/queries/src/java/org/apache/ 
> lucene/search/TermsFilter.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/TermsFilter.java (original)
> +++ lucene/java/trunk/contrib/queries/src/java/org/apache/lucene/ 
> search/TermsFilter.java Fri May 23 12:25:05 2008
> @@ -26,6 +26,7 @@
> import org.apache.lucene.index.IndexReader;
> import org.apache.lucene.index.Term;
> import org.apache.lucene.index.TermDocs;
> +import org.apache.lucene.util.OpenBitSet;
>
> /**
> * Constructs a filter for docs matching any of the terms added to  
> this class.
> @@ -50,11 +51,11 @@
> 	}
>
> 	/* (non-Javadoc)
> -	 * @see  
> org 
> .apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader)
> +   * @see  
> org 
> .apache 
> .lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader)
> 	 */
> -	public BitSet bits(IndexReader reader) throws IOException
> +  public DocIdSet getDocIdSet(IndexReader reader) throws IOException
> 	{
> -		BitSet result=new BitSet(reader.maxDoc());
> +    OpenBitSet result=new OpenBitSet(reader.maxDoc());
>        TermDocs td = reader.termDocs();
>        try
>        {
>
> Modified: lucene/java/trunk/contrib/queries/src/test/org/apache/ 
> lucene/search/BooleanFilterTest.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/ 
> search/BooleanFilterTest.java (original)
> +++ lucene/java/trunk/contrib/queries/src/test/org/apache/lucene/ 
> search/BooleanFilterTest.java Fri May 23 12:25:05 2008
> @@ -32,6 +32,7 @@
> import org.apache.lucene.search.FilterClause;
> import org.apache.lucene.search.RangeFilter;
> import org.apache.lucene.store.RAMDirectory;
> +import org.apache.lucene.util.DocIdBitSet;
>
> import junit.framework.TestCase;
>
> @@ -66,100 +67,141 @@
> 		writer.addDocument(doc);
> 	}
> 	
> -	private Filter getRangeFilter(String field,String lowerPrice,  
> String upperPrice)
> +  private Filter getRangeFilter(String field,String lowerPrice,  
> String upperPrice, boolean old)
> 	{
> -		return new RangeFilter(field,lowerPrice,upperPrice,true,true);
> +    Filter f = new  
> RangeFilter(field,lowerPrice,upperPrice,true,true);
> +    if (old) {
> +      return new OldBitSetFilterWrapper(f);
> +    }
> +
> +    return f;
> 	}
> -	private TermsFilter getTermsFilter(String field,String text)
> +  private Filter getTermsFilter(String field,String text, boolean  
> old)
> 	{
> 		TermsFilter tf=new TermsFilter();
> 		tf.addTerm(new Term(field,text));
> +    if (old) {
> +      return new OldBitSetFilterWrapper(tf);
> +    }
> +
> 		return tf;
> 	}
> +
> +        private void tstFilterCard(String mes, int expected, Filter  
> filt)
> +        throws Throwable
> +        {
> +          DocIdSetIterator disi =  
> filt.getDocIdSet(reader).iterator();
> +          int actual = 0;
> +          while (disi.next()) {
> +            actual++;
> +          }
> +          assertEquals(mes, expected, actual);
> +        }
> +
> 		
> 	public void testShould() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new  
> FilterClause 
> (getTermsFilter("price","030"),BooleanClause.Occur.SHOULD));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Should retrieves only 1 doc",1,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("price","030",  
> old),BooleanClause.Occur.SHOULD));
> +      tstFilterCard("Should retrieves only 1 doc",1,booleanFilter);
> +    }
> 	}
> 	
> 	public void testShoulds() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","010",  
> "020"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","020",  
> "030"),BooleanClause.Occur.SHOULD));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds are Ored together",5,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","010", "020",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","020", "030",  
> old),BooleanClause.Occur.SHOULD));
> +      tstFilterCard("Shoulds are Ored together",5,booleanFilter);
> +    }
> 	}
> 	public void testShouldsAndMustNot() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","010",  
> "020"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","020",  
> "030"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getTermsFilter("inStock",  
> "N"),BooleanClause.Occur.MUST_NOT));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds Ored but AndNot",4,bits.cardinality());
> -
> -		booleanFilter.add(new FilterClause(getTermsFilter("inStock",  
> "Maybe"),BooleanClause.Occur.MUST_NOT));
> -		bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds Ored but AndNots",3,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","010", "020",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","020", "030",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock",  
> "N", old),BooleanClause.Occur.MUST_NOT));
> +      tstFilterCard("Shoulds Ored but AndNot",4,booleanFilter);
> +
> +      booleanFilter.add(new FilterClause(getTermsFilter("inStock",  
> "Maybe", old),BooleanClause.Occur.MUST_NOT));
> +      tstFilterCard("Shoulds Ored but AndNots",3,booleanFilter);
> +    }
> 		
> 	}
> 	public void testShouldsAndMust() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","010",  
> "020"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","020",  
> "030"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getTermsFilter("accessRights",  
> "admin"),BooleanClause.Occur.MUST));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds Ored but MUST",3,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","010", "020",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","020", "030",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("accessRights", "admin",  
> old),BooleanClause.Occur.MUST));
> +      tstFilterCard("Shoulds Ored but MUST",3,booleanFilter);
> +    }
> 	}
> 	public void testShouldsAndMusts() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","010",  
> "020"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","020",  
> "030"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getTermsFilter("accessRights",  
> "admin"),BooleanClause.Occur.MUST));
> -		booleanFilter.add(new  
> FilterClause(getRangeFilter("date","20040101",  
> "20041231"),BooleanClause.Occur.MUST));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds Ored but MUSTs ANDED",1,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","010", "020",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","020", "030",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("accessRights", "admin",  
> old),BooleanClause.Occur.MUST));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("date","20040101", "20041231",  
> old),BooleanClause.Occur.MUST));
> +      tstFilterCard("Shoulds Ored but MUSTs ANDED",1,booleanFilter);
> +    }
> 	}
> 	public void testShouldsAndMustsAndMustNot() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getRangeFilter("price","030",  
> "040"),BooleanClause.Occur.SHOULD));
> -		booleanFilter.add(new FilterClause(getTermsFilter("accessRights",  
> "admin"),BooleanClause.Occur.MUST));
> -		booleanFilter.add(new  
> FilterClause(getRangeFilter("date","20050101",  
> "20051231"),BooleanClause.Occur.MUST));
> -		booleanFilter.add(new  
> FilterClause 
> (getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("Shoulds Ored but MUSTs ANDED and MustNot", 
> 0,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("price","030", "040",  
> old),BooleanClause.Occur.SHOULD));
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("accessRights", "admin",  
> old),BooleanClause.Occur.MUST));
> +      booleanFilter.add(new  
> FilterClause(getRangeFilter("date","20050101", "20051231",  
> old),BooleanClause.Occur.MUST));
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("inStock","N",  
> old),BooleanClause.Occur.MUST_NOT));
> +      tstFilterCard("Shoulds Ored but MUSTs ANDED and MustNot", 
> 0,booleanFilter);
> +    }
> 	}
> 	
> 	public void testJustMust() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new FilterClause(getTermsFilter("accessRights",  
> "admin"),BooleanClause.Occur.MUST));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("MUST",3,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("accessRights", "admin",  
> old),BooleanClause.Occur.MUST));
> +      tstFilterCard("MUST",3,booleanFilter);
> +    }
> 	}
> 	public void testJustMustNot() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new  
> FilterClause 
> (getTermsFilter("inStock","N"),BooleanClause.Occur.MUST_NOT));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("MUST_NOT",4,bits.cardinality());
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
> +
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("inStock","N",  
> old),BooleanClause.Occur.MUST_NOT));
> +      tstFilterCard("MUST_NOT",4,booleanFilter);
> +    }
> 	}
> 	public void testMustAndMustNot() throws Throwable
> 	{
> -		BooleanFilter booleanFilter = new BooleanFilter();
> -		booleanFilter.add(new  
> FilterClause(getTermsFilter("inStock","N"),BooleanClause.Occur.MUST));
> -		booleanFilter.add(new  
> FilterClause 
> (getTermsFilter("price","030"),BooleanClause.Occur.MUST_NOT));
> -		BitSet bits = booleanFilter.bits(reader);
> -		assertEquals("MUST_NOT wins over MUST for same docs", 
> 0,bits.cardinality());
> -	}
> +    for (int i = 0; i < 2; i++) {
> +      boolean old = (i==0);
>
> -	
> -	
> +      BooleanFilter booleanFilter = new BooleanFilter();
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("inStock","N",  
> old),BooleanClause.Occur.MUST));
> +      booleanFilter.add(new  
> FilterClause(getTermsFilter("price","030",  
> old),BooleanClause.Occur.MUST_NOT));
> +      tstFilterCard("MUST_NOT wins over MUST for same docs", 
> 0,booleanFilter);
> +    }
> +	}
> }
>
> Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ 
> ParallelMultiSearcher.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/ParallelMultiSearcher.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/src/java/org/apache/lucene/search/ 
> ParallelMultiSearcher.java (original)
> +++ lucene/java/trunk/src/java/org/apache/lucene/search/ 
> ParallelMultiSearcher.java Fri May 23 12:25:05 2008
> @@ -150,8 +150,8 @@
>
>  /** Lower-level search API.
>   *
> -   * <p>{@link HitCollector#collect(int,float)} is called for every  
> non-zero
> -   * scoring document.
> +   * <p>{@link HitCollector#collect(int,float)} is called for every  
> matching
> +   * document.
>   *
>   * <p>Applications should only use this if they need <i>all</i> of  
> the
>   * matching documents.  The high-level search API ({@link
>
> Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searchable.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searchable.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searchable.java (original)
> +++ lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searchable.java Fri May 23 12:25:05 2008
> @@ -33,7 +33,7 @@
> *
> * <p>Queries, filters and sort criteria are designed to be compact  
> so that
> * they may be efficiently passed to a remote index, with only the  
> top-scoring
> - * hits being returned, rather than every non-zero scoring hit.
> + * hits being returned, rather than every matching hit.
> */
> public interface Searchable extends java.rmi.Remote {
>  /** Lower-level search API.
>
> Modified: lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searcher.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/search/Searcher.java?rev=659635&r1=659634&r2=659635&view=diff
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searcher.java (original)
> +++ lucene/java/trunk/src/java/org/apache/lucene/search/ 
> Searcher.java Fri May 23 12:25:05 2008
> @@ -88,8 +88,8 @@
>
>  /** Lower-level search API.
>   *
> -   * <p>{@link HitCollector#collect(int,float)} is called for every  
> non-zero
> -   * scoring document.
> +   * <p>{@link HitCollector#collect(int,float)} is called for every  
> matching
> +   * document.
>   *
>   * <p>Applications should only use this if they need <i>all</i> of  
> the
>   * matching documents.  The high-level search API ({@link
> @@ -107,8 +107,8 @@
>
>  /** Lower-level search API.
>   *
> -   * <p>{@link HitCollector#collect(int,float)} is called for every  
> non-zero
> -   * scoring document.
> +   * <p>{@link HitCollector#collect(int,float)} is called for every  
> matching
> +   * document.
>   * <br>HitCollector-based access to remote indexes is discouraged.
>   *
>   * <p>Applications should only use this if they need <i>all</i> of  
> the
>
> Added: lucene/java/trunk/src/java/org/apache/lucene/util/ 
> OpenBitSetDISI.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/java/org/apache/lucene/util/OpenBitSetDISI.java?rev=659635&view=auto
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/src/java/org/apache/lucene/util/ 
> OpenBitSetDISI.java (added)
> +++ lucene/java/trunk/src/java/org/apache/lucene/util/ 
> OpenBitSetDISI.java Fri May 23 12:25:05 2008
> @@ -0,0 +1,101 @@
> +package org.apache.lucene.util;
> +
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed  
> with
> + * this work for additional information regarding copyright  
> ownership.
> + * The ASF licenses this file to You under the Apache License,  
> Version 2.0
> + * (the "License"); you may not use this file except in compliance  
> with
> + * the License.  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,  
> software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
> implied.
> + * See the License for the specific language governing permissions  
> and
> + * limitations under the License.
> + */
> +
> +import java.io.IOException;
> +import org.apache.lucene.search.DocIdSetIterator;
> +
> +public class OpenBitSetDISI extends OpenBitSet {
> +
> +  /** Construct an OpenBitSetDISI with its bits set
> +   * from the doc ids of the given DocIdSetIterator.
> +   * Also give a maximum size one larger than the largest doc id  
> for which a
> +   * bit may ever be set on this OpenBitSetDISI.
> +   */
> +  public OpenBitSetDISI(DocIdSetIterator disi, int maxSize) throws  
> IOException {
> +    super(maxSize);
> +    inPlaceOr(disi);
> +  }
> +
> +  /** Construct an OpenBitSetDISI with no bits set, and a given  
> maximum size
> +   * one larger than the largest doc id for which a bit may ever be  
> set
> +   * on this OpenBitSetDISI.
> +   */
> +  public OpenBitSetDISI(int maxSize) {
> +    super(maxSize);
> +  }
> +
> +  /**
> +   * Perform an inplace OR with the doc ids from a given  
> DocIdSetIterator,
> +   * setting the bit for each such doc id.
> +   * These doc ids should be smaller than the maximum size passed  
> to the
> +   * constructor.
> +   */
> +  public void inPlaceOr(DocIdSetIterator disi) throws IOException {
> +    while (disi.next() && (disi.doc() < size())) {
> +      fastSet(disi.doc());
> +    }
> +  }
> +
> +  /**
> +   * Perform an inplace AND with the doc ids from a given  
> DocIdSetIterator,
> +   * leaving only the bits set for which the doc ids are in common.
> +   * These doc ids should be smaller than the maximum size passed  
> to the
> +   * constructor.
> +   */
> +  public void inPlaceAnd(DocIdSetIterator disi) throws IOException {
> +    int index = nextSetBit(0);
> +    int lastNotCleared = -1;
> +    while ((index != -1) && disi.skipTo(index)) {
> +      while ((index != -1) && (index < disi.doc())) {
> +        fastClear(index);
> +        index = nextSetBit(index + 1);
> +      }
> +      if (index == disi.doc()) {
> +        lastNotCleared = index;
> +        index++;
> +      }
> +      assert (index == -1) || (index > disi.doc());
> +    }
> +    clear(lastNotCleared+1, size());
> +  }
> +
> +  /**
> +   * Perform an inplace NOT with the doc ids from a given  
> DocIdSetIterator,
> +   * clearing all the bits for each such doc id.
> +   * These doc ids should be smaller than the maximum size passed  
> to the
> +   * constructor.
> +   */
> +  public void inPlaceNot(DocIdSetIterator disi) throws IOException {
> +    while (disi.next() && (disi.doc() < size())) {
> +      fastClear(disi.doc());
> +    }
> +  }
> +
> +  /**
> +   * Perform an inplace XOR with the doc ids from a given  
> DocIdSetIterator,
> +   * flipping all the bits for each such doc id.
> +   * These doc ids should be smaller than the maximum size passed  
> to the
> +   * constructor.
> +   */
> +  public void inPlaceXor(DocIdSetIterator disi) throws IOException {
> +    while (disi.next() && (disi.doc() < size())) {
> +      fastFlip(disi.doc());
> +    }
> +  }
> +}
>
> Added: lucene/java/trunk/src/test/org/apache/lucene/search/ 
> OldBitSetFilterWrapper.java
> URL: http://svn.apache.org/viewvc/lucene/java/trunk/src/test/org/apache/lucene/search/OldBitSetFilterWrapper.java?rev=659635&view=auto
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- lucene/java/trunk/src/test/org/apache/lucene/search/ 
> OldBitSetFilterWrapper.java (added)
> +++ lucene/java/trunk/src/test/org/apache/lucene/search/ 
> OldBitSetFilterWrapper.java Fri May 23 12:25:05 2008
> @@ -0,0 +1,48 @@
> +package org.apache.lucene.search;
> +
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed  
> with
> + * this work for additional information regarding copyright  
> ownership.
> + * The ASF licenses this file to You under the Apache License,  
> Version 2.0
> + * (the "License"); you may not use this file except in compliance  
> with
> + * the License.  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,  
> software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or  
> implied.
> + * See the License for the specific language governing permissions  
> and
> + * limitations under the License.
> + */
> +
> +import java.io.IOException;
> +import java.util.BitSet;
> +
> +import org.apache.lucene.index.IndexReader;
> +
> +  /**
> +   *  Helper class used for testing compatibility with old BitSet- 
> based filters.
> +   *  Does not override {@link Filter#getDocIdSet(IndexReader)} and  
> thus ensures
> +   *  that {@link #bits(IndexReader)} is called.
> +   *
> +   *  @deprecated This class will be removed together with the
> +   *  {@link Filter#bits(IndexReader)} method in Lucene 3.0.
> +   */
> +  public class OldBitSetFilterWrapper extends Filter {
> +    private Filter filter;
> +
> +    public OldBitSetFilterWrapper(Filter filter) {
> +      this.filter = filter;
> +    }
> +
> +    public BitSet bits(IndexReader reader) throws IOException {
> +      BitSet bits = new BitSet(reader.maxDoc());
> +      DocIdSetIterator it = filter.getDocIdSet(reader).iterator();
> +      while(it.next()) {
> +        bits.set(it.doc());
> +      }
> +      return bits;
> +    }
> +  }
>
>

--------------------------
Grant Ingersoll
http://www.lucidimagination.com

Lucene Helpful Hints:
http://wiki.apache.org/lucene-java/BasicsOfPerformance
http://wiki.apache.org/lucene-java/LuceneFAQ








---------------------------------------------------------------------
To unsubscribe, e-mail: java-dev-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-dev-help@lucene.apache.org