From c29b449d427dc7f03f285e2054e56d93364d0806 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 5 Jan 2011 18:45:25 +0000 Subject: [PATCH 001/252] LUCENE-2837: fixup jdocs git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055575 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/document/AbstractField.java | 2 +- .../org/apache/lucene/document/Document.java | 3 ++- .../org/apache/lucene/document/Fieldable.java | 2 +- .../org/apache/lucene/index/IndexReader.java | 10 ++++----- .../apache/lucene/search/BoostAttribute.java | 2 +- .../org/apache/lucene/search/Collector.java | 2 +- .../org/apache/lucene/search/FieldDoc.java | 2 +- .../lucene/search/FieldValueHitQueue.java | 2 +- .../apache/lucene/search/IndexSearcher.java | 15 +++++++------ .../MaxNonCompetitiveBoostAttribute.java | 4 ++-- .../apache/lucene/search/MultiTermQuery.java | 2 +- .../org/apache/lucene/search/ScoreDoc.java | 2 +- .../org/apache/lucene/search/Similarity.java | 22 +++++++++---------- .../lucene/search/SimilarityDelegator.java | 2 +- .../java/org/apache/lucene/search/Sort.java | 4 ++-- .../org/apache/lucene/search/TopDocs.java | 4 ++-- .../apache/lucene/search/TopFieldDocs.java | 2 +- .../java/org/apache/lucene/search/Weight.java | 4 ++-- .../org/apache/lucene/search/package.html | 4 ++-- 19 files changed, 46 insertions(+), 44 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/document/AbstractField.java b/lucene/src/java/org/apache/lucene/document/AbstractField.java index 8f025aca33c..35287d882d4 100755 --- a/lucene/src/java/org/apache/lucene/document/AbstractField.java +++ b/lucene/src/java/org/apache/lucene/document/AbstractField.java @@ -99,7 +99,7 @@ public abstract class AbstractField implements Fieldable { * *

Note: this value is not stored directly with the document in the index. * Documents returned from {@link org.apache.lucene.index.IndexReader#document(int)} and - * {@link org.apache.lucene.search.Searcher#doc(int)} may thus not have the same value present as when + * {@link org.apache.lucene.search.IndexSearcher#doc(int)} may thus not have the same value present as when * this field was indexed. * * @see #setBoost(float) diff --git a/lucene/src/java/org/apache/lucene/document/Document.java b/lucene/src/java/org/apache/lucene/document/Document.java index 1dea49d465c..58e7a7ee3c3 100644 --- a/lucene/src/java/org/apache/lucene/document/Document.java +++ b/lucene/src/java/org/apache/lucene/document/Document.java @@ -18,6 +18,7 @@ package org.apache.lucene.document; */ import java.util.*; // for javadoc +import org.apache.lucene.search.IndexSearcher; // for javadoc import org.apache.lucene.search.ScoreDoc; // for javadoc import org.apache.lucene.index.IndexReader; // for javadoc @@ -165,7 +166,7 @@ public final class Document implements java.io.Serializable { /** Returns a List of all the fields in a document. *

Note that fields which are not {@link Fieldable#isStored() stored} are * not available in documents retrieved from the - * index, e.g. {@link Searcher#doc(int)} or {@link + * index, e.g. {@link IndexSearcher#doc(int)} or {@link * IndexReader#document(int)}. */ public final List getFields() { diff --git a/lucene/src/java/org/apache/lucene/document/Fieldable.java b/lucene/src/java/org/apache/lucene/document/Fieldable.java index 3d753d76e91..561d4df8140 100755 --- a/lucene/src/java/org/apache/lucene/document/Fieldable.java +++ b/lucene/src/java/org/apache/lucene/document/Fieldable.java @@ -64,7 +64,7 @@ public interface Fieldable extends Serializable { * *

Note: this value is not stored directly with the document in the index. * Documents returned from {@link org.apache.lucene.index.IndexReader#document(int)} and - * {@link org.apache.lucene.search.Searcher#doc(int)} may thus not have the same value present as when + * {@link org.apache.lucene.search.IndexSearcher#doc(int)} may thus not have the same value present as when * this field was indexed. * * @see #setBoost(float) diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index 2e3a93ebaac..cc561d6e43b 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -301,7 +301,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader * @param termInfosIndexDivisor Subsamples which indexed * terms are loaded into RAM. This has the same effect as {@link - * IndexWriter#setTermIndexInterval} except that setting + * IndexWriterConfig#setTermIndexInterval} except that setting * must be done at indexing time while this setting can be * set per reader. When set to N, then one in every * N*termIndexInterval terms in the index is loaded into @@ -351,7 +351,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader * @param termInfosIndexDivisor Subsamples which indexed * terms are loaded into RAM. This has the same effect as {@link - * IndexWriter#setTermIndexInterval} except that setting + * IndexWriterConfig#setTermIndexInterval} except that setting * must be done at indexing time while this setting can be * set per reader. When set to N, then one in every * N*termIndexInterval terms in the index is loaded into @@ -380,7 +380,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader * @param termInfosIndexDivisor Subsamples which indexed * terms are loaded into RAM. This has the same effect as {@link - * IndexWriter#setTermIndexInterval} except that setting + * IndexWriterConfig#setTermIndexInterval} except that setting * must be done at indexing time while this setting can be * set per reader. When set to N, then one in every * N*termIndexInterval terms in the index is loaded into @@ -413,7 +413,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * @param readOnly true if no changes (deletions, norms) will be made with this IndexReader * @param termInfosIndexDivisor Subsamples which indexed * terms are loaded into RAM. This has the same effect as {@link - * IndexWriter#setTermIndexInterval} except that setting + * IndexWriterConfig#setTermIndexInterval} except that setting * must be done at indexing time while this setting can be * set per reader. When set to N, then one in every * N*termIndexInterval terms in the index is loaded into @@ -542,7 +542,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * file descriptors, CPU time) will be consumed.

* *

For lower latency on reopening a reader, you should - * call {@link #setMergedSegmentWarmer} to + * call {@link IndexWriterConfig#setMergedSegmentWarmer} to * pre-warm a newly merged segment before it's committed * to the index. This is important for minimizing * index-to-search delay after a large merge.

diff --git a/lucene/src/java/org/apache/lucene/search/BoostAttribute.java b/lucene/src/java/org/apache/lucene/search/BoostAttribute.java index 93a2d3916bf..e9187a85445 100644 --- a/lucene/src/java/org/apache/lucene/search/BoostAttribute.java +++ b/lucene/src/java/org/apache/lucene/search/BoostAttribute.java @@ -21,7 +21,7 @@ import org.apache.lucene.util.Attribute; import org.apache.lucene.util.AttributeSource; // javadocs only import org.apache.lucene.index.TermsEnum; // javadocs only -/** Add this {@link Attribute} to a {@link TermsEnum} returned by {@link MultiTermQuery#getTermsEnum(IndexReader,AttributeSource)} +/** Add this {@link Attribute} to a {@link TermsEnum} returned by {@link MultiTermQuery#getTermsEnum(Terms,AttributeSource)} * and update the boost on each returned term. This enables to control the boost factor * for each matching term in {@link MultiTermQuery#SCORING_BOOLEAN_QUERY_REWRITE} or * {@link TopTermsRewrite} mode. diff --git a/lucene/src/java/org/apache/lucene/search/Collector.java b/lucene/src/java/org/apache/lucene/search/Collector.java index e2514887930..57d7b061e2d 100644 --- a/lucene/src/java/org/apache/lucene/search/Collector.java +++ b/lucene/src/java/org/apache/lucene/search/Collector.java @@ -136,7 +136,7 @@ public abstract class Collector { * *

* Note: This is called in an inner search loop. For good search performance, - * implementations of this method should not call {@link Searcher#doc(int)} or + * implementations of this method should not call {@link IndexSearcher#doc(int)} or * {@link org.apache.lucene.index.IndexReader#document(int)} on every hit. * Doing so can slow searches by an order of magnitude or more. */ diff --git a/lucene/src/java/org/apache/lucene/search/FieldDoc.java b/lucene/src/java/org/apache/lucene/search/FieldDoc.java index faf54a079ea..e6a5b1a34b1 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldDoc.java +++ b/lucene/src/java/org/apache/lucene/search/FieldDoc.java @@ -43,7 +43,7 @@ public class FieldDoc extends ScoreDoc { * Sort object. Each Object will be either an Integer, Float or String, * depending on the type of values in the terms of the original field. * @see Sort - * @see Searcher#search(Query,Filter,int,Sort) + * @see IndexSearcher#search(Query,Filter,int,Sort) */ public Comparable[] fields; diff --git a/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java b/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java index 13ecb8672de..10f85620cf6 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java +++ b/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java @@ -28,7 +28,7 @@ import org.apache.lucene.util.PriorityQueue; * * @lucene.experimental * @since 2.9 - * @see Searcher#search(Query,Filter,int,Sort) + * @see IndexSearcher#search(Query,Filter,int,Sort) * @see FieldCache */ public abstract class FieldValueHitQueue extends PriorityQueue { diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index cc0dc763c08..c81b3ca9f85 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -37,6 +37,7 @@ import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.NIOFSDirectory; // javadoc import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.ThreadInterruptedException; @@ -284,7 +285,7 @@ public class IndexSearcher { * *

Applications should only use this if they need all of the * matching documents. The high-level search API ({@link - * Searcher#search(Query, Filter, int)}) is usually more efficient, as it skips + * IndexSearcher#search(Query, Filter, int)}) is usually more efficient, as it skips * non-high-scoring hits. * * @param query to match documents @@ -303,7 +304,7 @@ public class IndexSearcher { * *

Applications should only use this if they need all of the * matching documents. The high-level search API ({@link - * Searcher#search(Query, int)}) is usually more efficient, as it skips + * IndexSearcher#search(Query, int)}) is usually more efficient, as it skips * non-high-scoring hits. *

Note: The score passed to this method is a raw score. * In other words, the score will not necessarily be a float whose value is @@ -347,8 +348,8 @@ public class IndexSearcher { /** Expert: Low-level search implementation. Finds the top n * hits for query, applying filter if non-null. * - *

Applications should usually call {@link Searcher#search(Query,int)} or - * {@link Searcher#search(Query,Filter,int)} instead. + *

Applications should usually call {@link IndexSearcher#search(Query,int)} or + * {@link IndexSearcher#search(Query,Filter,int)} instead. * @throws BooleanQuery.TooManyClauses */ protected TopDocs search(Weight weight, Filter filter, int nDocs) throws IOException { @@ -394,7 +395,7 @@ public class IndexSearcher { * sort. * *

Applications should usually call {@link - * Searcher#search(Query,Filter,int,Sort)} instead. + * IndexSearcher#search(Query,Filter,int,Sort)} instead. * * @throws BooleanQuery.TooManyClauses */ @@ -464,7 +465,7 @@ public class IndexSearcher { * *

* Applications should only use this if they need all of the matching - * documents. The high-level search API ({@link Searcher#search(Query,int)}) is + * documents. The high-level search API ({@link IndexSearcher#search(Query,int)}) is * usually more efficient, as it skips non-high-scoring hits. * * @param weight @@ -576,7 +577,7 @@ public class IndexSearcher { * and, for good performance, should not be displayed with every hit. * Computing an explanation is as expensive as executing the query over the * entire index. - *

Applications should call {@link Searcher#explain(Query, int)}. + *

Applications should call {@link IndexSearcher#explain(Query, int)}. * @throws BooleanQuery.TooManyClauses */ protected Explanation explain(Weight weight, int doc) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/search/MaxNonCompetitiveBoostAttribute.java b/lucene/src/java/org/apache/lucene/search/MaxNonCompetitiveBoostAttribute.java index 56505f0754e..4fd168e6b10 100644 --- a/lucene/src/java/org/apache/lucene/search/MaxNonCompetitiveBoostAttribute.java +++ b/lucene/src/java/org/apache/lucene/search/MaxNonCompetitiveBoostAttribute.java @@ -22,13 +22,13 @@ import org.apache.lucene.util.AttributeSource; // javadocs only import org.apache.lucene.util.BytesRef; /** Add this {@link Attribute} to a fresh {@link AttributeSource} before calling - * {@link MultiTermQuery#getTermsEnum(IndexReader,AttributeSource)}. + * {@link MultiTermQuery#getTermsEnum(Terms,AttributeSource)}. * {@link FuzzyQuery} is using this to control its internal behaviour * to only return competitive terms. *

Please note: This attribute is intended to be added by the {@link MultiTermQuery.RewriteMethod} * to an empty {@link AttributeSource} that is shared for all segments * during query rewrite. This attribute source is passed to all segment enums - * on {@link MultiTermQuery#getTermsEnum(IndexReader,AttributeSource)}. + * on {@link MultiTermQuery#getTermsEnum(Terms,AttributeSource)}. * {@link TopTermsRewrite} uses this attribute to * inform all enums about the current boost, that is not competitive. * @lucene.internal diff --git a/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java b/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java index a3a1fe70e24..a108360cea0 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java @@ -33,7 +33,7 @@ import org.apache.lucene.util.AttributeSource; * FilteredTermsEnum} enumeration. * *

This query cannot be used directly; you must subclass - * it and define {@link #getTermsEnum(IndexReader,AttributeSource)} to provide a {@link + * it and define {@link #getTermsEnum(Terms,AttributeSource)} to provide a {@link * FilteredTermsEnum} that iterates through the terms to be * matched. * diff --git a/lucene/src/java/org/apache/lucene/search/ScoreDoc.java b/lucene/src/java/org/apache/lucene/search/ScoreDoc.java index 759f71afaf7..f2828d509a8 100644 --- a/lucene/src/java/org/apache/lucene/search/ScoreDoc.java +++ b/lucene/src/java/org/apache/lucene/search/ScoreDoc.java @@ -24,7 +24,7 @@ public class ScoreDoc implements java.io.Serializable { public float score; /** Expert: A hit document's number. - * @see Searcher#doc(int) + * @see IndexSearcher#doc(int) */ public int doc; diff --git a/lucene/src/java/org/apache/lucene/search/Similarity.java b/lucene/src/java/org/apache/lucene/search/Similarity.java index a9916eca955..81b1a810047 100644 --- a/lucene/src/java/org/apache/lucene/search/Similarity.java +++ b/lucene/src/java/org/apache/lucene/search/Similarity.java @@ -521,8 +521,8 @@ import org.apache.lucene.util.SmallFloat; * * * @see #setDefault(Similarity) - * @see org.apache.lucene.index.IndexWriter#setSimilarity(Similarity) - * @see Searcher#setSimilarity(Similarity) + * @see org.apache.lucene.index.IndexWriterConfig#setSimilarity(Similarity) + * @see IndexSearcher#setSimilarity(Similarity) */ public abstract class Similarity implements Serializable { @@ -535,8 +535,8 @@ public abstract class Similarity implements Serializable { /** Set the default Similarity implementation used by indexing and search * code. * - * @see Searcher#setSimilarity(Similarity) - * @see org.apache.lucene.index.IndexWriter#setSimilarity(Similarity) + * @see IndexSearcher#setSimilarity(Similarity) + * @see org.apache.lucene.index.IndexWriterConfig#setSimilarity(Similarity) */ public static void setDefault(Similarity similarity) { Similarity.defaultImpl = similarity; @@ -547,8 +547,8 @@ public abstract class Similarity implements Serializable { * *

This is initially an instance of {@link DefaultSimilarity}. * - * @see Searcher#setSimilarity(Similarity) - * @see org.apache.lucene.index.IndexWriter#setSimilarity(Similarity) + * @see IndexSearcher#setSimilarity(Similarity) + * @see org.apache.lucene.index.IndexWriterConfig#setSimilarity(Similarity) */ public static Similarity getDefault() { return Similarity.defaultImpl; @@ -709,11 +709,11 @@ public abstract class Similarity implements Serializable { * idf(docFreq, searcher.maxDoc()); * * - * Note that {@link Searcher#maxDoc()} is used instead of + * Note that {@link IndexSearcher#maxDoc()} is used instead of * {@link org.apache.lucene.index.IndexReader#numDocs() IndexReader#numDocs()} because also - * {@link Searcher#docFreq(Term)} is used, and when the latter - * is inaccurate, so is {@link Searcher#maxDoc()}, and in the same direction. - * In addition, {@link Searcher#maxDoc()} is more efficient to compute + * {@link IndexSearcher#docFreq(Term)} is used, and when the latter + * is inaccurate, so is {@link IndexSearcher#maxDoc()}, and in the same direction. + * In addition, {@link IndexSearcher#maxDoc()} is more efficient to compute * * @param term the term in question * @param searcher the document collection being searched @@ -740,7 +740,7 @@ public abstract class Similarity implements Serializable { /** * This method forwards to {@link - * #idfExplain(Term,Searcher,int)} by passing + * #idfExplain(Term,IndexSearcher,int)} by passing * searcher.docFreq(term) as the docFreq. */ public IDFExplanation idfExplain(final Term term, final IndexSearcher searcher) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java b/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java index b83800c33e4..d68e18aba36 100644 --- a/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java +++ b/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java @@ -20,7 +20,7 @@ import org.apache.lucene.index.FieldInvertState; */ /** Expert: Delegating scoring implementation. Useful in {@link - * Query#getSimilarity(Searcher)} implementations, to override only certain + * Query#getSimilarity(IndexSearcher)} implementations, to override only certain * methods of a Searcher's Similarity implementation.. */ public class SimilarityDelegator extends Similarity { diff --git a/lucene/src/java/org/apache/lucene/search/Sort.java b/lucene/src/java/org/apache/lucene/search/Sort.java index 9c2bd0e257d..7969c991609 100644 --- a/lucene/src/java/org/apache/lucene/search/Sort.java +++ b/lucene/src/java/org/apache/lucene/search/Sort.java @@ -103,7 +103,7 @@ implements Serializable { /** * Represents sorting by computed relevance. Using this sort criteria returns * the same results as calling - * {@link Searcher#search(Query,int) Searcher#search()}without a sort criteria, + * {@link IndexSearcher#search(Query,int) IndexSearcher#search()}without a sort criteria, * only with slightly more overhead. */ public static final Sort RELEVANCE = new Sort(); @@ -116,7 +116,7 @@ implements Serializable { /** * Sorts by computed relevance. This is the same sort criteria as calling - * {@link Searcher#search(Query,int) Searcher#search()}without a sort criteria, + * {@link IndexSearcher#search(Query,int) IndexSearcher#search()}without a sort criteria, * only with slightly more overhead. */ public Sort() { diff --git a/lucene/src/java/org/apache/lucene/search/TopDocs.java b/lucene/src/java/org/apache/lucene/search/TopDocs.java index c185fbe1a82..6d14f88bb20 100644 --- a/lucene/src/java/org/apache/lucene/search/TopDocs.java +++ b/lucene/src/java/org/apache/lucene/search/TopDocs.java @@ -18,8 +18,8 @@ package org.apache.lucene.search; */ /** Represents hits returned by {@link - * Searcher#search(Query,Filter,int)} and {@link - * Searcher#search(Query,int)}. */ + * IndexSearcher#search(Query,Filter,int)} and {@link + * IndexSearcher#search(Query,int)}. */ public class TopDocs implements java.io.Serializable { /** The total number of hits for the query. */ diff --git a/lucene/src/java/org/apache/lucene/search/TopFieldDocs.java b/lucene/src/java/org/apache/lucene/search/TopFieldDocs.java index ec9750f64cf..fc4c2331c3b 100644 --- a/lucene/src/java/org/apache/lucene/search/TopFieldDocs.java +++ b/lucene/src/java/org/apache/lucene/search/TopFieldDocs.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; /** Represents hits returned by {@link - * Searcher#search(Query,Filter,int,Sort)}. + * IndexSearcher#search(Query,Filter,int,Sort)}. */ public class TopFieldDocs extends TopDocs { diff --git a/lucene/src/java/org/apache/lucene/search/Weight.java b/lucene/src/java/org/apache/lucene/search/Weight.java index 77a56bf8997..1da8f5ef436 100644 --- a/lucene/src/java/org/apache/lucene/search/Weight.java +++ b/lucene/src/java/org/apache/lucene/search/Weight.java @@ -27,14 +27,14 @@ import org.apache.lucene.index.IndexReader; *

* The purpose of {@link Weight} is to ensure searching does not * modify a {@link Query}, so that a {@link Query} instance can be reused.
- * {@link Searcher} dependent state of the query should reside in the + * {@link IndexSearcher} dependent state of the query should reside in the * {@link Weight}.
* {@link IndexReader} dependent state should reside in the {@link Scorer}. *

* A Weight is used in the following way: *

    *
  1. A Weight is constructed by a top-level query, given a - * Searcher ({@link Query#createWeight(Searcher)}). + * IndexSearcher ({@link Query#createWeight(IndexSearcher)}). *
  2. The {@link #sumOfSquaredWeights()} method is called on the * Weight to compute the query normalization factor * {@link Similarity#queryNorm(float)} of the query clauses contained in the diff --git a/lucene/src/java/org/apache/lucene/search/package.html b/lucene/src/java/org/apache/lucene/search/package.html index 133c95331dd..a11d84e5171 100644 --- a/lucene/src/java/org/apache/lucene/search/package.html +++ b/lucene/src/java/org/apache/lucene/search/package.html @@ -36,8 +36,8 @@ Code to search indices. Search over indices. Applications usually call {@link -org.apache.lucene.search.Searcher#search(Query,int)} or {@link -org.apache.lucene.search.Searcher#search(Query,Filter,int)}. +org.apache.lucene.search.IndexSearcher#search(Query,int)} or {@link +org.apache.lucene.search.IndexSearcher#search(Query,Filter,int)}.

    From acd9519e59f17da551cad75f28484cc615604843 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 5 Jan 2011 19:27:51 +0000 Subject: [PATCH 002/252] LUCENE-2837: small code cleanup git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055595 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/search/IndexSearcher.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index c81b3ca9f85..25f552c5fdf 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -371,7 +371,7 @@ public class IndexSearcher { for (int i = 0; i < subReaders.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, i, docStarts)); + new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, docStarts[i])); } int totalHits = 0; @@ -440,7 +440,7 @@ public class IndexSearcher { final ExecutionHelper runner = new ExecutionHelper(executor); for (int i = 0; i < subReaders.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, i, docStarts)); + new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, docStarts[i])); } int totalHits = 0; float maxScore = Float.NEGATIVE_INFINITY; @@ -626,20 +626,18 @@ public class IndexSearcher { private final Weight weight; private final Filter filter; private final int nDocs; - private final int i; private final HitQueue hq; - private final int[] starts; + private final int docBase; public MultiSearcherCallableNoSort(Lock lock, IndexSearcher searchable, Weight weight, - Filter filter, int nDocs, HitQueue hq, int i, int[] starts) { + Filter filter, int nDocs, HitQueue hq, int docBase) { this.lock = lock; this.searchable = searchable; this.weight = weight; this.filter = filter; this.nDocs = nDocs; this.hq = hq; - this.i = i; - this.starts = starts; + this.docBase = docBase; } public TopDocs call() throws IOException { @@ -647,7 +645,7 @@ public class IndexSearcher { final ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq final ScoreDoc scoreDoc = scoreDocs[j]; - scoreDoc.doc += starts[i]; // convert doc + scoreDoc.doc += docBase; // convert doc //it would be so nice if we had a thread-safe insert lock.lock(); try { @@ -672,21 +670,19 @@ public class IndexSearcher { private final Weight weight; private final Filter filter; private final int nDocs; - private final int i; private final FieldDocSortedHitQueue hq; - private final int[] starts; + private final int docBase; private final Sort sort; public MultiSearcherCallableWithSort(Lock lock, IndexSearcher searchable, Weight weight, - Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort, int i, int[] starts) { + Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort, int docBase) { this.lock = lock; this.searchable = searchable; this.weight = weight; this.filter = filter; this.nDocs = nDocs; this.hq = hq; - this.i = i; - this.starts = starts; + this.docBase = docBase; this.sort = sort; } @@ -700,7 +696,7 @@ public class IndexSearcher { // iterate over the score docs and change their fields value for (int j2 = 0; j2 < docs.scoreDocs.length; j2++) { FieldDoc fd = (FieldDoc) docs.scoreDocs[j2]; - fd.fields[j] = Integer.valueOf(((Integer) fd.fields[j]).intValue() + starts[i]); + fd.fields[j] = Integer.valueOf(((Integer) fd.fields[j]).intValue() + docBase); } break; } @@ -716,7 +712,7 @@ public class IndexSearcher { final ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq final FieldDoc fieldDoc = (FieldDoc) scoreDocs[j]; - fieldDoc.doc += starts[i]; // convert doc + fieldDoc.doc += docBase; // convert doc //it would be so nice if we had a thread-safe insert lock.lock(); try { From 36b17aab62c7a3d254fa976dfee3093af501f889 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 5 Jan 2011 20:47:08 +0000 Subject: [PATCH 003/252] LUCENE-2831: Revise Weight#scorer & Filter#getDocIdSet API to pass Readers context git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055636 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 + .../instantiated/InstantiatedIndexReader.java | 8 + .../lucene/index/memory/MemoryIndex.java | 7 + .../apache/lucene/search/BooleanFilter.java | 27 +-- .../apache/lucene/search/ChainedFilter.java | 32 ++-- .../apache/lucene/search/DuplicateFilter.java | 18 +- .../search/FieldCacheRewriteMethod.java | 7 +- .../org/apache/lucene/search/TermsFilter.java | 4 +- .../lucene/search/BooleanFilterTest.java | 3 +- .../apache/lucene/search/TermsFilterTest.java | 11 +- .../geohash/GeoHashDistanceFilter.java | 10 +- .../spatial/tier/CartesianShapeFilter.java | 12 +- .../spatial/tier/LatLongDistanceFilter.java | 13 +- .../lucene/spatial/tier/TestDistance.java | 8 +- .../builders/NumericRangeFilterBuilder.java | 4 +- .../TestNumericRangeFilterBuilder.java | 2 +- .../apache/lucene/index/BufferedDeletes.java | 7 +- .../apache/lucene/index/DirectoryReader.java | 28 ++- .../lucene/index/FilterIndexReader.java | 6 + .../org/apache/lucene/index/IndexReader.java | 172 +++++++++++++++++- .../org/apache/lucene/index/MultiReader.java | 25 +-- .../apache/lucene/index/ParallelReader.java | 11 +- .../apache/lucene/index/SegmentReader.java | 7 +- .../lucene/index/SlowMultiReaderWrapper.java | 8 + .../apache/lucene/search/BooleanQuery.java | 11 +- .../lucene/search/CachingSpanFilter.java | 5 +- .../lucene/search/CachingWrapperFilter.java | 10 +- .../lucene/search/ConstantScoreQuery.java | 11 +- .../lucene/search/DisjunctionMaxQuery.java | 11 +- .../lucene/search/FieldCacheRangeFilter.java | 45 ++--- .../lucene/search/FieldCacheTermsFilter.java | 5 +- .../java/org/apache/lucene/search/Filter.java | 16 +- .../apache/lucene/search/FilteredQuery.java | 5 +- .../apache/lucene/search/IndexSearcher.java | 161 ++++++++-------- .../lucene/search/MatchAllDocsQuery.java | 9 +- .../lucene/search/MultiPhraseQuery.java | 13 +- .../search/MultiTermQueryWrapperFilter.java | 8 +- .../org/apache/lucene/search/PhraseQuery.java | 15 +- .../lucene/search/QueryWrapperFilter.java | 12 +- .../apache/lucene/search/SpanQueryFilter.java | 5 +- .../org/apache/lucene/search/TermQuery.java | 10 +- .../java/org/apache/lucene/search/Weight.java | 38 ++-- .../search/function/CustomScoreQuery.java | 21 ++- .../search/function/ValueSourceQuery.java | 9 +- .../search/payloads/PayloadNearQuery.java | 8 +- .../search/payloads/PayloadTermQuery.java | 8 +- .../lucene/search/spans/SpanWeight.java | 12 +- .../org/apache/lucene/util/ReaderUtil.java | 91 +++++++++ .../search/CachingWrapperFilterHelper.java | 7 +- .../lucene/search/JustCompileSearch.java | 9 +- .../org/apache/lucene/search/MockFilter.java | 4 +- .../org/apache/lucene/search/QueryUtils.java | 51 ++++-- .../lucene/search/SingleDocTestFilter.java | 6 +- .../search/TestCachingWrapperFilter.java | 27 +-- .../search/TestDisjunctionMaxQuery.java | 10 +- .../apache/lucene/search/TestDocIdSet.java | 3 +- .../lucene/search/TestFilteredQuery.java | 7 +- .../lucene/search/TestFilteredSearch.java | 19 +- .../search/TestNumericRangeQuery32.java | 6 +- .../search/TestNumericRangeQuery64.java | 7 +- .../apache/lucene/search/TestScorerPerf.java | 3 +- .../org/apache/lucene/search/TestSort.java | 7 +- .../apache/lucene/search/TestTermScorer.java | 7 +- .../search/spans/TestNearSpansOrdered.java | 4 +- .../apache/lucene/search/spans/TestSpans.java | 3 +- .../PerSegmentSingleValuedFaceting.java | 29 ++- .../org/apache/solr/schema/LatLonType.java | 15 +- .../java/org/apache/solr/search/DocSet.java | 4 +- .../solr/search/SolrConstantScoreQuery.java | 13 +- .../org/apache/solr/search/SolrFilter.java | 7 +- .../apache/solr/search/SolrIndexReader.java | 15 +- .../apache/solr/search/SolrIndexSearcher.java | 2 +- .../apache/solr/search/SortedIntDocSet.java | 4 +- .../solr/search/function/BoostedQuery.java | 26 +-- .../solr/search/function/FunctionQuery.java | 23 +-- .../search/function/QueryValueSource.java | 2 +- .../function/ValueSourceRangeFilter.java | 6 +- .../solr/common/util/ContentStreamTest.java | 13 +- .../org/apache/solr/search/TestDocSet.java | 20 +- .../test/org/apache/solr/search/TestSort.java | 5 +- .../solr/update/DirectUpdateHandlerTest.java | 4 +- 81 files changed, 855 insertions(+), 486 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 78a75fd5db7..fdd2e6c78d1 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -128,6 +128,10 @@ Changes in backwards compatibility policy ParallelMultiSearcher into IndexSearcher as an optional ExecutorServiced passed to its ctor. (Mike McCandless) +* LUCENE-2837: Changed Weight#scorer, Weight#explain & Filter#getDocIdSet to + operate on a ReaderContext instead of directly on IndexReader to enable + searches to be aware of IndexSearcher's context. (Simon Willnauer) + Changes in Runtime Behavior * LUCENE-2650, LUCENE-2825: The behavior of FSDirectory.open has changed. On 64-bit diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java index 8fede649e66..58c5313bed4 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java @@ -31,6 +31,7 @@ import java.util.Comparator; import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BitVector; import org.apache.lucene.util.BytesRef; @@ -45,6 +46,8 @@ import org.apache.lucene.util.Bits; public class InstantiatedIndexReader extends IndexReader { private final InstantiatedIndex index; + private ReaderContext context = new AtomicReaderContext(this); + public InstantiatedIndexReader(InstantiatedIndex index) { super(); @@ -424,6 +427,11 @@ public class InstantiatedIndexReader extends IndexReader { } }; } + + @Override + public ReaderContext getTopReaderContext() { + return context; + } @Override public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException { diff --git a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index b30adc7c7ad..f342c4f640f 100644 --- a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -48,6 +48,7 @@ import org.apache.lucene.index.TermFreqVector; import org.apache.lucene.index.TermPositionVector; import org.apache.lucene.index.TermVectorMapper; import org.apache.lucene.index.FieldInvertState; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; @@ -738,6 +739,7 @@ public class MemoryIndex implements Serializable { private final class MemoryIndexReader extends IndexReader { private IndexSearcher searcher; // needed to find searcher.getSimilarity() + private final ReaderContext readerInfos = new AtomicReaderContext(this); private MemoryIndexReader() { super(); // avoid as much superclass baggage as possible @@ -764,6 +766,11 @@ public class MemoryIndex implements Serializable { if (DEBUG) System.err.println("MemoryIndexReader.docFreq: " + term + ", freq:" + freq); return freq; } + + @Override + public ReaderContext getTopReaderContext() { + return readerInfos; + } @Override public Fields fields() { diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java index 2e6868e5202..e3748774456 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.OpenBitSetDISI; @@ -41,10 +42,10 @@ public class BooleanFilter extends Filter ArrayList notFilters = null; ArrayList mustFilters = null; - private DocIdSetIterator getDISI(ArrayList filters, int index, IndexReader reader) + private DocIdSetIterator getDISI(ArrayList filters, int index, ReaderContext info) throws IOException { - return filters.get(index).getDocIdSet(reader).iterator(); + return filters.get(index).getDocIdSet(info).iterator(); } /** @@ -52,21 +53,21 @@ public class BooleanFilter extends Filter * of the filters that have been added. */ @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { OpenBitSetDISI res = null; - + final IndexReader reader = context.reader; if (shouldFilters != null) { for (int i = 0; i < shouldFilters.size(); i++) { if (res == null) { - res = new OpenBitSetDISI(getDISI(shouldFilters, i, reader), reader.maxDoc()); + res = new OpenBitSetDISI(getDISI(shouldFilters, i, context), reader.maxDoc()); } else { - DocIdSet dis = shouldFilters.get(i).getDocIdSet(reader); + DocIdSet dis = shouldFilters.get(i).getDocIdSet(context); if(dis instanceof OpenBitSet) { // optimized case for OpenBitSets res.or((OpenBitSet) dis); } else { - res.inPlaceOr(getDISI(shouldFilters, i, reader)); + res.inPlaceOr(getDISI(shouldFilters, i, context)); } } } @@ -75,15 +76,15 @@ public class BooleanFilter extends Filter if (notFilters!=null) { for (int i = 0; i < notFilters.size(); i++) { if (res == null) { - res = new OpenBitSetDISI(getDISI(notFilters, i, reader), reader.maxDoc()); + res = new OpenBitSetDISI(getDISI(notFilters, i, context), reader.maxDoc()); res.flip(0, reader.maxDoc()); // NOTE: may set bits on deleted docs } else { - DocIdSet dis = notFilters.get(i).getDocIdSet(reader); + DocIdSet dis = notFilters.get(i).getDocIdSet(context); if(dis instanceof OpenBitSet) { // optimized case for OpenBitSets res.andNot((OpenBitSet) dis); } else { - res.inPlaceNot(getDISI(notFilters, i, reader)); + res.inPlaceNot(getDISI(notFilters, i, context)); } } } @@ -92,14 +93,14 @@ public class BooleanFilter extends Filter if (mustFilters!=null) { for (int i = 0; i < mustFilters.size(); i++) { if (res == null) { - res = new OpenBitSetDISI(getDISI(mustFilters, i, reader), reader.maxDoc()); + res = new OpenBitSetDISI(getDISI(mustFilters, i, context), reader.maxDoc()); } else { - DocIdSet dis = mustFilters.get(i).getDocIdSet(reader); + DocIdSet dis = mustFilters.get(i).getDocIdSet(context); if(dis instanceof OpenBitSet) { // optimized case for OpenBitSets res.and((OpenBitSet) dis); } else { - res.inPlaceAnd(getDISI(mustFilters, i, reader)); + res.inPlaceAnd(getDISI(mustFilters, i, context)); } } } diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java index e95b50660d8..a8cc00caf5f 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; @@ -96,21 +97,21 @@ public class ChainedFilter extends Filter * {@link Filter#getDocIdSet}. */ @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException + public DocIdSet getDocIdSet(ReaderContext context) 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 getDocIdSet(reader, logic, index); + return getDocIdSet(context, logic, index); else if (logicArray != null) - return getDocIdSet(reader, logicArray, index); + return getDocIdSet(context, logicArray, index); else - return getDocIdSet(reader, DEFAULT, index); + return getDocIdSet(context, DEFAULT, index); } - private DocIdSetIterator getDISI(Filter filter, IndexReader reader) + private DocIdSetIterator getDISI(Filter filter, ReaderContext info) throws IOException { - DocIdSet docIdSet = filter.getDocIdSet(reader); + DocIdSet docIdSet = filter.getDocIdSet(info); if (docIdSet == null) { return DocIdSet.EMPTY_DOCIDSET.iterator(); } else { @@ -123,9 +124,10 @@ public class ChainedFilter extends Filter } } - private OpenBitSetDISI initialResult(IndexReader reader, int logic, int[] index) + private OpenBitSetDISI initialResult(ReaderContext info, int logic, int[] index) throws IOException { + IndexReader reader = info.reader; OpenBitSetDISI result; /** * First AND operation takes place against a completely false @@ -133,12 +135,12 @@ public class ChainedFilter extends Filter */ if (logic == AND) { - result = new OpenBitSetDISI(getDISI(chain[index[0]], reader), reader.maxDoc()); + result = new OpenBitSetDISI(getDISI(chain[index[0]], info), reader.maxDoc()); ++index[0]; } else if (logic == ANDNOT) { - result = new OpenBitSetDISI(getDISI(chain[index[0]], reader), reader.maxDoc()); + result = new OpenBitSetDISI(getDISI(chain[index[0]], info), reader.maxDoc()); result.flip(0,reader.maxDoc()); // NOTE: may set bits for deleted docs. ++index[0]; } @@ -155,13 +157,13 @@ public class ChainedFilter extends Filter * @param logic Logical operation * @return DocIdSet */ - private DocIdSet getDocIdSet(IndexReader reader, int logic, int[] index) + private DocIdSet getDocIdSet(ReaderContext info, int logic, int[] index) throws IOException { - OpenBitSetDISI result = initialResult(reader, logic, index); + OpenBitSetDISI result = initialResult(info, logic, index); for (; index[0] < chain.length; index[0]++) { - doChain(result, logic, chain[index[0]].getDocIdSet(reader)); + doChain(result, logic, chain[index[0]].getDocIdSet(info)); } return result; } @@ -172,16 +174,16 @@ public class ChainedFilter extends Filter * @param logic Logical operation * @return DocIdSet */ - private DocIdSet getDocIdSet(IndexReader reader, int[] logic, int[] index) + private DocIdSet getDocIdSet(ReaderContext info, int[] logic, int[] index) throws IOException { if (logic.length != chain.length) throw new IllegalArgumentException("Invalid number of elements in logic array"); - OpenBitSetDISI result = initialResult(reader, logic[0], index); + OpenBitSetDISI result = initialResult(info, logic[0], index); for (; index[0] < chain.length; index[0]++) { - doChain(result, logic[index[0]], chain[index[0]].getDocIdSet(reader)); + doChain(result, logic[index[0]], chain[index[0]].getDocIdSet(info)); } return result; } diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java index 3a249344986..5f2e3b1528f 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java @@ -19,6 +19,7 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.TermsEnum; @@ -27,7 +28,8 @@ import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.Bits; public class DuplicateFilter extends Filter -{ +{ // TODO: make duplicate filter aware of ReaderContext such that we can + // filter duplicates across segments String fieldName; @@ -70,15 +72,15 @@ public class DuplicateFilter extends Filter } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { if(processingMode==PM_FAST_INVALIDATION) { - return fastBits(reader); + return fastBits(context.reader); } else { - return correctBits(reader); + return correctBits(context.reader); } } @@ -96,7 +98,7 @@ public class DuplicateFilter extends Filter } else { docs = termsEnum.docs(delDocs, docs); int doc = docs.nextDoc(); - if (doc != docs.NO_MORE_DOCS) { + if (doc != DocsEnum.NO_MORE_DOCS) { if (keepMode == KM_USE_FIRST_OCCURRENCE) { bits.set(doc); } else { @@ -104,7 +106,7 @@ public class DuplicateFilter extends Filter while (true) { lastDoc = doc; doc = docs.nextDoc(); - if (doc == docs.NO_MORE_DOCS) { + if (doc == DocsEnum.NO_MORE_DOCS) { break; } } @@ -136,7 +138,7 @@ public class DuplicateFilter extends Filter // unset potential duplicates docs = termsEnum.docs(delDocs, docs); int doc = docs.nextDoc(); - if (doc != docs.NO_MORE_DOCS) { + if (doc != DocsEnum.NO_MORE_DOCS) { if (keepMode == KM_USE_FIRST_OCCURRENCE) { doc = docs.nextDoc(); } @@ -147,7 +149,7 @@ public class DuplicateFilter extends Filter lastDoc = doc; bits.clear(lastDoc); doc = docs.nextDoc(); - if (doc == docs.NO_MORE_DOCS) { + if (doc == DocsEnum.NO_MORE_DOCS) { break; } } diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java index e296fcaa5ff..6dee395ab70 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.Comparator; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.BytesRef; @@ -108,8 +109,8 @@ public final class FieldCacheRewriteMethod extends MultiTermQuery.RewriteMethod * results. */ @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(reader, query.field); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(context.reader, query.field); final OpenBitSet termSet = new OpenBitSet(fcsi.numOrd()); TermsEnum termsEnum = query.getTermsEnum(new Terms() { @@ -142,7 +143,7 @@ public final class FieldCacheRewriteMethod extends MultiTermQuery.RewriteMethod return DocIdSet.EMPTY_DOCIDSET; } - return new FieldCacheRangeFilter.FieldCacheDocIdSet(reader, true) { + return new FieldCacheRangeFilter.FieldCacheDocIdSet(context.reader, true) { @Override boolean matchDoc(int doc) throws ArrayIndexOutOfBoundsException { return termSet.fastGet(fcsi.getOrd(doc)); diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java index 5ab5834a5b4..e1ab950ab0c 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java @@ -23,6 +23,7 @@ import java.util.Set; import java.util.TreeSet; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.Terms; @@ -57,7 +58,8 @@ public class TermsFilter extends Filter * @see org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader) */ @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + IndexReader reader = context.reader; OpenBitSet result=new OpenBitSet(reader.maxDoc()); Fields fields = reader.fields(); BytesRef br = new BytesRef(); diff --git a/lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java b/lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java index a9a6766f927..b9a8dfacd6c 100644 --- a/lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java +++ b/lucene/contrib/queries/src/test/org/apache/lucene/search/BooleanFilterTest.java @@ -24,6 +24,7 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.Term; @@ -83,7 +84,7 @@ public class BooleanFilterTest extends LuceneTestCase { private void tstFilterCard(String mes, int expected, Filter filt) throws Throwable { - DocIdSetIterator disi = filt.getDocIdSet(reader).iterator(); + DocIdSetIterator disi = filt.getDocIdSet(new AtomicReaderContext(reader)).iterator(); int actual = 0; while (disi.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { actual++; diff --git a/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java b/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java index 454b6de9165..27d76cdb8df 100644 --- a/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java +++ b/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java @@ -21,6 +21,7 @@ import java.util.HashSet; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -59,23 +60,25 @@ public class TermsFilterTest extends LuceneTestCase { w.addDocument(doc); } IndexReader reader = new SlowMultiReaderWrapper(w.getReader()); + ReaderContext context = reader.getTopReaderContext(); + assertTrue(context.isAtomic); w.close(); TermsFilter tf=new TermsFilter(); tf.addTerm(new Term(fieldName,"19")); - OpenBitSet bits = (OpenBitSet)tf.getDocIdSet(reader); + OpenBitSet bits = (OpenBitSet)tf.getDocIdSet(context); assertEquals("Must match nothing", 0, bits.cardinality()); tf.addTerm(new Term(fieldName,"20")); - bits = (OpenBitSet)tf.getDocIdSet(reader); + bits = (OpenBitSet)tf.getDocIdSet(context); assertEquals("Must match 1", 1, bits.cardinality()); tf.addTerm(new Term(fieldName,"10")); - bits = (OpenBitSet)tf.getDocIdSet(reader); + bits = (OpenBitSet)tf.getDocIdSet(context); assertEquals("Must match 2", 2, bits.cardinality()); tf.addTerm(new Term(fieldName,"00")); - bits = (OpenBitSet)tf.getDocIdSet(reader); + bits = (OpenBitSet)tf.getDocIdSet(context); assertEquals("Must match 2", 2, bits.cardinality()); reader.close(); diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java index 69431f71f26..4f348b648d1 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java @@ -19,7 +19,7 @@ package org.apache.lucene.spatial.geohash; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.FieldCache.DocTerms; import org.apache.lucene.search.Filter; @@ -62,15 +62,15 @@ public class GeoHashDistanceFilter extends DistanceFilter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { - final DocTerms geoHashValues = FieldCache.DEFAULT.getTerms(reader, geoHashField); + final DocTerms geoHashValues = FieldCache.DEFAULT.getTerms(context.reader, geoHashField); final BytesRef br = new BytesRef(); final int docBase = nextDocBase; - nextDocBase += reader.maxDoc(); + nextDocBase += context.reader.maxDoc(); - return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) { + return new FilteredDocIdSet(startingFilter.getDocIdSet(context)) { @Override public boolean match(int doc) { diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java index 11527f396d4..07a833f3e2e 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.util.List; import org.apache.lucene.index.DocsEnum; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.Filter; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; @@ -45,8 +45,8 @@ public class CartesianShapeFilter extends Filter { } @Override - public DocIdSet getDocIdSet(final IndexReader reader) throws IOException { - final Bits delDocs = reader.getDeletedDocs(); + public DocIdSet getDocIdSet(final ReaderContext context) throws IOException { + final Bits delDocs = context.reader.getDeletedDocs(); final List area = shape.getArea(); final int sz = area.size(); @@ -58,7 +58,7 @@ public class CartesianShapeFilter extends Filter { return new DocIdSet() { @Override public DocIdSetIterator iterator() throws IOException { - return reader.termDocsEnum(delDocs, fieldName, bytesRef); + return context.reader.termDocsEnum(delDocs, fieldName, bytesRef); } @Override @@ -67,11 +67,11 @@ public class CartesianShapeFilter extends Filter { } }; } else { - final OpenBitSet bits = new OpenBitSet(reader.maxDoc()); + final OpenBitSet bits = new OpenBitSet(context.reader.maxDoc()); for (int i =0; i< sz; i++) { double boxId = area.get(i).doubleValue(); NumericUtils.longToPrefixCoded(NumericUtils.doubleToSortableLong(boxId), 0, bytesRef); - final DocsEnum docsEnum = reader.termDocsEnum(delDocs, fieldName, bytesRef); + final DocsEnum docsEnum = context.reader.termDocsEnum(delDocs, fieldName, bytesRef); if (docsEnum == null) continue; // iterate through all documents // which have this boxId diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java index 44fba384701..58b475bca60 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java @@ -18,7 +18,8 @@ package org.apache.lucene.spatial.tier; import java.io.IOException; -import org.apache.lucene.index.IndexReader; + +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.FilteredDocIdSet; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.Filter; @@ -64,15 +65,15 @@ public class LatLongDistanceFilter extends DistanceFilter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { - final double[] latIndex = FieldCache.DEFAULT.getDoubles(reader, latField); - final double[] lngIndex = FieldCache.DEFAULT.getDoubles(reader, lngField); + final double[] latIndex = FieldCache.DEFAULT.getDoubles(context.reader, latField); + final double[] lngIndex = FieldCache.DEFAULT.getDoubles(context.reader, lngField); final int docBase = nextDocBase; - nextDocBase += reader.maxDoc(); + nextDocBase += context.reader.maxDoc(); - return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) { + return new FilteredDocIdSet(startingFilter.getDocIdSet(context)) { @Override protected boolean match(int doc) { double x = latIndex[doc]; diff --git a/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java b/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java index 0e0a787f8fe..f355fab632d 100644 --- a/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java +++ b/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java @@ -22,6 +22,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericField; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; @@ -30,6 +31,7 @@ import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.store.Directory; + public class TestDistance extends LuceneTestCase { private Directory directory; @@ -100,9 +102,9 @@ public class TestDistance extends LuceneTestCase { LatLongDistanceFilter f = new LatLongDistanceFilter(new QueryWrapperFilter(new MatchAllDocsQuery()), lat, lng, 1.0, latField, lngField); - IndexReader[] readers = r.getSequentialSubReaders(); - for(int i=0;i 0) { IndexSearcher searcher = new IndexSearcher(reader); + + final ReaderContext readerContext = searcher.getTopReaderContext(); + assert readerContext.isAtomic; try { for (Entry entry : deletes.queries.entrySet()) { Query query = entry.getKey(); int limit = entry.getValue().intValue(); Weight weight = query.weight(searcher); - Scorer scorer = weight.scorer(reader, true, false); + + Scorer scorer = weight.scorer(readerContext, true, false); if (scorer != null) { while(true) { int doc = scorer.nextDoc(); diff --git a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java index ff014d99f6b..c4ed2633760 100644 --- a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java +++ b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java @@ -35,7 +35,6 @@ import org.apache.lucene.store.Lock; import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.util.Bits; -import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.search.FieldCache; // not great (circular); used only to purge FieldCache entry on close @@ -60,8 +59,8 @@ class DirectoryReader extends IndexReader implements Cloneable { private boolean rollbackHasChanges; private SegmentReader[] subReaders; + private ReaderContext topLevelReaderContext; private int[] starts; // 1st docno for each segment - private final Map subReaderToSlice = new HashMap(); private int maxDoc = 0; private int numDocs = -1; private boolean hasDeletions = false; @@ -300,25 +299,22 @@ class DirectoryReader extends IndexReader implements Cloneable { private void initialize(SegmentReader[] subReaders) throws IOException { this.subReaders = subReaders; starts = new int[subReaders.length + 1]; // build starts array - + final AtomicReaderContext[] subReaderCtx = new AtomicReaderContext[subReaders.length]; + topLevelReaderContext = new CompositeReaderContext(this, subReaderCtx, subReaderCtx); final List subFields = new ArrayList(); - final List fieldSlices = new ArrayList(); - + for (int i = 0; i < subReaders.length; i++) { starts[i] = maxDoc; + subReaderCtx[i] = new AtomicReaderContext(topLevelReaderContext, subReaders[i], i, maxDoc, i, maxDoc); maxDoc += subReaders[i].maxDoc(); // compute maxDocs if (subReaders[i].hasDeletions()) { hasDeletions = true; } - - final ReaderUtil.Slice slice = new ReaderUtil.Slice(starts[i], subReaders[i].maxDoc(), i); - subReaderToSlice.put(subReaders[i], slice); - + final Fields f = subReaders[i].fields(); if (f != null) { subFields.add(f); - fieldSlices.add(slice); } } starts[subReaders.length] = maxDoc; @@ -844,18 +840,18 @@ class DirectoryReader extends IndexReader implements Cloneable { fieldSet.addAll(names); } return fieldSet; - } + } + + @Override + public ReaderContext getTopReaderContext() { + return topLevelReaderContext; + } @Override public IndexReader[] getSequentialSubReaders() { return subReaders; } - @Override - public int getSubReaderDocBase(IndexReader subReader) { - return subReaderToSlice.get(subReader).start; - } - /** Returns the directory this index resides in. */ @Override public Directory directory() { diff --git a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java index ca211eaccea..aa18fcdb51f 100644 --- a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java @@ -19,6 +19,7 @@ package org.apache.lucene.index; import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; import org.apache.lucene.search.FieldCache; // not great (circular); used only to purge FieldCache entry on close @@ -417,6 +418,11 @@ public class FilterIndexReader extends IndexReader { public IndexReader[] getSequentialSubReaders() { return in.getSequentialSubReaders(); } + + @Override + public ReaderContext getTopReaderContext() { + return in.getTopReaderContext(); + } @Override public Fields fields() throws IOException { diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index cc561d6e43b..ac0f203a8fb 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -1126,7 +1126,7 @@ public abstract class IndexReader implements Cloneable,Closeable { if (docs == null) return 0; int n = 0; int doc; - while ((doc = docs.nextDoc()) != docs.NO_MORE_DOCS) { + while ((doc = docs.nextDoc()) != DocsEnum.NO_MORE_DOCS) { deleteDocument(doc); n++; } @@ -1356,9 +1356,7 @@ public abstract class IndexReader implements Cloneable,Closeable { } /** Expert: returns the sequential sub readers that this - * reader is logically composed of. For example, - * IndexSearcher uses this API to drive searching by one - * sub reader at a time. If this reader is not composed + * reader is logically composed of. If this reader is not composed * of sequential child readers, it should return null. * If this method returns an empty array, that means this * reader is a null reader (for example a MultiReader @@ -1373,12 +1371,33 @@ public abstract class IndexReader implements Cloneable,Closeable { public IndexReader[] getSequentialSubReaders() { return null; } - - - /** Expert: returns the docID base for this subReader. */ - public int getSubReaderDocBase(IndexReader subReader) { - throw new UnsupportedOperationException(); - } + + /** + * Expert: Returns a the root {@link ReaderContext} for this + * {@link IndexReader}'s sub-reader tree. Iff this reader is composed of sub + * readers ,ie. this reader being a composite reader, this method returns a + * {@link CompositeReaderContext} holding the reader's direct children as well as a + * view of the reader tree's atomic leaf contexts. All sub- + * {@link ReaderContext} instances referenced from this readers top-level + * context are private to this reader and are not shared with another context + * tree. For example, IndexSearcher uses this API to drive searching by one + * atomic leaf reader at a time. If this reader is not composed of child + * readers, this method returns an {@link AtomicReaderContext}. + *

    + * Note: Any of the sub-{@link CompositeReaderContext} instances reference from this + * top-level context holds a null {@link CompositeReaderContext#leaves} + * reference. Only the top-level context maintains the convenience leaf-view + * for performance reasons. + *

    + * NOTE: You should not try using sub-readers returned by this method to make + * any changes (setNorm, deleteDocument, etc.). While this might succeed for + * one composite reader (like MultiReader), it will most likely lead to index + * corruption for other readers (like DirectoryReader obtained through + * {@link #open}. Use the top-level context's reader directly. + * + * @lucene.experimental + */ + public abstract ReaderContext getTopReaderContext(); /** Expert */ public Object getCoreCacheKey() { @@ -1431,4 +1450,137 @@ public abstract class IndexReader implements Cloneable,Closeable { Fields retrieveFields() { return fields; } + + /** + * A struct like class that represents a hierarchical relationship between + * {@link IndexReader} instances. + * @lucene.experimental + */ + public static abstract class ReaderContext { + /** The reader context for this reader's immediate parent, or null if none */ + public final ReaderContext parent; + /** The actual reader */ + public final IndexReader reader; + /** true iff the reader is an atomic reader */ + public final boolean isAtomic; + /** true if this context struct represents the top level reader within the hierarchical context */ + public final boolean isTopLevel; + /** the doc base for this reader in the parent, 0 if parent is null */ + public final int docBaseInParent; + /** the ord for this reader in the parent, 0 if parent is null */ + public final int ordInParent; + + ReaderContext(ReaderContext parent, IndexReader reader, + boolean isAtomic, boolean isTopLevel, int ordInParent, int docBaseInParent) { + this.parent = parent; + this.reader = reader; + this.isAtomic = isAtomic; + this.docBaseInParent = docBaseInParent; + this.ordInParent = ordInParent; + this.isTopLevel = isTopLevel; + } + + /** + * Returns the context's leaves if this context is a top-level context + * otherwise null. + *

    + * Note: this is convenience method since leaves can always be obtained by + * walking the context tree. + */ + public AtomicReaderContext[] leaves() { + return null; + } + + /** + * Returns the context's children iff this context is a composite context + * otherwise null. + *

    + * Note: this method is a convenience method to prevent + * instanceof checks and type-casts to + * {@link CompositeReaderContext}. + */ + public ReaderContext[] children() { + return null; + } + } + + /** + * {@link ReaderContext} for composite {@link IndexReader} instance. + * @lucene.experimental + */ + public static final class CompositeReaderContext extends ReaderContext { + /** the composite readers immediate children */ + public final ReaderContext[] children; + /** the composite readers leaf reader contexts if this is the top level reader in this context */ + public final AtomicReaderContext[] leaves; + + /** + * Creates a {@link CompositeReaderContext} for intermediate readers that aren't + * not top-level readers in the current context + */ + public CompositeReaderContext(ReaderContext parent, IndexReader reader, + int ordInParent, int docbaseInParent, ReaderContext[] children) { + this(parent, reader, ordInParent, docbaseInParent, children, null); + } + + /** + * Creates a {@link CompositeReaderContext} for top-level readers with parent set to null + */ + public CompositeReaderContext(IndexReader reader, ReaderContext[] children, AtomicReaderContext[] leaves) { + this(null, reader, 0, 0, children, leaves); + } + + private CompositeReaderContext(ReaderContext parent, IndexReader reader, + int ordInParent, int docbaseInParent, ReaderContext[] children, + AtomicReaderContext[] leaves) { + super(parent, reader, false, leaves != null, ordInParent, docbaseInParent); + this.children = children; + this.leaves = leaves; + } + + @Override + public AtomicReaderContext[] leaves() { + return leaves; + } + + + @Override + public ReaderContext[] children() { + return children; + } + } + + /** + * {@link ReaderContext} for atomic {@link IndexReader} instances + * @lucene.experimental + */ + public static final class AtomicReaderContext extends ReaderContext { + /** The readers ord in the top-level's leaves array */ + public final int ord; + /** The readers absolute doc base */ + public final int docBase; + /** + * Creates a new {@link AtomicReaderContext} + */ + public AtomicReaderContext(ReaderContext parent, IndexReader reader, + int ord, int docBase, int leafOrd, int leafDocBase) { + this(parent, reader, ord, docBase, leafOrd, leafDocBase, false); + } + + private AtomicReaderContext(ReaderContext parent, IndexReader reader, + int ord, int docBase, int leafOrd, int leafDocBase, boolean topLevel) { + super(parent, reader, true, topLevel, ord, docBase); + assert reader.getSequentialSubReaders() == null : "Atomic readers must not have subreaders"; + this.ord = leafOrd; + this.docBase = leafDocBase; + } + + /** + * Creates a new {@link AtomicReaderContext} for a atomic reader without an immediate + * parent. + */ + public AtomicReaderContext(IndexReader atomicReader) { + this(null, atomicReader, 0, 0, 0, 0, true); // toplevel!! + } + } } diff --git a/lucene/src/java/org/apache/lucene/index/MultiReader.java b/lucene/src/java/org/apache/lucene/index/MultiReader.java index a765f3ae10f..a519eeb6197 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiReader.java +++ b/lucene/src/java/org/apache/lucene/index/MultiReader.java @@ -33,8 +33,8 @@ import org.apache.lucene.util.ReaderUtil; * their content. */ public class MultiReader extends IndexReader implements Cloneable { protected IndexReader[] subReaders; + private final ReaderContext topLevelContext; private int[] starts; // 1st docno for each segment - private final Map subReaderToSlice = new HashMap(); private boolean[] decrefOnClose; // remember which subreaders to decRef on close private int maxDoc = 0; private int numDocs = -1; @@ -48,7 +48,7 @@ public class MultiReader extends IndexReader implements Cloneable { * @param subReaders set of (sub)readers */ public MultiReader(IndexReader... subReaders) throws IOException { - initialize(subReaders, true); + topLevelContext = initialize(subReaders, true); } /** @@ -60,14 +60,13 @@ public class MultiReader extends IndexReader implements Cloneable { * @param subReaders set of (sub)readers */ public MultiReader(IndexReader[] subReaders, boolean closeSubReaders) throws IOException { - initialize(subReaders, closeSubReaders); + topLevelContext = initialize(subReaders, closeSubReaders); } - private void initialize(IndexReader[] subReaders, boolean closeSubReaders) throws IOException { + private ReaderContext initialize(IndexReader[] subReaders, boolean closeSubReaders) throws IOException { this.subReaders = subReaders.clone(); starts = new int[subReaders.length + 1]; // build starts array decrefOnClose = new boolean[subReaders.length]; - for (int i = 0; i < subReaders.length; i++) { starts[i] = maxDoc; maxDoc += subReaders[i].maxDoc(); // compute maxDocs @@ -82,14 +81,9 @@ public class MultiReader extends IndexReader implements Cloneable { if (subReaders[i].hasDeletions()) { hasDeletions = true; } - - final ReaderUtil.Slice slice = new ReaderUtil.Slice(starts[i], - subReaders[i].maxDoc(), - i); - subReaderToSlice.put(subReaders[i], slice); } - starts[subReaders.length] = maxDoc; + return ReaderUtil.buildReaderContext(this); } @Override @@ -97,11 +91,6 @@ public class MultiReader extends IndexReader implements Cloneable { throw new UnsupportedOperationException(""); } - @Override - public int getSubReaderDocBase(IndexReader subReader) { - return subReaderToSlice.get(subReader).start; - } - @Override public Fields fields() throws IOException { throw new UnsupportedOperationException("please use MultiFields.getFields, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level Fields"); @@ -403,4 +392,8 @@ public class MultiReader extends IndexReader implements Cloneable { public IndexReader[] getSequentialSubReaders() { return subReaders; } + + public ReaderContext getTopReaderContext() { + return topLevelContext; + } } diff --git a/lucene/src/java/org/apache/lucene/index/ParallelReader.java b/lucene/src/java/org/apache/lucene/index/ParallelReader.java index 77f98487d35..775c865b2b9 100644 --- a/lucene/src/java/org/apache/lucene/index/ParallelReader.java +++ b/lucene/src/java/org/apache/lucene/index/ParallelReader.java @@ -21,7 +21,9 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; import org.apache.lucene.document.FieldSelectorResult; import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.Bits; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.search.FieldCache; // not great (circular); used only to purge FieldCache entry on close import org.apache.lucene.search.Similarity; import org.apache.lucene.util.BytesRef; @@ -55,7 +57,7 @@ public class ParallelReader extends IndexReader { private Map> readerToFields = new HashMap>(); private List storedFieldReaders = new ArrayList(); private Map normsCache = new HashMap(); - + private final ReaderContext topLevelReaderContext = new AtomicReaderContext(this); private int maxDoc; private int numDocs; private boolean hasDeletions; @@ -90,7 +92,7 @@ public class ParallelReader extends IndexReader { buffer.append(')'); return buffer.toString(); } - + /** Add an IndexReader. * @throws IOException if there is a low-level IO error */ @@ -559,6 +561,11 @@ public class ParallelReader extends IndexReader { } return fieldSet; } + @Override + public ReaderContext getTopReaderContext() { + return topLevelReaderContext; + } + } diff --git a/lucene/src/java/org/apache/lucene/index/SegmentReader.java b/lucene/src/java/org/apache/lucene/index/SegmentReader.java index 1909f62523f..66ebced2126 100644 --- a/lucene/src/java/org/apache/lucene/index/SegmentReader.java +++ b/lucene/src/java/org/apache/lucene/index/SegmentReader.java @@ -51,7 +51,7 @@ public class SegmentReader extends IndexReader implements Cloneable { private SegmentInfo si; private int readBufferSize; - + private final ReaderContext readerContext = new AtomicReaderContext(this); CloseableThreadLocal fieldsReaderLocal = new FieldsReaderLocal(); CloseableThreadLocal termVectorsLocal = new CloseableThreadLocal(); @@ -1183,6 +1183,11 @@ public class SegmentReader extends IndexReader implements Cloneable { buffer.append(si.toString(core.dir, pendingDeleteCount)); return buffer.toString(); } + + @Override + public ReaderContext getTopReaderContext() { + return readerContext; + } /** * Return the name of the segment this reader is reading. diff --git a/lucene/src/java/org/apache/lucene/index/SlowMultiReaderWrapper.java b/lucene/src/java/org/apache/lucene/index/SlowMultiReaderWrapper.java index 7a29870586f..2deb8b2c741 100644 --- a/lucene/src/java/org/apache/lucene/index/SlowMultiReaderWrapper.java +++ b/lucene/src/java/org/apache/lucene/index/SlowMultiReaderWrapper.java @@ -30,6 +30,7 @@ import org.apache.lucene.util.ReaderUtil; // javadoc import org.apache.lucene.index.DirectoryReader; // javadoc import org.apache.lucene.index.MultiReader; // javadoc +import org.apache.lucene.index.IndexReader.ReaderContext; /** * This class forces a composite reader (eg a {@link @@ -55,10 +56,12 @@ import org.apache.lucene.index.MultiReader; // javadoc public final class SlowMultiReaderWrapper extends FilterIndexReader { + private final ReaderContext readerContext; private final Map normsCache = new HashMap(); public SlowMultiReaderWrapper(IndexReader other) { super(other); + readerContext = new AtomicReaderContext(this); // emulate atomic reader! } @Override @@ -103,6 +106,11 @@ public final class SlowMultiReaderWrapper extends FilterIndexReader { } } + @Override + public ReaderContext getTopReaderContext() { + return readerContext; + } + @Override protected void doSetNorm(int n, String field, byte value) throws CorruptIndexException, IOException { diff --git a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java index 56f7d098114..d756eff3bad 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java @@ -18,6 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.search.BooleanClause.Occur; @@ -223,7 +224,7 @@ public class BooleanQuery extends Query implements Iterable { } @Override - public Explanation explain(IndexReader reader, int doc) + public Explanation explain(ReaderContext context, int doc) throws IOException { final int minShouldMatch = BooleanQuery.this.getMinimumNumberShouldMatch(); @@ -237,7 +238,7 @@ public class BooleanQuery extends Query implements Iterable { for (Iterator wIter = weights.iterator(); wIter.hasNext();) { Weight w = wIter.next(); BooleanClause c = cIter.next(); - if (w.scorer(reader, true, true) == null) { + if (w.scorer(context, true, true) == null) { if (c.isRequired()) { fail = true; Explanation r = new Explanation(0.0f, "no match on required clause (" + c.getQuery().toString() + ")"); @@ -245,7 +246,7 @@ public class BooleanQuery extends Query implements Iterable { } continue; } - Explanation e = w.explain(reader, doc); + Explanation e = w.explain(context, doc); if (e.isMatch()) { if (!c.isProhibited()) { sumExpl.addDetail(e); @@ -299,7 +300,7 @@ public class BooleanQuery extends Query implements Iterable { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { List required = new ArrayList(); List prohibited = new ArrayList(); @@ -307,7 +308,7 @@ public class BooleanQuery extends Query implements Iterable { Iterator cIter = clauses.iterator(); for (Weight w : weights) { BooleanClause c = cIter.next(); - Scorer subScorer = w.scorer(reader, true, false); + Scorer subScorer = w.scorer(context, true, false); if (subScorer == null) { if (c.isRequired()) { return null; diff --git a/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java b/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java index d19c872ee58..1939406749e 100644 --- a/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java +++ b/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java @@ -17,6 +17,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.Bits; import java.io.IOException; @@ -60,8 +61,8 @@ public class CachingSpanFilter extends SpanFilter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - SpanFilterResult result = getCachedResult(reader); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + SpanFilterResult result = getCachedResult(context.reader); return result != null ? result.getDocIdSet() : null; } diff --git a/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java index d51eed25172..1fc5c9f8b80 100644 --- a/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.WeakHashMap; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.OpenBitSetDISI; import org.apache.lucene.util.Bits; @@ -37,6 +38,9 @@ import org.apache.lucene.util.Bits; * {@link DeletesMode#DYNAMIC}). */ public class CachingWrapperFilter extends Filter { + // TODO: make this filter aware of ReaderContext. a cached filter could + // specify the actual readers key or something similar to indicate on which + // level of the readers hierarchy it should be cached. Filter filter; /** @@ -191,8 +195,8 @@ public class CachingWrapperFilter extends Filter { int hitCount, missCount; @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + final IndexReader reader = context.reader; final Object coreKey = reader.getCoreCacheKey(); final Object delCoreKey = reader.hasDeletions() ? reader.getDeletedDocs() : coreKey; @@ -205,7 +209,7 @@ public class CachingWrapperFilter extends Filter { missCount++; // cache miss - docIdSet = docIdSetToCache(filter.getDocIdSet(reader), reader); + docIdSet = docIdSetToCache(filter.getDocIdSet(context), reader); if (docIdSet != null) { cache.put(coreKey, delCoreKey, docIdSet); diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index fe76121d3c2..6af8ed5305c 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -18,6 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; @@ -132,18 +133,18 @@ public class ConstantScoreQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { final DocIdSetIterator disi; if (filter != null) { assert query == null; - final DocIdSet dis = filter.getDocIdSet(reader); + final DocIdSet dis = filter.getDocIdSet(context); if (dis == null) return null; disi = dis.iterator(); } else { assert query != null && innerWeight != null; disi = - innerWeight.scorer(reader, scoreDocsInOrder, topScorer); + innerWeight.scorer(context, scoreDocsInOrder, topScorer); } if (disi == null) return null; @@ -156,8 +157,8 @@ public class ConstantScoreQuery extends Query { } @Override - public Explanation explain(IndexReader reader, int doc) throws IOException { - final Scorer cs = scorer(reader, true, false); + public Explanation explain(ReaderContext context, int doc) throws IOException { + final Scorer cs = scorer(context, true, false); final boolean exists = (cs != null && cs.advance(doc) == doc); final ComplexExplanation result = new ComplexExplanation(); diff --git a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index b6cd0295247..83f7764776f 100644 --- a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -23,6 +23,7 @@ import java.util.Iterator; import java.util.Set; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; /** @@ -141,12 +142,12 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /* Create the scorer used to score our associated DisjunctionMaxQuery */ @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { Scorer[] scorers = new Scorer[weights.size()]; int idx = 0; for (Weight w : weights) { - Scorer subScorer = w.scorer(reader, true, false); + Scorer subScorer = w.scorer(context, true, false); if (subScorer != null && subScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { scorers[idx++] = subScorer; } @@ -158,13 +159,13 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /* Explain the score we computed for doc */ @Override - public Explanation explain(IndexReader reader, int doc) throws IOException { - if (disjuncts.size() == 1) return weights.get(0).explain(reader,doc); + public Explanation explain(ReaderContext context, int doc) throws IOException { + if (disjuncts.size() == 1) return weights.get(0).explain(context,doc); ComplexExplanation result = new ComplexExplanation(); float max = 0.0f, sum = 0.0f; result.setDescription(tieBreakerMultiplier == 0.0f ? "max of:" : "max plus " + tieBreakerMultiplier + " times others of:"); for (Weight wt : weights) { - Explanation e = wt.explain(reader, doc); + Explanation e = wt.explain(context, doc); if (e.isMatch()) { result.setMatch(Boolean.TRUE); result.addDetail(e); diff --git a/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java b/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java index 6c4245a5d70..e0a03169285 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java +++ b/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.MultiFields; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.Bits; @@ -73,7 +74,7 @@ public abstract class FieldCacheRangeFilter extends Filter { /** This method is implemented for each data type */ @Override - public abstract DocIdSet getDocIdSet(IndexReader reader) throws IOException; + public abstract DocIdSet getDocIdSet(ReaderContext context) throws IOException; /** * Creates a string range filter using {@link FieldCache#getTermsIndex}. This works with all @@ -83,8 +84,8 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newStringRange(String field, String lowerVal, String upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, null, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(reader, field); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(context.reader, field); final BytesRef spare = new BytesRef(); final int lowerPoint = fcsi.binarySearchLookup(lowerVal == null ? null : new BytesRef(lowerVal), spare); final int upperPoint = fcsi.binarySearchLookup(upperVal == null ? null : new BytesRef(upperVal), spare); @@ -124,7 +125,7 @@ public abstract class FieldCacheRangeFilter extends Filter { // for this DocIdSet, we can ignore deleted docs // because deleted docs have an order of 0 (null entry in StringIndex) - return new FieldCacheDocIdSet(reader, true) { + return new FieldCacheDocIdSet(context.reader, true) { @Override final boolean matchDoc(int doc) { final int docOrd = fcsi.getOrd(doc); @@ -152,7 +153,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newByteRange(String field, FieldCache.ByteParser parser, Byte lowerVal, Byte upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { final byte inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { final byte i = lowerVal.byteValue(); @@ -174,9 +175,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final byte[] values = FieldCache.DEFAULT.getBytes(reader, field, (FieldCache.ByteParser) parser); + final byte[] values = FieldCache.DEFAULT.getBytes(context.reader, field, (FieldCache.ByteParser) parser); // we only respect deleted docs if the range contains 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; @@ -203,7 +204,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newShortRange(String field, FieldCache.ShortParser parser, Short lowerVal, Short upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { final short inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { short i = lowerVal.shortValue(); @@ -225,9 +226,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final short[] values = FieldCache.DEFAULT.getShorts(reader, field, (FieldCache.ShortParser) parser); + final short[] values = FieldCache.DEFAULT.getShorts(context.reader, field, (FieldCache.ShortParser) parser); // ignore deleted docs if range doesn't contain 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; @@ -254,7 +255,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newIntRange(String field, FieldCache.IntParser parser, Integer lowerVal, Integer upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { final int inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { int i = lowerVal.intValue(); @@ -276,9 +277,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final int[] values = FieldCache.DEFAULT.getInts(reader, field, (FieldCache.IntParser) parser); + final int[] values = FieldCache.DEFAULT.getInts(context.reader, field, (FieldCache.IntParser) parser); // ignore deleted docs if range doesn't contain 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0 && inclusiveUpperPoint >= 0)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; @@ -305,7 +306,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newLongRange(String field, FieldCache.LongParser parser, Long lowerVal, Long upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { final long inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { long i = lowerVal.longValue(); @@ -327,9 +328,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final long[] values = FieldCache.DEFAULT.getLongs(reader, field, (FieldCache.LongParser) parser); + final long[] values = FieldCache.DEFAULT.getLongs(context.reader, field, (FieldCache.LongParser) parser); // ignore deleted docs if range doesn't contain 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0L && inclusiveUpperPoint >= 0L)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0L && inclusiveUpperPoint >= 0L)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; @@ -356,7 +357,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newFloatRange(String field, FieldCache.FloatParser parser, Float lowerVal, Float upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { // we transform the floating point numbers to sortable integers // using NumericUtils to easier find the next bigger/lower value final float inclusiveLowerPoint, inclusiveUpperPoint; @@ -382,9 +383,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final float[] values = FieldCache.DEFAULT.getFloats(reader, field, (FieldCache.FloatParser) parser); + final float[] values = FieldCache.DEFAULT.getFloats(context.reader, field, (FieldCache.FloatParser) parser); // ignore deleted docs if range doesn't contain 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0.0f && inclusiveUpperPoint >= 0.0f)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0.0f && inclusiveUpperPoint >= 0.0f)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; @@ -411,7 +412,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newDoubleRange(String field, FieldCache.DoubleParser parser, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { // we transform the floating point numbers to sortable integers // using NumericUtils to easier find the next bigger/lower value final double inclusiveLowerPoint, inclusiveUpperPoint; @@ -437,9 +438,9 @@ public abstract class FieldCacheRangeFilter extends Filter { if (inclusiveLowerPoint > inclusiveUpperPoint) return DocIdSet.EMPTY_DOCIDSET; - final double[] values = FieldCache.DEFAULT.getDoubles(reader, field, (FieldCache.DoubleParser) parser); + final double[] values = FieldCache.DEFAULT.getDoubles(context.reader, field, (FieldCache.DoubleParser) parser); // ignore deleted docs if range doesn't contain 0 - return new FieldCacheDocIdSet(reader, !(inclusiveLowerPoint <= 0.0 && inclusiveUpperPoint >= 0.0)) { + return new FieldCacheDocIdSet(context.reader, !(inclusiveLowerPoint <= 0.0 && inclusiveUpperPoint >= 0.0)) { @Override boolean matchDoc(int doc) { return values[doc] >= inclusiveLowerPoint && values[doc] <= inclusiveUpperPoint; diff --git a/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java b/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java index 57f8be754a4..684b139e4cf 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java +++ b/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.lucene.index.DocsEnum; // javadoc @link import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.BytesRef; @@ -115,8 +116,8 @@ public class FieldCacheTermsFilter extends Filter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - return new FieldCacheTermsFilterDocIdSet(getFieldCache().getTermsIndex(reader, field)); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + return new FieldCacheTermsFilterDocIdSet(getFieldCache().getTermsIndex(context.reader, field)); } protected class FieldCacheTermsFilterDocIdSet extends DocIdSet { diff --git a/lucene/src/java/org/apache/lucene/search/Filter.java b/lucene/src/java/org/apache/lucene/search/Filter.java index f8061ebf52f..2dea148e94e 100644 --- a/lucene/src/java/org/apache/lucene/search/Filter.java +++ b/lucene/src/java/org/apache/lucene/search/Filter.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.DocIdBitSet; /** @@ -38,10 +38,13 @@ public abstract class Filter implements java.io.Serializable { * must refer to document IDs for that segment, not for * the top-level reader. * - * @param reader a {@link IndexReader} instance opened on the index currently - * searched on. The provided reader is always an - * atomic reader, so you can call reader.fields() - * or reader.getDeletedDocs(), for example. + * @param context a {@link ReaderContext} instance opened on the index currently + * searched on. Note, it is likely that the provided reader info does not + * represent the whole underlying index i.e. if the index has more than + * one segment the given reader only represents a single segment. + * The provided context is always an atomic context, so you can call + * {@link IndexReader#fields()} or {@link IndexReader#getDeletedDocs()} + * on the context's reader, for example. * * @return a DocIdSet that provides the documents which should be permitted or * prohibited in search results. NOTE: null can be returned if @@ -49,5 +52,6 @@ public abstract class Filter implements java.io.Serializable { * * @see DocIdBitSet */ - public abstract DocIdSet getDocIdSet(IndexReader reader) throws IOException; + // TODO make this context an AtomicContext + public abstract DocIdSet getDocIdSet(ReaderContext context) throws IOException; } diff --git a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java index 6f27cfc6773..f0b6001665f 100644 --- a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java +++ b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java @@ -18,6 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; @@ -81,7 +82,7 @@ extends Query { } @Override - public Explanation explain (IndexReader ir, int i) throws IOException { + public Explanation explain (ReaderContext ir, int i) throws IOException { Explanation inner = weight.explain (ir, i); if (getBoost()!=1) { Explanation preBoost = inner; @@ -111,7 +112,7 @@ extends Query { // return a filtering scorer @Override - public Scorer scorer(IndexReader indexReader, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(ReaderContext indexReader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { final Scorer scorer = weight.scorer(indexReader, true, false); if (scorer == null) { diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 25f552c5fdf..eb2a3809e89 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -18,9 +18,7 @@ package org.apache.lucene.search; */ import java.io.IOException; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; @@ -35,6 +33,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.NIOFSDirectory; // javadoc @@ -57,14 +57,15 @@ import org.apache.lucene.util.ThreadInterruptedException; * use your own (non-Lucene) objects instead.

    */ public class IndexSearcher { - IndexReader reader; + final IndexReader reader; // package private for testing! private boolean closeReader; // NOTE: these members might change in incompatible ways // in the next release - protected final IndexReader[] subReaders; + protected final ReaderContext readerContext; + protected final AtomicReaderContext[] leafContexts; protected final IndexSearcher[] subSearchers; - protected final int[] docStarts; +// protected final int[] docStarts; private final ExecutorService executor; /** The Similarity implementation used by this searcher. */ @@ -115,83 +116,73 @@ public class IndexSearcher { this(r, false, executor); } - /** Expert: directly specify the reader, subReaders and - * their docID starts. + /** + * Creates a searcher searching the provided top-level {@link ReaderContext}. + *

    + * Given a non-null {@link ExecutorService} this method runs + * searches for each segment separately, using the provided ExecutorService. + * IndexSearcher will not shutdown/awaitTermination this ExecutorService on + * close; you must do so, eventually, on your own. NOTE: if you are using + * {@link NIOFSDirectory}, do not use the shutdownNow method of + * ExecutorService as this uses Thread.interrupt under-the-hood which can + * silently close file descriptors (see LUCENE-2239). * - * @lucene.experimental */ - public IndexSearcher(IndexReader reader, IndexReader[] subReaders, int[] docStarts) { - this.reader = reader; - this.subReaders = subReaders; - this.docStarts = docStarts; - subSearchers = new IndexSearcher[subReaders.length]; - for(int i=0;iLUCENE-2239). - * - * @lucene.experimental */ - public IndexSearcher(IndexReader reader, IndexReader[] subReaders, int[] docStarts, ExecutorService executor) { - this.reader = reader; - this.subReaders = subReaders; - this.docStarts = docStarts; - subSearchers = new IndexSearcher[subReaders.length]; - for(int i=0;i subReadersList = new ArrayList(); - gatherSubReaders(subReadersList, reader); - subReaders = subReadersList.toArray(new IndexReader[subReadersList.size()]); - docStarts = new int[subReaders.length]; - subSearchers = new IndexSearcher[subReaders.length]; - int maxDoc = 0; - for (int i = 0; i < subReaders.length; i++) { - docStarts[i] = maxDoc; - maxDoc += subReaders[i].maxDoc(); - if (subReaders[i] == r) { + this.readerContext = context; + if (context.isAtomic) { + assert context.leaves() == null : "AtomicReaderContext must not have any leaves"; + this.leafContexts = new AtomicReaderContext[] { (AtomicReaderContext) context }; + } else { + assert context.leaves() != null : "non-atomic top-level context must have leaves"; + this.leafContexts = context.leaves(); + } + subSearchers = new IndexSearcher[this.leafContexts.length]; + for (int i = 0; i < subSearchers.length; i++) { // TODO do we need those IS if executor is null? + if (leafContexts[i].reader == context.reader) { subSearchers[i] = this; } else { - subSearchers[i] = new IndexSearcher(subReaders[i]); + subSearchers[i] = new IndexSearcher(leafContexts[i].reader.getTopReaderContext()); // we need to get a TL context for sub searchers! } } } - protected void gatherSubReaders(List allSubReaders, IndexReader r) { - ReaderUtil.gatherSubReaders(allSubReaders, r); - } - /** Return the {@link IndexReader} this searches. */ public IndexReader getIndexReader() { return reader; } - /** Returns the atomic subReaders used by this searcher. */ - public IndexReader[] getSubReaders() { - return subReaders; - } - /** Expert: Returns one greater than the largest possible document number. * * @see org.apache.lucene.index.IndexReader#maxDoc() @@ -206,7 +197,7 @@ public class IndexSearcher { return reader.docFreq(term); } else { final ExecutionHelper runner = new ExecutionHelper(executor); - for(int i = 0; i < subReaders.length; i++) { + for(int i = 0; i < subSearchers.length; i++) { final IndexSearcher searchable = subSearchers[i]; runner.submit(new Callable() { public Integer call() throws IOException { @@ -369,9 +360,9 @@ public class IndexSearcher { final Lock lock = new ReentrantLock(); final ExecutionHelper runner = new ExecutionHelper(executor); - for (int i = 0; i < subReaders.length; i++) { // search each sub + for (int i = 0; i < subSearchers.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, docStarts[i])); + new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, leafContexts[i].docBase)); } int totalHits = 0; @@ -438,9 +429,9 @@ public class IndexSearcher { final FieldDocSortedHitQueue hq = new FieldDocSortedHitQueue(nDocs); final Lock lock = new ReentrantLock(); final ExecutionHelper runner = new ExecutionHelper(executor); - for (int i = 0; i < subReaders.length; i++) { // search each sub + for (int i = 0; i < subSearchers.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, docStarts[i])); + new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, leafContexts[i].docBase)); } int totalHits = 0; float maxScore = Float.NEGATIVE_INFINITY; @@ -484,27 +475,27 @@ public class IndexSearcher { // always use single thread: if (filter == null) { - for (int i = 0; i < subReaders.length; i++) { // search each subreader - collector.setNextReader(subReaders[i], docStarts[i]); - Scorer scorer = weight.scorer(subReaders[i], !collector.acceptsDocsOutOfOrder(), true); + for (int i = 0; i < leafContexts.length; i++) { // search each subreader + collector.setNextReader(leafContexts[i].reader, leafContexts[i].docBase); + Scorer scorer = weight.scorer(leafContexts[i], !collector.acceptsDocsOutOfOrder(), true); if (scorer != null) { scorer.score(collector); } } } else { - for (int i = 0; i < subReaders.length; i++) { // search each subreader - collector.setNextReader(subReaders[i], docStarts[i]); - searchWithFilter(subReaders[i], weight, filter, collector); + for (int i = 0; i < leafContexts.length; i++) { // search each subreader + collector.setNextReader(leafContexts[i].reader, leafContexts[i].docBase); + searchWithFilter(leafContexts[i], weight, filter, collector); } } } - private void searchWithFilter(IndexReader reader, Weight weight, + private void searchWithFilter(ReaderContext context, Weight weight, final Filter filter, final Collector collector) throws IOException { assert filter != null; - Scorer scorer = weight.scorer(reader, true, false); + Scorer scorer = weight.scorer(context, true, false); if (scorer == null) { return; } @@ -513,7 +504,7 @@ public class IndexSearcher { assert docID == -1 || docID == DocIdSetIterator.NO_MORE_DOCS; // CHECKME: use ConjunctionScorer here? - DocIdSet filterDocIdSet = filter.getDocIdSet(reader); + DocIdSet filterDocIdSet = filter.getDocIdSet(context); if (filterDocIdSet == null) { // this means the filter does not accept any documents. return; @@ -581,10 +572,10 @@ public class IndexSearcher { * @throws BooleanQuery.TooManyClauses */ protected Explanation explain(Weight weight, int doc) throws IOException { - int n = ReaderUtil.subIndex(doc, docStarts); - int deBasedDoc = doc - docStarts[n]; + int n = ReaderUtil.subIndex(doc, leafContexts); + int deBasedDoc = doc - leafContexts[n].docBase; - return weight.explain(subReaders[n], deBasedDoc); + return weight.explain(leafContexts[n], deBasedDoc); } private boolean fieldSortDoTrackScores; @@ -615,6 +606,14 @@ public class IndexSearcher { return query.weight(this); } + /** + * Returns this searchers the top-level {@link ReaderContext}. + * @see IndexReader#getTopReaderContext() + */ + /* Sugar for .getIndexReader().getTopReaderContext() */ + public ReaderContext getTopReaderContext() { + return readerContext; + } /** * A thread subclass for searching a single searchable diff --git a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java index eb4fcc1ae0d..38625194474 100644 --- a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java @@ -18,6 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.Bits; @@ -126,13 +127,13 @@ public class MatchAllDocsQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new MatchAllScorer(reader, similarity, this, - normsField != null ? reader.norms(normsField) : null); + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + return new MatchAllScorer(context.reader, similarity, this, + normsField != null ? context.reader.norms(normsField) : null); } @Override - public Explanation explain(IndexReader reader, int doc) { + public Explanation explain(ReaderContext context, int doc) { // explain query weight Explanation queryExpl = new ComplexExplanation (true, getValue(), "MatchAllDocsQuery, product of:"); diff --git a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java index 2eb23cd7bfd..42b2086ea3c 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.*; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -167,10 +168,10 @@ public class MultiPhraseQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { if (termArrays.size() == 0) // optimize zero-term case return null; - + final IndexReader reader = context.reader; final Bits delDocs = reader.getDeletedDocs(); PhraseQuery.PostingsAndFreq[] postingsFreqs = new PhraseQuery.PostingsAndFreq[termArrays.size()]; @@ -219,7 +220,7 @@ public class MultiPhraseQuery extends Query { if (slop == 0) { ExactPhraseScorer s = new ExactPhraseScorer(this, postingsFreqs, similarity, - reader.norms(field)); + reader.norms(field)); if (s.noDocs) { return null; } else { @@ -232,7 +233,7 @@ public class MultiPhraseQuery extends Query { } @Override - public Explanation explain(IndexReader reader, int doc) + public Explanation explain(ReaderContext context, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); result.setDescription("weight("+getQuery()+" in "+doc+"), product of:"); @@ -263,7 +264,7 @@ public class MultiPhraseQuery extends Query { fieldExpl.setDescription("fieldWeight("+getQuery()+" in "+doc+ "), product of:"); - Scorer scorer = scorer(reader, true, false); + Scorer scorer = scorer(context, true, false); if (scorer == null) { return new Explanation(0.0f, "no matching docs"); } @@ -283,7 +284,7 @@ public class MultiPhraseQuery extends Query { fieldExpl.addDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); - byte[] fieldNorms = reader.norms(field); + byte[] fieldNorms = context.reader.norms(field); float fieldNorm = fieldNorms!=null ? similarity.decodeNormValue(fieldNorms[doc]) : 1.0f; fieldNormExpl.setValue(fieldNorm); diff --git a/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java index 21b271a550b..6d591c8a984 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java @@ -19,8 +19,9 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.DocsEnum; @@ -104,7 +105,8 @@ public class MultiTermQueryWrapperFilter extends Filte * results. */ @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + final IndexReader reader = context.reader; final Fields fields = reader.fields(); if (fields == null) { // reader has no fields @@ -121,7 +123,7 @@ public class MultiTermQueryWrapperFilter extends Filte assert termsEnum != null; if (termsEnum.next() != null) { // fill into a OpenBitSet - final OpenBitSet bitSet = new OpenBitSet(reader.maxDoc()); + final OpenBitSet bitSet = new OpenBitSet(context.reader.maxDoc()); int termCount = 0; final Bits delDocs = reader.getDeletedDocs(); DocsEnum docsEnum = null; diff --git a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java index c5c287b84a8..7142461ef25 100644 --- a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.Set; import java.util.ArrayList; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.IndexReader; @@ -174,10 +175,10 @@ public class PhraseQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { if (terms.size() == 0) // optimize zero-term case return null; - + final IndexReader reader = context.reader; PostingsAndFreq[] postingsFreqs = new PostingsAndFreq[terms.size()]; final Bits delDocs = reader.getDeletedDocs(); for (int i = 0; i < terms.size(); i++) { @@ -206,7 +207,7 @@ public class PhraseQuery extends Query { if (slop == 0) { // optimize exact case ExactPhraseScorer s = new ExactPhraseScorer(this, postingsFreqs, similarity, - reader.norms(field)); + reader.norms(field)); if (s.noDocs) { return null; } else { @@ -215,12 +216,12 @@ public class PhraseQuery extends Query { } else { return new SloppyPhraseScorer(this, postingsFreqs, similarity, slop, - reader.norms(field)); + reader.norms(field)); } } @Override - public Explanation explain(IndexReader reader, int doc) + public Explanation explain(ReaderContext context, int doc) throws IOException { Explanation result = new Explanation(); @@ -267,7 +268,7 @@ public class PhraseQuery extends Query { fieldExpl.setDescription("fieldWeight("+field+":"+query+" in "+doc+ "), product of:"); - Scorer scorer = scorer(reader, true, false); + Scorer scorer = scorer(context, true, false); if (scorer == null) { return new Explanation(0.0f, "no matching docs"); } @@ -287,7 +288,7 @@ public class PhraseQuery extends Query { fieldExpl.addDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); - byte[] fieldNorms = reader.norms(field); + byte[] fieldNorms = context.reader.norms(field); float fieldNorm = fieldNorms!=null ? similarity.decodeNormValue(fieldNorms[doc]) : 1.0f; fieldNormExpl.setValue(fieldNorm); diff --git a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java index 3aa6d4d2245..a2c2c29eaa1 100644 --- a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java @@ -18,9 +18,7 @@ package org.apache.lucene.search; */ import java.io.IOException; - - -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; /** * Constrains search results to only match those which also match a provided @@ -48,12 +46,14 @@ public class QueryWrapperFilter extends Filter { } @Override - public DocIdSet getDocIdSet(final IndexReader reader) throws IOException { - final Weight weight = query.weight(new IndexSearcher(reader)); + public DocIdSet getDocIdSet(final ReaderContext context) throws IOException { + // get a private context that is used to rewrite, createWeight and score eventually + final ReaderContext privateContext = context.reader.getTopReaderContext(); + final Weight weight = query.weight(new IndexSearcher(privateContext)); return new DocIdSet() { @Override public DocIdSetIterator iterator() throws IOException { - return weight.scorer(reader, true, false); + return weight.scorer(privateContext, true, false); } @Override public boolean isCacheable() { return false; } diff --git a/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java b/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java index 4c8265155ea..68649be097a 100644 --- a/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java +++ b/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java @@ -17,6 +17,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.spans.SpanQuery; import org.apache.lucene.search.spans.Spans; import org.apache.lucene.util.OpenBitSet; @@ -52,8 +53,8 @@ public class SpanQueryFilter extends SpanFilter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - SpanFilterResult result = bitSpans(reader); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + SpanFilterResult result = bitSpans(context.reader); return result.getDocIdSet(); } diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index 6eb34c6eab9..bf8346cfb50 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -21,8 +21,10 @@ import java.io.IOException; import java.util.Set; import org.apache.lucene.index.DocsEnum; -import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.Term; import org.apache.lucene.search.Explanation.IDFExplanation; import org.apache.lucene.util.ToStringUtils; @@ -75,7 +77,8 @@ public class TermQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + final IndexReader reader = context.reader; DocsEnum docs = reader.termDocsEnum(reader.getDeletedDocs(), term.field(), term.bytes()); @@ -88,8 +91,9 @@ public class TermQuery extends Query { } @Override - public Explanation explain(IndexReader reader, int doc) + public Explanation explain(ReaderContext context, int doc) throws IOException { + final IndexReader reader = context.reader; ComplexExplanation result = new ComplexExplanation(); result.setDescription("weight("+getQuery()+" in "+doc+"), product of:"); diff --git a/lucene/src/java/org/apache/lucene/search/Weight.java b/lucene/src/java/org/apache/lucene/search/Weight.java index 1da8f5ef436..016904eb833 100644 --- a/lucene/src/java/org/apache/lucene/search/Weight.java +++ b/lucene/src/java/org/apache/lucene/search/Weight.java @@ -21,16 +21,26 @@ import java.io.IOException; import java.io.Serializable; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; /** * Expert: Calculate query weights and build query scorers. *

    - * The purpose of {@link Weight} is to ensure searching does not - * modify a {@link Query}, so that a {@link Query} instance can be reused.
    + * The purpose of {@link Weight} is to ensure searching does not modify a + * {@link Query}, so that a {@link Query} instance can be reused.
    * {@link IndexSearcher} dependent state of the query should reside in the * {@link Weight}.
    * {@link IndexReader} dependent state should reside in the {@link Scorer}. *

    + * Since {@link Weight} creates {@link Scorer} instances for a given + * {@link ReaderContext} ({@link #scorer(ReaderContext, boolean, boolean)}) + * callers must maintain the relationship between the searcher's top-level + * {@link ReaderContext} and the context used to create a {@link Scorer}. A + * {@link ReaderContext} used to create a {@link Scorer} should be a leaf + * context ({@link AtomicReaderContext}) of the searcher's top-level context, + * otherwise the scorer's state will be undefined. + *

    * A Weight is used in the following way: *

      *
    1. A Weight is constructed by a top-level query, given a @@ -41,9 +51,11 @@ import org.apache.lucene.index.IndexReader; * query. *
    2. The query normalization factor is passed to {@link #normalize(float)}. At * this point the weighting is complete. - *
    3. A Scorer is constructed by {@link #scorer(IndexReader,boolean,boolean)}. + *
    4. A Scorer is constructed by + * {@link #scorer(ReaderContext,boolean,boolean)}. *
    * + * * @since 2.9 */ public abstract class Weight implements Serializable { @@ -51,12 +63,12 @@ public abstract class Weight implements Serializable { /** * An explanation of the score computation for the named document. * - * @param reader sub-reader containing the give doc - * @param doc + * @param context the readers context to create the {@link Explanation} for. + * @param doc the document's id relative to the given context's reader * @return an Explanation for the score - * @throws IOException + * @throws IOException if an {@link IOException} occurs */ - public abstract Explanation explain(IndexReader reader, int doc) throws IOException; + public abstract Explanation explain(ReaderContext context, int doc) throws IOException; /** The query that this concerns. */ public abstract Query getQuery(); @@ -78,9 +90,12 @@ public abstract class Weight implements Serializable { * in-order.
    * NOTE: null can be returned if no documents will be scored by this * query. + * NOTE: Calling this method with a {@link ReaderContext} that is not a + * leaf context ({@link AtomicReaderContext}) of the searcher's top-level context + * used to create this {@link Weight} instance can cause undefined behavior. * - * @param reader - * the {@link IndexReader} for which to return the {@link Scorer}. + * @param context + * the {@link ReaderContext} for which to return the {@link Scorer}. * @param scoreDocsInOrder * specifies whether in-order scoring of documents is required. Note * that if set to false (i.e., out-of-order scoring is required), @@ -96,7 +111,8 @@ public abstract class Weight implements Serializable { * @return a {@link Scorer} which scores documents in/out-of order. * @throws IOException */ - public abstract Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, + // TODO make this context an AtomicContext if possible + public abstract Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException; /** The sum of squared weights of contained query clauses. */ @@ -106,7 +122,7 @@ public abstract class Weight implements Serializable { * Returns true iff this implementation scores docs only out of order. This * method is used in conjunction with {@link Collector}'s * {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and - * {@link #scorer(org.apache.lucene.index.IndexReader, boolean, boolean)} to + * {@link #scorer(ReaderContext, boolean, boolean)} to * create a matching {@link Scorer} instance for a given {@link Collector}, or * vice versa. *

    diff --git a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java index e1e39f3fd21..ecea73df689 100755 --- a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.Arrays; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.ComplexExplanation; import org.apache.lucene.search.Explanation; @@ -239,40 +240,40 @@ public class CustomScoreQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { // Pass true for "scoresDocsInOrder", because we // require in-order scoring, even if caller does not, // since we call advance on the valSrcScorers. Pass // false for "topScorer" because we will not invoke // score(Collector) on these scorers: - Scorer subQueryScorer = subQueryWeight.scorer(reader, true, false); + Scorer subQueryScorer = subQueryWeight.scorer(context, true, false); if (subQueryScorer == null) { return null; } Scorer[] valSrcScorers = new Scorer[valSrcWeights.length]; for(int i = 0; i < valSrcScorers.length; i++) { - valSrcScorers[i] = valSrcWeights[i].scorer(reader, true, topScorer); + valSrcScorers[i] = valSrcWeights[i].scorer(context, true, topScorer); } - return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorers); + return new CustomScorer(similarity, context.reader, this, subQueryScorer, valSrcScorers); } @Override - public Explanation explain(IndexReader reader, int doc) throws IOException { - Explanation explain = doExplain(reader, doc); + public Explanation explain(ReaderContext context, int doc) throws IOException { + Explanation explain = doExplain(context, doc); return explain == null ? new Explanation(0.0f, "no matching docs") : explain; } - private Explanation doExplain(IndexReader reader, int doc) throws IOException { - Explanation subQueryExpl = subQueryWeight.explain(reader, doc); + private Explanation doExplain(ReaderContext info, int doc) throws IOException { + Explanation subQueryExpl = subQueryWeight.explain(info, doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } // match Explanation[] valSrcExpls = new Explanation[valSrcWeights.length]; for(int i = 0; i < valSrcWeights.length; i++) { - valSrcExpls[i] = valSrcWeights[i].explain(reader, doc); + valSrcExpls[i] = valSrcWeights[i].explain(info, doc); } - Explanation customExp = CustomScoreQuery.this.getCustomScoreProvider(reader).customExplain(doc,subQueryExpl,valSrcExpls); + Explanation customExp = CustomScoreQuery.this.getCustomScoreProvider(info.reader).customExplain(doc,subQueryExpl,valSrcExpls); float sc = getValue() * customExp.getValue(); Explanation res = new ComplexExplanation( true, sc, CustomScoreQuery.this.toString() + ", product of:"); diff --git a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java index bf7a0216dcc..25af66e85d9 100644 --- a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java @@ -19,6 +19,7 @@ package org.apache.lucene.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.*; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.Bits; @@ -98,14 +99,14 @@ public class ValueSourceQuery extends Query { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new ValueSourceScorer(similarity, reader, this); + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + return new ValueSourceScorer(similarity, context.reader, this); } /*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */ @Override - public Explanation explain(IndexReader reader, int doc) throws IOException { - DocValues vals = valSrc.getValues(reader); + public Explanation explain(ReaderContext context, int doc) throws IOException { + DocValues vals = valSrc.getValues(context.reader); float sc = queryWeight * vals.floatVal(doc); Explanation result = new ComplexExplanation( diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java index 37bb6c7d32c..1bb3b7a5f95 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java @@ -17,7 +17,7 @@ package org.apache.lucene.search.payloads; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.IndexSearcher; @@ -143,10 +143,10 @@ public class PayloadNearQuery extends SpanNearQuery { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new PayloadNearSpanScorer(query.getSpans(reader), this, - similarity, reader.norms(query.getField())); + return new PayloadNearSpanScorer(query.getSpans(context.reader), this, + similarity, context.reader.norms(query.getField())); } } diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java index 1d251447132..4aa29583473 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java @@ -17,9 +17,9 @@ package org.apache.lucene.search.payloads; * limitations under the License. */ +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Weight; @@ -74,10 +74,10 @@ public class PayloadTermQuery extends SpanTermQuery { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new PayloadTermSpanScorer((TermSpans) query.getSpans(reader), - this, similarity, reader.norms(query.getField())); + return new PayloadTermSpanScorer((TermSpans) query.getSpans(context.reader), + this, similarity, context.reader.norms(query.getField())); } protected class PayloadTermSpanScorer extends SpanScorer { diff --git a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java index 37451fecb2d..6142ad42453 100644 --- a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java +++ b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java @@ -17,7 +17,7 @@ package org.apache.lucene.search.spans; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.search.Explanation.IDFExplanation; @@ -72,13 +72,13 @@ public class SpanWeight extends Weight { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new SpanScorer(query.getSpans(reader), this, similarity, reader + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + return new SpanScorer(query.getSpans(context.reader), this, similarity, context.reader .norms(query.getField())); } @Override - public Explanation explain(IndexReader reader, int doc) + public Explanation explain(ReaderContext context, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); @@ -111,12 +111,12 @@ public class SpanWeight extends Weight { fieldExpl.setDescription("fieldWeight("+field+":"+query.toString(field)+ " in "+doc+"), product of:"); - Explanation tfExpl = ((SpanScorer)scorer(reader, true, false)).explain(doc); + Explanation tfExpl = ((SpanScorer)scorer(context, true, false)).explain(doc); fieldExpl.addDetail(tfExpl); fieldExpl.addDetail(idfExpl); Explanation fieldNormExpl = new Explanation(); - byte[] fieldNorms = reader.norms(field); + byte[] fieldNorms = context.reader.norms(field); float fieldNorm = fieldNorms!=null ? similarity.decodeNormValue(fieldNorms[doc]) : 1.0f; fieldNormExpl.setValue(fieldNorm); diff --git a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java index 430fc9bf38e..bc03c9a9376 100644 --- a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java +++ b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java @@ -19,9 +19,13 @@ package org.apache.lucene.util; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.CompositeReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; /** * Common util methods for dealing with {@link IndexReader}s. @@ -148,6 +152,67 @@ public final class ReaderUtil { .toArray(new IndexReader[subReadersList.size()]); return subReaders[subIndex]; } + + public static ReaderContext buildReaderContext(IndexReader reader) { + return new ReaderContextBuilder(reader).build(); + } + + public static class ReaderContextBuilder { + private final IndexReader reader; + private final AtomicReaderContext[] leaves; + private int leafOrd = 0; + private int leafDocBase = 0; + public ReaderContextBuilder(IndexReader reader) { + this.reader = reader; + leaves = new AtomicReaderContext[numLeaves(reader)]; + } + + public ReaderContext build() { + return build(null, reader, 0, 0); + } + + private ReaderContext build(CompositeReaderContext parent, IndexReader reader, int ord, int docBase) { + IndexReader[] sequentialSubReaders = reader.getSequentialSubReaders(); + if (sequentialSubReaders == null) { + AtomicReaderContext atomic = new AtomicReaderContext(parent, reader, ord, docBase, leafOrd, leafDocBase); + leaves[leafOrd++] = atomic; + leafDocBase += reader.maxDoc(); + return atomic; + } else { + ReaderContext[] children = new ReaderContext[sequentialSubReaders.length]; + final CompositeReaderContext newParent; + if (parent == null) { + newParent = new CompositeReaderContext(reader, children, leaves); + } else { + newParent = new CompositeReaderContext(parent, reader, ord, docBase, children); + } + + int newDocBase = 0; + for (int i = 0; i < sequentialSubReaders.length; i++) { + build(newParent, sequentialSubReaders[i], i, newDocBase); + newDocBase += sequentialSubReaders[i].maxDoc(); + } + return newParent; + } + } + + private int numLeaves(IndexReader reader) { + final AtomicInteger numLeaves = new AtomicInteger(); + try { + new Gather(reader) { + @Override + protected void add(int base, IndexReader r) { + numLeaves.incrementAndGet(); + } + }.run(); + } catch (IOException ioe) { + // won't happen + throw new RuntimeException(ioe); + } + return numLeaves.get(); + } + + } /** @@ -175,4 +240,30 @@ public final class ReaderUtil { } return hi; } + + /** + * Returns index of the searcher/reader for document n in the + * array used to construct this searcher/reader. + */ + public static int subIndex(int n, AtomicReaderContext[] leaves) { // find + // searcher/reader for doc n: + int size = leaves.length; + int lo = 0; // search starts array + int hi = size - 1; // for first element less than n, return its index + while (hi >= lo) { + int mid = (lo + hi) >>> 1; + int midValue = leaves[mid].docBase; + if (n < midValue) + hi = mid - 1; + else if (n > midValue) + lo = mid + 1; + else { // found a match + while (mid + 1 < size && leaves[mid + 1].docBase == midValue) { + mid++; // scan to last match + } + return mid; + } + } + return hi; + } } diff --git a/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java b/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java index 80df5720f0f..5acd441b18d 100644 --- a/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java +++ b/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java @@ -20,7 +20,8 @@ package org.apache.lucene.search; import java.io.IOException; import junit.framework.Assert; -import org.apache.lucene.index.IndexReader; + +import org.apache.lucene.index.IndexReader.ReaderContext; /** * A unit test helper class to test when the filter is getting cached and when it is not. @@ -41,10 +42,10 @@ public class CachingWrapperFilterHelper extends CachingWrapperFilter { } @Override - public synchronized DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public synchronized DocIdSet getDocIdSet(ReaderContext context) throws IOException { final int saveMissCount = missCount; - DocIdSet docIdSet = super.getDocIdSet(reader); + DocIdSet docIdSet = super.getDocIdSet(context); if (shouldHaveCache) { Assert.assertEquals("Cache should have data ", saveMissCount, missCount); diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index daa24c91658..25c43b69921 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.PriorityQueue; @@ -152,7 +153,7 @@ final class JustCompileSearch { // still added here in case someone will add abstract methods in the future. @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { return null; } } @@ -281,7 +282,7 @@ final class JustCompileSearch { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { return null; } } @@ -333,7 +334,7 @@ final class JustCompileSearch { static final class JustCompileWeight extends Weight { @Override - public Explanation explain(IndexReader reader, int doc) throws IOException { + public Explanation explain(ReaderContext context, int doc) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } @@ -358,7 +359,7 @@ final class JustCompileSearch { } @Override - public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/MockFilter.java b/lucene/src/test/org/apache/lucene/search/MockFilter.java index 36b4247fa91..1ac9207e9ef 100644 --- a/lucene/src/test/org/apache/lucene/search/MockFilter.java +++ b/lucene/src/test/org/apache/lucene/search/MockFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.DocIdBitSet; import java.util.BitSet; @@ -25,7 +25,7 @@ public class MockFilter extends Filter { private boolean wasCalled; @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { wasCalled = true; return new DocIdBitSet(new BitSet()); } diff --git a/lucene/src/test/org/apache/lucene/search/QueryUtils.java b/lucene/src/test/org/apache/lucene/search/QueryUtils.java index c2c8b17fc52..fd52b748a74 100644 --- a/lucene/src/test/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test/org/apache/lucene/search/QueryUtils.java @@ -12,6 +12,8 @@ import junit.framework.Assert; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; @@ -210,14 +212,22 @@ public class QueryUtils { throw e2; } } - + + private static AtomicReaderContext[] getLeaves(IndexSearcher searcher) { + ReaderContext topLevelReaderContext = searcher.getTopReaderContext(); + if (topLevelReaderContext.isAtomic) { + return new AtomicReaderContext[] {(AtomicReaderContext) topLevelReaderContext}; + } else { + return topLevelReaderContext.leaves(); + } + } /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc * and ensure a hitcollector receives same docs and scores */ public static void checkSkipTo(final Query q, final IndexSearcher s) throws IOException { //System.out.println("Checking "+q); - + final AtomicReaderContext[] context = getLeaves(s); if (q.weight(s).scoresDocsOutOfOrder()) return; // in this case order of skipTo() might differ from that of next(). final int skip_op = 0; @@ -247,8 +257,8 @@ public class QueryUtils { s.search(q, new Collector() { private Scorer sc; - private IndexReader reader; private Scorer scorer; + private int leafPtr; @Override public void setScorer(Scorer scorer) throws IOException { @@ -262,7 +272,7 @@ public class QueryUtils { try { if (scorer == null) { Weight w = q.weight(s); - scorer = w.scorer(reader, true, false); + scorer = w.scorer(context[leafPtr], true, false); } int op = order[(opidx[0]++) % order.length]; @@ -305,14 +315,17 @@ public class QueryUtils { // previous reader, hits NO_MORE_DOCS if (lastReader[0] != null) { final IndexReader previousReader = lastReader[0]; - Weight w = q.weight(new IndexSearcher(previousReader)); - Scorer scorer = w.scorer(previousReader, true, false); + IndexSearcher indexSearcher = new IndexSearcher(previousReader); + Weight w = q.weight(indexSearcher); + Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); } + leafPtr++; } - this.reader = lastReader[0] = reader; + lastReader[0] = reader; + assert context[leafPtr].reader == reader; this.scorer = null; lastDoc[0] = -1; } @@ -327,8 +340,9 @@ public class QueryUtils { // confirm that skipping beyond the last doc, on the // previous reader, hits NO_MORE_DOCS final IndexReader previousReader = lastReader[0]; - Weight w = q.weight(new IndexSearcher(previousReader)); - Scorer scorer = w.scorer(previousReader, true, false); + IndexSearcher indexSearcher = new IndexSearcher(previousReader); + Weight w = q.weight(indexSearcher); + Scorer scorer = w.scorer(previousReader.getTopReaderContext() , true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -343,10 +357,10 @@ public class QueryUtils { final float maxDiff = 1e-3f; final int lastDoc[] = {-1}; final IndexReader lastReader[] = {null}; - + final ReaderContext[] context = getLeaves(s); s.search(q,new Collector() { private Scorer scorer; - private IndexReader reader; + private int leafPtr; @Override public void setScorer(Scorer scorer) throws IOException { this.scorer = scorer; @@ -358,7 +372,7 @@ public class QueryUtils { long startMS = System.currentTimeMillis(); for (int i=lastDoc[0]+1; i<=doc; i++) { Weight w = q.weight(s); - Scorer scorer = w.scorer(reader, true, false); + Scorer scorer = w.scorer(context[leafPtr], true, false); Assert.assertTrue("query collected "+doc+" but skipTo("+i+") says no more docs!",scorer.advance(i) != DocIdSetIterator.NO_MORE_DOCS); Assert.assertEquals("query collected "+doc+" but skipTo("+i+") got to "+scorer.docID(),doc,scorer.docID()); float skipToScore = scorer.score(); @@ -383,15 +397,17 @@ public class QueryUtils { // previous reader, hits NO_MORE_DOCS if (lastReader[0] != null) { final IndexReader previousReader = lastReader[0]; - Weight w = q.weight(new IndexSearcher(previousReader)); - Scorer scorer = w.scorer(previousReader, true, false); + IndexSearcher indexSearcher = new IndexSearcher(previousReader); + Weight w = q.weight(indexSearcher); + Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); } + leafPtr++; } - this.reader = lastReader[0] = reader; + lastReader[0] = reader; lastDoc[0] = -1; } @Override @@ -404,8 +420,9 @@ public class QueryUtils { // confirm that skipping beyond the last doc, on the // previous reader, hits NO_MORE_DOCS final IndexReader previousReader = lastReader[0]; - Weight w = q.weight(new IndexSearcher(previousReader)); - Scorer scorer = w.scorer(previousReader, true, false); + IndexSearcher indexSearcher = new IndexSearcher(previousReader); + Weight w = q.weight(indexSearcher); + Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); diff --git a/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java b/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java index bd1df4e3ee0..2625cda5b67 100644 --- a/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java +++ b/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.DocIdBitSet; import java.util.BitSet; @@ -31,8 +31,8 @@ public class SingleDocTestFilter extends Filter { } @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - BitSet bits = new BitSet(reader.maxDoc()); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + BitSet bits = new BitSet(context.reader.maxDoc()); bits.set(doc); return new DocIdBitSet(bits); } diff --git a/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java b/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java index f56e440b0cd..a38fe553a26 100644 --- a/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java +++ b/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java @@ -23,6 +23,8 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.SerialMergeScheduler; import org.apache.lucene.index.SlowMultiReaderWrapper; @@ -40,20 +42,20 @@ public class TestCachingWrapperFilter extends LuceneTestCase { writer.close(); IndexReader reader = IndexReader.open(dir, true); - + ReaderContext context = reader.getTopReaderContext(); MockFilter filter = new MockFilter(); CachingWrapperFilter cacher = new CachingWrapperFilter(filter); // first time, nested filter is called - cacher.getDocIdSet(reader); + cacher.getDocIdSet(context); assertTrue("first time", filter.wasCalled()); // make sure no exception if cache is holding the wrong docIdSet - cacher.getDocIdSet(reader); + cacher.getDocIdSet(context); // second time, nested filter should not be called filter.clear(); - cacher.getDocIdSet(reader); + cacher.getDocIdSet(context); assertFalse("second time", filter.wasCalled()); reader.close(); @@ -66,17 +68,18 @@ public class TestCachingWrapperFilter extends LuceneTestCase { writer.close(); IndexReader reader = IndexReader.open(dir, true); + ReaderContext context = reader.getTopReaderContext(); final Filter filter = new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { return null; } }; CachingWrapperFilter cacher = new CachingWrapperFilter(filter); // the caching filter should return the empty set constant - assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(reader)); + assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(context)); reader.close(); dir.close(); @@ -88,10 +91,11 @@ public class TestCachingWrapperFilter extends LuceneTestCase { writer.close(); IndexReader reader = IndexReader.open(dir, true); + ReaderContext context = reader.getTopReaderContext(); final Filter filter = new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { return new DocIdSet() { @Override public DocIdSetIterator iterator() { @@ -103,16 +107,17 @@ public class TestCachingWrapperFilter extends LuceneTestCase { CachingWrapperFilter cacher = new CachingWrapperFilter(filter); // the caching filter should return the empty set constant - assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(reader)); + assertSame(DocIdSet.EMPTY_DOCIDSET, cacher.getDocIdSet(context)); reader.close(); dir.close(); } private static void assertDocIdSetCacheable(IndexReader reader, Filter filter, boolean shouldCacheable) throws IOException { + ReaderContext context = reader.getTopReaderContext(); final CachingWrapperFilter cacher = new CachingWrapperFilter(filter); - final DocIdSet originalSet = filter.getDocIdSet(reader); - final DocIdSet cachedSet = cacher.getDocIdSet(reader); + final DocIdSet originalSet = filter.getDocIdSet(context); + final DocIdSet cachedSet = cacher.getDocIdSet(context); assertTrue(cachedSet.isCacheable()); assertEquals(shouldCacheable, originalSet.isCacheable()); //System.out.println("Original: "+originalSet.getClass().getName()+" -- cached: "+cachedSet.getClass().getName()); @@ -140,7 +145,7 @@ public class TestCachingWrapperFilter extends LuceneTestCase { // a openbitset filter is always cacheable assertDocIdSetCacheable(reader, new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { return new OpenBitSet(); } }, true); diff --git a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java index b89b6897c8a..1b89d4dd7dc 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; import java.text.DecimalFormat; @@ -163,9 +164,9 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { dq.add(tq("dek", "DOES_NOT_EXIST")); QueryUtils.check(random, dq, s); - + assertTrue(s.getTopReaderContext().isAtomic); final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer(s.getIndexReader(), true, false); + final Scorer ds = dw.scorer(s.getTopReaderContext(), true, false); final boolean skipOk = ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS; if (skipOk) { fail("firsttime skipTo found a match? ... " @@ -177,11 +178,10 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { final DisjunctionMaxQuery dq = new DisjunctionMaxQuery(0.0f); dq.add(tq("dek", "albino")); dq.add(tq("dek", "DOES_NOT_EXIST")); - + assertTrue(s.getTopReaderContext().isAtomic); QueryUtils.check(random, dq, s); - final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer(s.getIndexReader(), true, false); + final Scorer ds = dw.scorer(s.getTopReaderContext(), true, false); assertTrue("firsttime skipTo found no match", ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS); assertEquals("found wrong docid", "d4", r.document(ds.docID()).get("id")); diff --git a/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java b/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java index 78f517c67c7..5ff89d5c888 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java +++ b/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java @@ -28,6 +28,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -114,7 +115,7 @@ public class TestDocIdSet extends LuceneTestCase { // Now search w/ a Filter which returns a null DocIdSet Filter f = new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { return null; } }; diff --git a/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java b/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java index ef0bf485aff..dd1655ad2a0 100644 --- a/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; @@ -87,7 +88,7 @@ public class TestFilteredQuery extends LuceneTestCase { private static Filter newStaticFilterB() { return new Filter() { @Override - public DocIdSet getDocIdSet (IndexReader reader) { + public DocIdSet getDocIdSet (ReaderContext context) { BitSet bitset = new BitSet(5); bitset.set (1); bitset.set (3); @@ -158,7 +159,7 @@ public class TestFilteredQuery extends LuceneTestCase { private static Filter newStaticFilterA() { return new Filter() { @Override - public DocIdSet getDocIdSet (IndexReader reader) { + public DocIdSet getDocIdSet (ReaderContext context) { BitSet bitset = new BitSet(5); bitset.set(0, 5); return new DocIdBitSet(bitset); @@ -216,7 +217,7 @@ public class TestFilteredQuery extends LuceneTestCase { bq.add(new TermQuery(new Term("field", "two")), BooleanClause.Occur.SHOULD); ScoreDoc[] hits = searcher.search(query, 1000).scoreDocs; assertEquals(1, hits.length); - QueryUtils.check(random, query,searcher); + QueryUtils.check(random, query, searcher); } } diff --git a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java index 951abdd246c..a4b02fa9592 100644 --- a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java +++ b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java @@ -25,6 +25,8 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -33,6 +35,7 @@ import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.util.OpenBitSet; + /** * */ @@ -59,7 +62,7 @@ public class TestFilteredSearch extends LuceneTestCase { directory.close(); } - public void searchFiltered(IndexWriter writer, Directory directory, SimpleDocIdSetFilter filter, boolean optimize) { + public void searchFiltered(IndexWriter writer, Directory directory, Filter filter, boolean optimize) { try { for (int i = 0; i < 60; i++) {//Simple docs Document doc = new Document(); @@ -75,7 +78,6 @@ public class TestFilteredSearch extends LuceneTestCase { IndexSearcher indexSearcher = new IndexSearcher(directory, true); - filter.setTopReader(indexSearcher.getIndexReader()); ScoreDoc[] hits = indexSearcher.search(booleanQuery, filter, 1000).scoreDocs; assertEquals("Number of matched documents", 1, hits.length); indexSearcher.close(); @@ -89,20 +91,17 @@ public class TestFilteredSearch extends LuceneTestCase { public static final class SimpleDocIdSetFilter extends Filter { private final int[] docs; private int index; - private IndexReader topReader; + public SimpleDocIdSetFilter(int[] docs) { this.docs = docs; } - public void setTopReader(IndexReader r) { - topReader = r; - } - @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { + assert context.isAtomic; final OpenBitSet set = new OpenBitSet(); - int docBase = topReader.getSubReaderDocBase(reader); - final int limit = docBase+reader.maxDoc(); + int docBase = ((AtomicReaderContext)context).docBase; + final int limit = docBase+context.reader.maxDoc(); for (;index < docs.length; index++) { final int docId = docs[index]; if(docId > limit) diff --git a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java index 699e4c20f8c..f4b330e8fe9 100644 --- a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java +++ b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java @@ -177,13 +177,13 @@ public class TestNumericRangeQuery32 extends LuceneTestCase { @Test public void testInverseRange() throws Exception { NumericRangeFilter f = NumericRangeFilter.newIntRange("field8", 8, 1000, -1000, true, true); - assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); f = NumericRangeFilter.newIntRange("field8", 8, Integer.MAX_VALUE, null, false, false); assertSame("A exclusive range starting with Integer.MAX_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); f = NumericRangeFilter.newIntRange("field8", 8, null, Integer.MIN_VALUE, false, false); assertSame("A exclusive range ending with Integer.MIN_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); } @Test diff --git a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java index 63a3409a8c6..2e5c3e8b256 100644 --- a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java +++ b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java @@ -182,13 +182,14 @@ public class TestNumericRangeQuery64 extends LuceneTestCase { @Test public void testInverseRange() throws Exception { NumericRangeFilter f = NumericRangeFilter.newLongRange("field8", 8, 1000L, -1000L, true, true); - assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, + f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); f = NumericRangeFilter.newLongRange("field8", 8, Long.MAX_VALUE, null, false, false); assertSame("A exclusive range starting with Long.MAX_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); f = NumericRangeFilter.newLongRange("field8", 8, null, Long.MIN_VALUE, false, false); assertSame("A exclusive range ending with Long.MIN_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()))); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); } @Test diff --git a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java index 7aba01f55ee..364b452ce23 100755 --- a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java +++ b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java @@ -7,6 +7,7 @@ import java.util.BitSet; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -141,7 +142,7 @@ public class TestScorerPerf extends LuceneTestCase { final BitSet rnd = sets[random.nextInt(sets.length)]; Query q = new ConstantScoreQuery(new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) { + public DocIdSet getDocIdSet(ReaderContext context) { return new DocIdBitSet(rnd); } }); diff --git a/lucene/src/test/org/apache/lucene/search/TestSort.java b/lucene/src/test/org/apache/lucene/search/TestSort.java index a4b22d654e0..b0889f21332 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSort.java +++ b/lucene/src/test/org/apache/lucene/search/TestSort.java @@ -34,6 +34,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; @@ -687,9 +688,9 @@ public class TestSort extends LuceneTestCase implements Serializable { // a filter that only allows through the first hit Filter filt = new Filter() { @Override - public DocIdSet getDocIdSet(IndexReader reader) throws IOException { - BitSet bs = new BitSet(reader.maxDoc()); - bs.set(0, reader.maxDoc()); + public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + BitSet bs = new BitSet(context.reader.maxDoc()); + bs.set(0, context.reader.maxDoc()); bs.set(docs1.scoreDocs[0].doc); return new DocIdBitSet(bs); } diff --git a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java index 53900f67b84..7265ada5b1c 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java @@ -28,6 +28,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.SlowMultiReaderWrapper; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; public class TestTermScorer extends LuceneTestCase { @@ -71,7 +72,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); - Scorer ts = weight.scorer(indexSearcher.getIndexReader(), true, true); + Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); // we have 2 documents with the term all in them, one document for all the // other values final List docs = new ArrayList(); @@ -132,7 +133,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); - Scorer ts = weight.scorer(indexSearcher.getIndexReader(), true, true); + Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); assertTrue("next did not return a doc", ts.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); assertTrue("score is not correct", ts.score() == 1.6931472f); @@ -150,7 +151,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); - Scorer ts = weight.scorer(indexSearcher.getIndexReader(), true, true); + Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); assertTrue("Didn't skip", ts.advance(3) != DocIdSetIterator.NO_MORE_DOCS); // The next doc should be doc 5 assertTrue("doc should be number 5", ts.docID() == 5); diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java index d5b6b406a05..fc3fb442bab 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java @@ -168,7 +168,7 @@ public class TestNearSpansOrdered extends LuceneTestCase { public void testSpanNearScorerSkipTo1() throws Exception { SpanNearQuery q = makeQuery(); Weight w = q.weight(searcher); - Scorer s = w.scorer(searcher.getIndexReader(), true, false); + Scorer s = w.scorer(searcher.getTopReaderContext(), true, false); assertEquals(1, s.advance(1)); } /** @@ -177,7 +177,7 @@ public class TestNearSpansOrdered extends LuceneTestCase { */ public void testSpanNearScorerExplain() throws Exception { SpanNearQuery q = makeQuery(); - Explanation e = q.weight(searcher).explain(searcher.getIndexReader(), 1); + Explanation e = q.weight(searcher).explain(searcher.getTopReaderContext(), 1); assertTrue("Scorer explanation value for doc#1 isn't positive: " + e.toString(), 0.0f < e.getValue()); diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java index ac96892d5a0..9d3c83adbae 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java @@ -29,6 +29,7 @@ import org.apache.lucene.store.Directory; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.RandomIndexWriter; @@ -420,7 +421,7 @@ public class TestSpans extends LuceneTestCase { } }; - Scorer spanScorer = snq.weight(searcher).scorer(new SlowMultiReaderWrapper(searcher.getIndexReader()), true, false); + Scorer spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), true, false); assertTrue("first doc", spanScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); assertEquals("first doc number", spanScorer.docID(), 11); diff --git a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java index fc1016597a7..24938cbb9c2 100755 --- a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java +++ b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java @@ -1,5 +1,8 @@ package org.apache.solr.request; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; @@ -67,10 +70,7 @@ class PerSegmentSingleValuedFaceting { // reuse the translation logic to go from top level set to per-segment set baseSet = docs.getTopFilter(); - SolrIndexReader topReader = searcher.getReader(); - final SolrIndexReader[] leafReaders = topReader.getLeafReaders(); - int[] offsets = topReader.getLeafOffsets(); - + final AtomicReaderContext[] leaves = searcher.getTopReaderContext().leaves(); // The list of pending tasks that aren't immediately submitted // TODO: Is there a completion service, or a delegating executor that can // limit the number of concurrent tasks submitted to a bigger executor? @@ -78,8 +78,8 @@ class PerSegmentSingleValuedFaceting { int threads = nThreads <= 0 ? Integer.MAX_VALUE : nThreads; - for (int i=0; i task = new Callable() { public SegFacet call() throws Exception { @@ -101,7 +101,7 @@ class PerSegmentSingleValuedFaceting { // now merge the per-segment results PriorityQueue queue = new PriorityQueue() { { - initialize(leafReaders.length); + initialize(leaves.length); } @Override protected boolean lessThan(SegFacet a, SegFacet b) { @@ -112,7 +112,7 @@ class PerSegmentSingleValuedFaceting { boolean hasMissingCount=false; int missingCount=0; - for (int i=0; i 10 ); // found something... diff --git a/solr/src/test/org/apache/solr/search/TestDocSet.java b/solr/src/test/org/apache/solr/search/TestDocSet.java index e52aecbf115..280e58d39ae 100644 --- a/solr/src/test/org/apache/solr/search/TestDocSet.java +++ b/solr/src/test/org/apache/solr/search/TestDocSet.java @@ -26,6 +26,7 @@ import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.OpenBitSetIterator; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.FilterIndexReader; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.MultiReader; import org.apache.lucene.search.Filter; import org.apache.lucene.search.DocIdSet; @@ -404,6 +405,7 @@ public class TestDocSet extends LuceneTestCase { } public void doFilterTest(SolrIndexReader reader) throws IOException { + ReaderContext topLevelContext = reader.getTopReaderContext(); OpenBitSet bs = getRandomSet(reader.maxDoc(), rand.nextInt(reader.maxDoc()+1)); DocSet a = new BitDocSet(bs); DocSet b = getIntDocSet(bs); @@ -412,23 +414,23 @@ public class TestDocSet extends LuceneTestCase { Filter fb = b.getTopFilter(); // test top-level - DocIdSet da = fa.getDocIdSet(reader); - DocIdSet db = fb.getDocIdSet(reader); + DocIdSet da = fa.getDocIdSet(topLevelContext); + DocIdSet db = fb.getDocIdSet(topLevelContext); doTestIteratorEqual(da, db); // first test in-sequence sub readers - for (SolrIndexReader sir : reader.getLeafReaders()) { - da = fa.getDocIdSet(sir); - db = fb.getDocIdSet(sir); + for (ReaderContext readerInfo : topLevelContext.leaves()) { + da = fa.getDocIdSet(readerInfo); + db = fb.getDocIdSet(readerInfo); doTestIteratorEqual(da, db); } - int nReaders = reader.getLeafReaders().length; + int nReaders = topLevelContext.leaves().length; // now test out-of-sequence sub readers for (int i=0; i r.numDocs()); // should have deletions - assertTrue(r.getLeafReaders().length > 1); // more than 1 segment + assertFalse(r.getTopReaderContext().isAtomic); // more than 1 segment sr.close(); assertU(commit("expungeDeletes","true")); @@ -254,7 +254,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 { r = sr.getSearcher().getReader(); assertEquals(r.maxDoc(), r.numDocs()); // no deletions assertEquals(4,r.maxDoc()); // no dups - assertTrue(r.getLeafReaders().length > 1); // still more than 1 segment + assertFalse(r.getTopReaderContext().isAtomic); //still more than 1 segment sr.close(); } From 9557559df07057b292ff5fd3023a8f6bcab05c1a Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Wed, 5 Jan 2011 21:04:28 +0000 Subject: [PATCH 004/252] LUCENE-2831: use int[] instead of AtomicInteger git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055638 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/java/org/apache/lucene/util/ReaderUtil.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java index bc03c9a9376..701cfee2368 100644 --- a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java +++ b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java @@ -19,7 +19,6 @@ package org.apache.lucene.util; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; import java.io.IOException; import org.apache.lucene.index.IndexReader; @@ -197,19 +196,19 @@ public final class ReaderUtil { } private int numLeaves(IndexReader reader) { - final AtomicInteger numLeaves = new AtomicInteger(); + final int[] numLeaves = new int[1]; try { new Gather(reader) { @Override protected void add(int base, IndexReader r) { - numLeaves.incrementAndGet(); + numLeaves[0]++; } }.run(); } catch (IOException ioe) { // won't happen throw new RuntimeException(ioe); } - return numLeaves.get(); + return numLeaves[0]; } } From 84b4473205e2e1d4f14d3bd407b75945ec579472 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 5 Jan 2011 21:39:42 +0000 Subject: [PATCH 005/252] LUCENE-2756: add de morgan test (against IS w/ ES) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055652 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/search/TestBooleanQuery.java | 56 +++++++++++++++++-- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java b/lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java index 4fa2a54440e..870a5eb0ac8 100644 --- a/lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestBooleanQuery.java @@ -17,13 +17,21 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.RandomIndexWriter; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.MultiReader; +import org.apache.lucene.index.RandomIndexWriter; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; -import org.apache.lucene.index.Term; +import org.apache.lucene.util.NamedThreadFactory; public class TestBooleanQuery extends LuceneTestCase { @@ -116,5 +124,45 @@ public class TestBooleanQuery extends LuceneTestCase { w.close(); dir.close(); } - + + public void testDeMorgan() throws Exception { + Directory dir1 = newDirectory(); + RandomIndexWriter iw1 = new RandomIndexWriter(random, dir1); + Document doc1 = new Document(); + doc1.add(newField("field", "foo bar", Field.Index.ANALYZED)); + iw1.addDocument(doc1); + IndexReader reader1 = iw1.getReader(); + iw1.close(); + + Directory dir2 = newDirectory(); + RandomIndexWriter iw2 = new RandomIndexWriter(random, dir2); + Document doc2 = new Document(); + doc2.add(newField("field", "foo baz", Field.Index.ANALYZED)); + iw2.addDocument(doc2); + IndexReader reader2 = iw2.getReader(); + iw2.close(); + + QueryParser qp = new QueryParser(TEST_VERSION_CURRENT, "field", new MockAnalyzer()); + qp.setMultiTermRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE); + + MultiReader multireader = new MultiReader(reader1, reader2); + IndexSearcher searcher = new IndexSearcher(multireader); + assertEquals(0, searcher.search(qp.parse("+foo -ba*"), 10).totalHits); + + final ExecutorService es = Executors.newCachedThreadPool(new NamedThreadFactory("NRT search threads")); + searcher = new IndexSearcher(multireader, es); + if (VERBOSE) + System.out.println("rewritten form: " + searcher.rewrite(qp.parse("+foo -ba*"))); + assertEquals(0, searcher.search(qp.parse("+foo -ba*"), 10).totalHits); + es.shutdown(); + es.awaitTermination(1, TimeUnit.SECONDS); + + multireader.close(); + reader1.close(); + reader2.close(); + dir1.close(); + dir2.close(); + } } + + From 5e009c8a1739650d33bb44513d71d69317ed1e78 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Wed, 5 Jan 2011 21:57:30 +0000 Subject: [PATCH 006/252] tests: start w/ absolute path to find solr root git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055659 13f79535-47bb-0310-9956-ffa450edef68 --- solr/src/test/org/apache/solr/SolrTestCaseJ4.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/src/test/org/apache/solr/SolrTestCaseJ4.java b/solr/src/test/org/apache/solr/SolrTestCaseJ4.java index 2906e46c630..9eb858da5a6 100755 --- a/solr/src/test/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/src/test/org/apache/solr/SolrTestCaseJ4.java @@ -1052,7 +1052,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase { static String determineSourceHome() { // ugly, ugly hack to determine the example home without depending on the CWD // this is needed for example/multicore tests which reside outside the classpath - File base = getFile("solr/conf/"); + File base = getFile("solr/conf/").getAbsoluteFile(); while (!new File(base, "solr/CHANGES.txt").exists()) { base = base.getParentFile(); } From 4140f73774e6c8f1509e13d3e196847500204f0b Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Thu, 6 Jan 2011 01:03:00 +0000 Subject: [PATCH 007/252] LUCENE-2831: fix isTopLevel git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055695 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/lucene/index/IndexReader.java | 17 ++++++----------- .../org/apache/lucene/search/IndexSearcher.java | 5 +---- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index ac0f203a8fb..fb09bbc5917 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -1471,13 +1471,13 @@ public abstract class IndexReader implements Cloneable,Closeable { public final int ordInParent; ReaderContext(ReaderContext parent, IndexReader reader, - boolean isAtomic, boolean isTopLevel, int ordInParent, int docBaseInParent) { + boolean isAtomic, int ordInParent, int docBaseInParent) { this.parent = parent; this.reader = reader; this.isAtomic = isAtomic; this.docBaseInParent = docBaseInParent; this.ordInParent = ordInParent; - this.isTopLevel = isTopLevel; + this.isTopLevel = parent==null; } /** @@ -1533,7 +1533,7 @@ public abstract class IndexReader implements Cloneable,Closeable { private CompositeReaderContext(ReaderContext parent, IndexReader reader, int ordInParent, int docbaseInParent, ReaderContext[] children, AtomicReaderContext[] leaves) { - super(parent, reader, false, leaves != null, ordInParent, docbaseInParent); + super(parent, reader, false, ordInParent, docbaseInParent); this.children = children; this.leaves = leaves; } @@ -1561,15 +1561,10 @@ public abstract class IndexReader implements Cloneable,Closeable { public final int docBase; /** * Creates a new {@link AtomicReaderContext} - */ + */ public AtomicReaderContext(ReaderContext parent, IndexReader reader, int ord, int docBase, int leafOrd, int leafDocBase) { - this(parent, reader, ord, docBase, leafOrd, leafDocBase, false); - } - - private AtomicReaderContext(ReaderContext parent, IndexReader reader, - int ord, int docBase, int leafOrd, int leafDocBase, boolean topLevel) { - super(parent, reader, true, topLevel, ord, docBase); + super(parent, reader, true, ord, docBase); assert reader.getSequentialSubReaders() == null : "Atomic readers must not have subreaders"; this.ord = leafOrd; this.docBase = leafDocBase; @@ -1580,7 +1575,7 @@ public abstract class IndexReader implements Cloneable,Closeable { * parent. */ public AtomicReaderContext(IndexReader atomicReader) { - this(null, atomicReader, 0, 0, 0, 0, true); // toplevel!! + this(null, atomicReader, 0, 0, 0, 0); } } } diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index eb2a3809e89..73f5f834e3e 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -153,10 +153,7 @@ public class IndexSearcher { } private IndexSearcher(ReaderContext context, boolean closeReader, ExecutorService executor) { - // TODO: eable this assert once SolrIndexReader and friends are refactored to use ReaderContext - // We can't assert this here since SolrIndexReader will fail in some contexts - once solr is consistent we should be fine here - // Lucene instead passes all tests even with this assert! - // assert context.isTopLevel: "IndexSearcher's ReaderContext must be topLevel for reader" + context.reader; + assert context.isTopLevel: "IndexSearcher's ReaderContext must be topLevel for reader" + context.reader; reader = context.reader; this.executor = executor; this.closeReader = closeReader; From ac068109b8ea012d9a6ba1fe42144b12149a531b Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Thu, 6 Jan 2011 02:23:10 +0000 Subject: [PATCH 008/252] spelling git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055714 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/java/org/apache/lucene/search/IndexSearcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 73f5f834e3e..4136c0458e8 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -147,7 +147,7 @@ public class IndexSearcher { this(context, null); } - // convinience ctor for other IR based ctors + // convenience ctor for other IR based ctors private IndexSearcher(IndexReader reader, boolean closeReader, ExecutorService executor) { this(reader.getTopReaderContext(), closeReader, executor); } From f717f54ff6b007fd28d995df60ca69bb4c8fd13a Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Thu, 6 Jan 2011 04:44:34 +0000 Subject: [PATCH 009/252] Fix javadocs build git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055745 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/build.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/lucene/build.xml b/lucene/build.xml index fddb875c9e9..1d1930a61f4 100644 --- a/lucene/build.xml +++ b/lucene/build.xml @@ -217,7 +217,6 @@ - From 1b22e86417bd4988b15a44e7074455c9d4da11cc Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Thu, 6 Jan 2011 13:51:10 +0000 Subject: [PATCH 010/252] LUCENE-2847: Support all of unicode, including supplementary code points above the basic multilingual plane, in StandardTokenizer and UAX29URLEmailTokenizer. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055877 13f79535-47bb-0310-9956-ffa450edef68 --- modules/analysis/CHANGES.txt | 12 +- modules/analysis/common/build.xml | 9 +- .../analysis/standard/ASCIITLD.jflex-macro | 5 +- .../standard/SUPPLEMENTARY.jflex-macro | 105 + .../standard/StandardTokenizerImpl.java | 589 +- .../standard/StandardTokenizerImpl.jflex | 40 +- .../standard/UAX29URLEmailTokenizer.java | 4983 ++++++++++------- .../standard/UAX29URLEmailTokenizer.jflex | 41 +- .../analysis/core/TestStandardAnalyzer.java | 6 + .../core/TestUAX29URLEmailTokenizer.java | 6 + modules/analysis/icu/build.xml | 17 + .../icu/GenerateJFlexSupplementaryMacros.java | 76 + 12 files changed, 3531 insertions(+), 2358 deletions(-) create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro create mode 100644 modules/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java diff --git a/modules/analysis/CHANGES.txt b/modules/analysis/CHANGES.txt index 59dbc6024d0..d5bd6e3942f 100644 --- a/modules/analysis/CHANGES.txt +++ b/modules/analysis/CHANGES.txt @@ -9,12 +9,14 @@ API Changes * LUCENE-2413: Removed the AnalyzerUtil in common/miscellaneous. (Robert Muir) - * LUCENE-2167,LUCENE-2699,LUCENE-2763: StandardTokenizer/Analyzer in - common/standard/ now implement the Word Break rules from the Unicode 6.0.0 - Text Segmentation algorithm (UAX#29). + * LUCENE-2167,LUCENE-2699,LUCENE-2763,LUCENE-2847: StandardTokenizer/Analyzer + in common/standard/ now implement the Word Break rules from the Unicode 6.0.0 + Text Segmentation algorithm (UAX#29), covering the full range of Unicode code + points, including values from U+FFFF to U+10FFFF - ClassicTokenizer/Analyzer retains the old StandardTokenizer/Analyzer - implementation and behavior. + ClassicTokenizer/Analyzer retains the old (pre-Lucene 3.1) StandardTokenizer/ + Analyzer implementation and behavior. Only the Unicode Basic Multilingual + Plane (code points from U+0000 to U+FFFF) is covered. UAX29URLEmailTokenizer tokenizes URLs and E-mail addresses according to the relevant RFCs, in addition to implementing the UAX#29 Word Break rules. diff --git a/modules/analysis/common/build.xml b/modules/analysis/common/build.xml index 3a7d30334e7..61e523ad2c0 100644 --- a/modules/analysis/common/build.xml +++ b/modules/analysis/common/build.xml @@ -38,8 +38,15 @@ - + + + + + + + diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro index 054167e0cd1..0557740e6d0 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/ASCIITLD.jflex-macro @@ -15,8 +15,8 @@ */ // Generated from IANA Root Zone Database -// file version from Saturday, December 4, 2010 12:34:19 PM UTC -// generated on Sunday, December 5, 2010 12:24:12 AM UTC +// file version from Wednesday, January 5, 2011 12:34:09 PM UTC +// generated on Thursday, January 6, 2011 5:09:41 AM UTC // by org.apache.lucene.analysis.standard.GenerateJflexTLDMacros ASCIITLD = "." ( @@ -306,6 +306,7 @@ ASCIITLD = "." ( | [xX][nN]--[pP]1[aA][iI] | [xX][nN]--[pP][gG][bB][sS]0[dD][hH] | [xX][nN]--[wW][gG][bB][hH]1[cC] + | [xX][nN]--[wW][gG][bB][lL]6[aA] | [xX][nN]--[xX][kK][cC]2[aA][lL]3[hH][yY][eE]2[aA] | [xX][nN]--[yY][gG][bB][iI]2[aA][mM][mM][xX] | [xX][nN]--[zZ][cC][kK][zZ][aA][hH] diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro new file mode 100644 index 00000000000..21c1ed940ae --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro @@ -0,0 +1,105 @@ +ALetterSupp = ( + ([\ud80d][\uDC00-\uDC2E]) + | ([\ud80c][\uDC00-\uDFFF]) + | ([\ud809][\uDC00-\uDC62]) + | ([\ud808][\uDC00-\uDF6E]) + | ([\ud81a][\uDC00-\uDE38]) + | ([\ud804][\uDC03-\uDC37\uDC83-\uDCAF]) + | ([\ud835][\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]) + | ([\ud801][\uDC00-\uDC9D]) + | ([\ud800][\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF4A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]) + | ([\ud803][\uDC00-\uDC48]) + | ([\ud802][\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]) +) +FormatSupp = ( + ([\ud804][\uDCBD]) + | ([\ud834][\uDD73-\uDD7A]) + | ([\udb40][\uDC01\uDC20-\uDC7F]) +) +ExtendSupp = ( + ([\ud804][\uDC00-\uDC02\uDC38-\uDC46\uDC80-\uDC82\uDCB0-\uDCBA]) + | ([\ud834][\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]) + | ([\ud800][\uDDFD]) + | ([\udb40][\uDD00-\uDDEF]) + | ([\ud802][\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]) +) +NumericSupp = ( + ([\ud804][\uDC66-\uDC6F]) + | ([\ud835][\uDFCE-\uDFFF]) + | ([\ud801][\uDCA0-\uDCA9]) +) +KatakanaSupp = ( + ([\ud82c][\uDC00]) +) +MidLetterSupp = ( + [] +) +MidNumSupp = ( + [] +) +MidNumLetSupp = ( + [] +) +ExtendNumLetSupp = ( + [] +) +ExtendNumLetSupp = ( + [] +) +ComplexContextSupp = ( + [] +) +HanSupp = ( + ([\ud87e][\uDC00-\uDE1D]) + | ([\ud86b][\uDC00-\uDFFF]) + | ([\ud86a][\uDC00-\uDFFF]) + | ([\ud869][\uDC00-\uDED6\uDF00-\uDFFF]) + | ([\ud868][\uDC00-\uDFFF]) + | ([\ud86e][\uDC00-\uDC1D]) + | ([\ud86d][\uDC00-\uDF34\uDF40-\uDFFF]) + | ([\ud86c][\uDC00-\uDFFF]) + | ([\ud863][\uDC00-\uDFFF]) + | ([\ud862][\uDC00-\uDFFF]) + | ([\ud861][\uDC00-\uDFFF]) + | ([\ud860][\uDC00-\uDFFF]) + | ([\ud867][\uDC00-\uDFFF]) + | ([\ud866][\uDC00-\uDFFF]) + | ([\ud865][\uDC00-\uDFFF]) + | ([\ud864][\uDC00-\uDFFF]) + | ([\ud858][\uDC00-\uDFFF]) + | ([\ud859][\uDC00-\uDFFF]) + | ([\ud85a][\uDC00-\uDFFF]) + | ([\ud85b][\uDC00-\uDFFF]) + | ([\ud85c][\uDC00-\uDFFF]) + | ([\ud85d][\uDC00-\uDFFF]) + | ([\ud85e][\uDC00-\uDFFF]) + | ([\ud85f][\uDC00-\uDFFF]) + | ([\ud850][\uDC00-\uDFFF]) + | ([\ud851][\uDC00-\uDFFF]) + | ([\ud852][\uDC00-\uDFFF]) + | ([\ud853][\uDC00-\uDFFF]) + | ([\ud854][\uDC00-\uDFFF]) + | ([\ud855][\uDC00-\uDFFF]) + | ([\ud856][\uDC00-\uDFFF]) + | ([\ud857][\uDC00-\uDFFF]) + | ([\ud849][\uDC00-\uDFFF]) + | ([\ud848][\uDC00-\uDFFF]) + | ([\ud84b][\uDC00-\uDFFF]) + | ([\ud84a][\uDC00-\uDFFF]) + | ([\ud84d][\uDC00-\uDFFF]) + | ([\ud84c][\uDC00-\uDFFF]) + | ([\ud84f][\uDC00-\uDFFF]) + | ([\ud84e][\uDC00-\uDFFF]) + | ([\ud841][\uDC00-\uDFFF]) + | ([\ud840][\uDC00-\uDFFF]) + | ([\ud843][\uDC00-\uDFFF]) + | ([\ud842][\uDC00-\uDFFF]) + | ([\ud845][\uDC00-\uDFFF]) + | ([\ud844][\uDC00-\uDFFF]) + | ([\ud847][\uDC00-\uDFFF]) + | ([\ud846][\uDC00-\uDFFF]) +) +HiraganaSupp = ( + ([\ud83c][\uDE00]) + | ([\ud82c][\uDC01]) +) diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java index b4c6e902763..83c17d0b61e 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.5.0-SNAPSHOT on 12/4/10 7:24 PM */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT on 1/6/11 12:09 AM */ package org.apache.lucene.analysis.standard; @@ -35,14 +35,6 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; *

  3. <IDEOGRAPHIC>: A single CJKV ideographic character
  4. *
  5. <HIRAGANA>: A single hiragana character
  6. * - * WARNING: Because JFlex does not support Unicode supplementary - * characters (characters above the Basic Multilingual Plane, which contains - * those up to and including U+FFFF), this scanner will not recognize them - * properly. If you need to be able to process text containing supplementary - * characters, consider using the ICU4J-backed implementation in modules/analysis/icu - * (org.apache.lucene.analysis.icu.segmentation.ICUTokenizer) - * instead of this class, since the ICU4J-backed implementation does not have - * this limitation. */ public final class StandardTokenizerImpl implements StandardTokenizerInterface { @@ -70,115 +62,138 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\47\0\1\7\4\0\1\6\1\0\1\7\1\0\12\3\1\5\1\6"+ - "\5\0\32\1\4\0\1\10\1\0\32\1\57\0\1\1\2\0\1\2"+ - "\7\0\1\1\1\0\1\5\2\0\1\1\5\0\27\1\1\0\37\1"+ - "\1\0\u01ca\1\4\0\14\1\16\0\5\1\7\0\1\1\1\0\1\1"+ - "\21\0\160\2\5\1\1\0\2\1\2\0\4\1\1\6\7\0\1\1"+ - "\1\5\3\1\1\0\1\1\1\0\24\1\1\0\123\1\1\0\213\1"+ - "\1\0\7\2\236\1\11\0\46\1\2\0\1\1\7\0\47\1\1\0"+ - "\1\6\7\0\55\2\1\0\1\2\1\0\2\2\1\0\2\2\1\0"+ - "\1\2\10\0\33\1\5\0\4\1\1\5\13\0\4\2\10\0\2\6"+ - "\2\0\13\2\5\0\53\1\25\2\12\3\1\0\1\3\1\6\1\0"+ - "\2\1\1\2\143\1\1\0\1\1\10\2\1\0\6\2\2\1\2\2"+ - "\1\0\4\2\2\1\12\3\3\1\2\0\1\1\17\0\1\2\1\1"+ - "\1\2\36\1\33\2\2\0\131\1\13\2\1\1\16\0\12\3\41\1"+ - "\11\2\2\1\2\0\1\6\1\0\1\1\5\0\26\1\4\2\1\1"+ - "\11\2\1\1\3\2\1\1\5\2\22\0\31\1\3\2\244\0\4\2"+ - "\66\1\3\2\1\1\22\2\1\1\7\2\12\1\2\2\2\0\12\3"+ - "\1\0\7\1\1\0\7\1\1\0\3\2\1\0\10\1\2\0\2\1"+ - "\2\0\26\1\1\0\7\1\1\0\1\1\3\0\4\1\2\0\1\2"+ - "\1\1\7\2\2\0\2\2\2\0\3\2\1\1\10\0\1\2\4\0"+ - "\2\1\1\0\3\1\2\2\2\0\12\3\2\1\17\0\3\2\1\0"+ - "\6\1\4\0\2\1\2\0\26\1\1\0\7\1\1\0\2\1\1\0"+ - "\2\1\1\0\2\1\2\0\1\2\1\0\5\2\4\0\2\2\2\0"+ - "\3\2\3\0\1\2\7\0\4\1\1\0\1\1\7\0\12\3\2\2"+ - "\3\1\1\2\13\0\3\2\1\0\11\1\1\0\3\1\1\0\26\1"+ - "\1\0\7\1\1\0\2\1\1\0\5\1\2\0\1\2\1\1\10\2"+ - "\1\0\3\2\1\0\3\2\2\0\1\1\17\0\2\1\2\2\2\0"+ - "\12\3\21\0\3\2\1\0\10\1\2\0\2\1\2\0\26\1\1\0"+ - "\7\1\1\0\2\1\1\0\5\1\2\0\1\2\1\1\7\2\2\0"+ - "\2\2\2\0\3\2\10\0\2\2\4\0\2\1\1\0\3\1\2\2"+ - "\2\0\12\3\1\0\1\1\20\0\1\2\1\1\1\0\6\1\3\0"+ - "\3\1\1\0\4\1\3\0\2\1\1\0\1\1\1\0\2\1\3\0"+ - "\2\1\3\0\3\1\3\0\14\1\4\0\5\2\3\0\3\2\1\0"+ - "\4\2\2\0\1\1\6\0\1\2\16\0\12\3\21\0\3\2\1\0"+ - "\10\1\1\0\3\1\1\0\27\1\1\0\12\1\1\0\5\1\3\0"+ - "\1\1\7\2\1\0\3\2\1\0\4\2\7\0\2\2\1\0\2\1"+ - "\6\0\2\1\2\2\2\0\12\3\22\0\2\2\1\0\10\1\1\0"+ - "\3\1\1\0\27\1\1\0\12\1\1\0\5\1\2\0\1\2\1\1"+ - "\7\2\1\0\3\2\1\0\4\2\7\0\2\2\7\0\1\1\1\0"+ - "\2\1\2\2\2\0\12\3\1\0\2\1\17\0\2\2\1\0\10\1"+ - "\1\0\3\1\1\0\51\1\2\0\1\1\7\2\1\0\3\2\1\0"+ - "\4\2\1\1\10\0\1\2\10\0\2\1\2\2\2\0\12\3\12\0"+ - "\6\1\2\0\2\2\1\0\22\1\3\0\30\1\1\0\11\1\1\0"+ - "\1\1\2\0\7\1\3\0\1\2\4\0\6\2\1\0\1\2\1\0"+ - "\10\2\22\0\2\2\15\0\60\11\1\12\2\11\7\12\5\0\7\11"+ - "\10\12\1\0\12\3\47\0\2\11\1\0\1\11\2\0\2\11\1\0"+ - "\1\11\2\0\1\11\6\0\4\11\1\0\7\11\1\0\3\11\1\0"+ - "\1\11\1\0\1\11\2\0\2\11\1\0\4\11\1\12\2\11\6\12"+ - "\1\0\2\12\1\11\2\0\5\11\1\0\1\11\1\0\6\12\2\0"+ - "\12\3\2\0\2\11\42\0\1\1\27\0\2\2\6\0\12\3\13\0"+ - "\1\2\1\0\1\2\1\0\1\2\4\0\2\2\10\1\1\0\44\1"+ - "\4\0\24\2\1\0\2\2\5\1\13\2\1\0\44\2\11\0\1\2"+ - "\71\0\53\11\24\12\1\11\12\3\6\0\6\11\4\12\4\11\3\12"+ - "\1\11\3\12\2\11\7\12\3\11\4\12\15\11\14\12\1\11\1\12"+ - "\12\3\4\12\2\11\46\1\12\0\53\1\1\0\1\1\3\0\u0149\1"+ - "\1\0\4\1\2\0\7\1\1\0\1\1\1\0\4\1\2\0\51\1"+ - "\1\0\4\1\2\0\41\1\1\0\4\1\2\0\7\1\1\0\1\1"+ - "\1\0\4\1\2\0\17\1\1\0\71\1\1\0\4\1\2\0\103\1"+ - "\2\0\3\2\40\0\20\1\20\0\125\1\14\0\u026c\1\2\0\21\1"+ - "\1\0\32\1\5\0\113\1\3\0\3\1\17\0\15\1\1\0\4\1"+ - "\3\2\13\0\22\1\3\2\13\0\22\1\2\2\14\0\15\1\1\0"+ - "\3\1\1\0\2\2\14\0\64\11\40\12\3\0\1\11\4\0\1\11"+ - "\1\12\2\0\12\3\41\0\3\2\2\0\12\3\6\0\130\1\10\0"+ - "\51\1\1\2\1\1\5\0\106\1\12\0\35\1\3\0\14\2\4\0"+ - "\14\2\12\0\12\3\36\11\2\0\5\11\13\0\54\11\4\0\21\12"+ - "\7\11\2\12\6\0\12\3\1\11\3\0\2\11\40\0\27\1\5\2"+ - "\4\0\65\11\12\12\1\0\35\12\2\0\1\2\12\3\6\0\12\3"+ - "\6\0\16\11\122\0\5\2\57\1\21\2\7\1\4\0\12\3\21\0"+ - "\11\2\14\0\3\2\36\1\12\2\3\0\2\1\12\3\6\0\46\1"+ - "\16\2\14\0\44\1\24\2\10\0\12\3\3\0\3\1\12\3\44\1"+ - "\122\0\3\2\1\0\25\2\4\1\1\2\4\1\1\2\15\0\300\1"+ - "\47\2\25\0\4\2\u0116\1\2\0\6\1\2\0\46\1\2\0\6\1"+ - "\2\0\10\1\1\0\1\1\1\0\1\1\1\0\1\1\1\0\37\1"+ - "\2\0\65\1\1\0\7\1\1\0\1\1\3\0\3\1\1\0\7\1"+ - "\3\0\4\1\2\0\6\1\4\0\15\1\5\0\3\1\1\0\7\1"+ - "\17\0\4\2\10\0\2\7\12\0\1\7\2\0\1\5\2\0\5\2"+ - "\20\0\2\10\3\0\1\6\17\0\1\10\13\0\5\2\5\0\6\2"+ - "\1\0\1\1\15\0\1\1\20\0\15\1\63\0\41\2\21\0\1\1"+ - "\4\0\1\1\2\0\12\1\1\0\1\1\3\0\5\1\6\0\1\1"+ - "\1\0\1\1\1\0\1\1\1\0\4\1\1\0\13\1\2\0\4\1"+ - "\5\0\5\1\4\0\1\1\21\0\51\1\u032d\0\64\1\u0716\0\57\1"+ - "\1\0\57\1\1\0\205\1\6\0\4\1\3\2\16\0\46\1\12\0"+ - "\66\1\11\0\1\1\17\0\1\2\27\1\11\0\7\1\1\0\7\1"+ - "\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1"+ - "\1\0\7\1\1\0\40\2\57\0\1\1\120\0\32\13\1\0\131\13"+ - "\14\0\326\13\57\0\1\1\1\0\1\13\31\0\11\13\6\2\1\0"+ - "\5\4\2\0\3\13\1\1\1\1\4\0\126\14\2\0\2\2\2\4"+ - "\3\14\133\4\1\0\4\4\5\0\51\1\3\0\136\1\21\0\33\1"+ - "\65\0\20\4\320\0\57\4\1\0\130\4\250\0\u19b6\13\112\0\u51cc\13"+ - "\64\0\u048d\1\103\0\56\1\2\0\u010d\1\3\0\20\1\12\3\2\1"+ - "\24\0\57\1\4\2\11\0\2\2\1\0\31\1\10\0\120\1\2\2"+ - "\45\0\11\1\2\0\147\1\2\0\4\1\1\0\2\1\16\0\12\1"+ - "\120\0\10\1\1\2\3\1\1\2\4\1\1\2\27\1\5\2\30\0"+ - "\64\1\14\0\2\2\62\1\21\2\13\0\12\3\6\0\22\2\6\1"+ - "\3\0\1\1\4\0\12\3\34\1\10\2\2\0\27\1\15\2\14\0"+ - "\35\1\3\0\4\2\57\1\16\2\16\0\1\1\12\3\46\0\51\1"+ - "\16\2\11\0\3\1\1\2\10\1\2\2\2\0\12\3\6\0\33\11"+ - "\1\12\4\0\60\11\1\12\1\11\3\12\2\11\2\12\5\11\2\12"+ - "\1\11\1\12\1\11\30\0\5\11\41\0\6\1\2\0\6\1\2\0"+ - "\6\1\11\0\7\1\1\0\7\1\221\0\43\1\10\2\1\0\2\2"+ - "\2\0\12\3\6\0\u2ba4\1\14\0\27\1\4\0\61\1\u2104\0\u012e\13"+ - "\2\0\76\13\2\0\152\13\46\0\7\1\14\0\5\1\5\0\1\1"+ - "\1\2\12\1\1\0\15\1\1\0\5\1\1\0\1\1\1\0\2\1"+ - "\1\0\2\1\1\0\154\1\41\0\u016b\1\22\0\100\1\2\0\66\1"+ - "\50\0\14\1\4\0\20\2\1\6\2\0\1\5\1\6\13\0\7\2"+ - "\14\0\2\10\30\0\3\10\1\6\1\0\1\7\1\0\1\6\1\5"+ - "\32\0\5\1\1\0\207\1\2\0\1\2\7\0\1\7\4\0\1\6"+ - "\1\0\1\7\1\0\12\3\1\5\1\6\5\0\32\1\4\0\1\10"+ - "\1\0\32\1\13\0\70\4\2\2\37\1\3\0\6\1\2\0\6\1"+ - "\2\0\6\1\2\0\3\1\34\0\3\2\4\0"; + "\47\0\1\140\4\0\1\137\1\0\1\140\1\0\12\134\1\136\1\137"+ + "\5\0\32\132\4\0\1\141\1\0\32\132\57\0\1\132\2\0\1\133"+ + "\7\0\1\132\1\0\1\136\2\0\1\132\5\0\27\132\1\0\37\132"+ + "\1\0\u01ca\132\4\0\14\132\16\0\5\132\7\0\1\132\1\0\1\132"+ + "\21\0\160\133\5\132\1\0\2\132\2\0\4\132\1\137\7\0\1\132"+ + "\1\136\3\132\1\0\1\132\1\0\24\132\1\0\123\132\1\0\213\132"+ + "\1\0\7\133\236\132\11\0\46\132\2\0\1\132\7\0\47\132\1\0"+ + "\1\137\7\0\55\133\1\0\1\133\1\0\2\133\1\0\2\133\1\0"+ + "\1\133\10\0\33\132\5\0\4\132\1\136\13\0\4\133\10\0\2\137"+ + "\2\0\13\133\5\0\53\132\25\133\12\134\1\0\1\134\1\137\1\0"+ + "\2\132\1\133\143\132\1\0\1\132\7\133\1\133\1\0\6\133\2\132"+ + "\2\133\1\0\4\133\2\132\12\134\3\132\2\0\1\132\17\0\1\133"+ + "\1\132\1\133\36\132\33\133\2\0\131\132\13\133\1\132\16\0\12\134"+ + "\41\132\11\133\2\132\2\0\1\137\1\0\1\132\5\0\26\132\4\133"+ + "\1\132\11\133\1\132\3\133\1\132\5\133\22\0\31\132\3\133\244\0"+ + "\4\133\66\132\3\133\1\132\22\133\1\132\7\133\12\132\2\133\2\0"+ + "\12\134\1\0\7\132\1\0\7\132\1\0\3\133\1\0\10\132\2\0"+ + "\2\132\2\0\26\132\1\0\7\132\1\0\1\132\3\0\4\132\2\0"+ + "\1\133\1\132\7\133\2\0\2\133\2\0\3\133\1\132\10\0\1\133"+ + "\4\0\2\132\1\0\3\132\2\133\2\0\12\134\2\132\17\0\3\133"+ + "\1\0\6\132\4\0\2\132\2\0\26\132\1\0\7\132\1\0\2\132"+ + "\1\0\2\132\1\0\2\132\2\0\1\133\1\0\5\133\4\0\2\133"+ + "\2\0\3\133\3\0\1\133\7\0\4\132\1\0\1\132\7\0\12\134"+ + "\2\133\3\132\1\133\13\0\3\133\1\0\11\132\1\0\3\132\1\0"+ + "\26\132\1\0\7\132\1\0\2\132\1\0\5\132\2\0\1\133\1\132"+ + "\10\133\1\0\3\133\1\0\3\133\2\0\1\132\17\0\2\132\2\133"+ + "\2\0\12\134\21\0\3\133\1\0\10\132\2\0\2\132\2\0\26\132"+ + "\1\0\7\132\1\0\2\132\1\0\5\132\2\0\1\133\1\132\7\133"+ + "\2\0\2\133\2\0\3\133\10\0\2\133\4\0\2\132\1\0\3\132"+ + "\2\133\2\0\12\134\1\0\1\132\20\0\1\133\1\132\1\0\6\132"+ + "\3\0\3\132\1\0\4\132\3\0\2\132\1\0\1\132\1\0\2\132"+ + "\3\0\2\132\3\0\3\132\3\0\14\132\4\0\5\133\3\0\3\133"+ + "\1\0\4\133\2\0\1\132\6\0\1\133\16\0\12\134\21\0\3\133"+ + "\1\0\10\132\1\0\3\132\1\0\27\132\1\0\12\132\1\0\5\132"+ + "\3\0\1\132\7\133\1\0\3\133\1\0\4\133\7\0\2\133\1\0"+ + "\2\132\6\0\2\132\2\133\2\0\12\134\22\0\2\133\1\0\10\132"+ + "\1\0\3\132\1\0\27\132\1\0\12\132\1\0\5\132\2\0\1\133"+ + "\1\132\7\133\1\0\3\133\1\0\4\133\7\0\2\133\7\0\1\132"+ + "\1\0\2\132\2\133\2\0\12\134\1\0\2\132\17\0\2\133\1\0"+ + "\10\132\1\0\3\132\1\0\51\132\2\0\1\132\7\133\1\0\3\133"+ + "\1\0\4\133\1\132\10\0\1\133\10\0\2\132\2\133\2\0\12\134"+ + "\12\0\6\132\2\0\2\133\1\0\22\132\3\0\30\132\1\0\11\132"+ + "\1\0\1\132\2\0\7\132\3\0\1\133\4\0\6\133\1\0\1\133"+ + "\1\0\10\133\22\0\2\133\15\0\60\142\1\143\2\142\7\143\5\0"+ + "\7\142\10\143\1\0\12\134\47\0\2\142\1\0\1\142\2\0\2\142"+ + "\1\0\1\142\2\0\1\142\6\0\4\142\1\0\7\142\1\0\3\142"+ + "\1\0\1\142\1\0\1\142\2\0\2\142\1\0\4\142\1\143\2\142"+ + "\6\143\1\0\2\143\1\142\2\0\5\142\1\0\1\142\1\0\6\143"+ + "\2\0\12\134\2\0\2\142\42\0\1\132\27\0\2\133\6\0\12\134"+ + "\13\0\1\133\1\0\1\133\1\0\1\133\4\0\2\133\10\132\1\0"+ + "\44\132\4\0\24\133\1\0\2\133\5\132\13\133\1\0\44\133\11\0"+ + "\1\133\71\0\53\142\24\143\1\142\12\134\6\0\6\142\4\143\4\142"+ + "\3\143\1\142\3\143\2\142\7\143\3\142\4\143\15\142\14\143\1\142"+ + "\1\143\12\134\4\143\2\142\46\132\12\0\53\132\1\0\1\132\3\0"+ + "\u0149\132\1\0\4\132\2\0\7\132\1\0\1\132\1\0\4\132\2\0"+ + "\51\132\1\0\4\132\2\0\41\132\1\0\4\132\2\0\7\132\1\0"+ + "\1\132\1\0\4\132\2\0\17\132\1\0\71\132\1\0\4\132\2\0"+ + "\103\132\2\0\3\133\40\0\20\132\20\0\125\132\14\0\u026c\132\2\0"+ + "\21\132\1\0\32\132\5\0\113\132\3\0\3\132\17\0\15\132\1\0"+ + "\4\132\3\133\13\0\22\132\3\133\13\0\22\132\2\133\14\0\15\132"+ + "\1\0\3\132\1\0\2\133\14\0\64\142\2\143\36\143\3\0\1\142"+ + "\4\0\1\142\1\143\2\0\12\134\41\0\3\133\2\0\12\134\6\0"+ + "\130\132\10\0\51\132\1\133\1\132\5\0\106\132\12\0\35\132\3\0"+ + "\14\133\4\0\14\133\12\0\12\134\36\142\2\0\5\142\13\0\54\142"+ + "\4\0\21\143\7\142\2\143\6\0\12\134\1\142\3\0\2\142\40\0"+ + "\27\132\5\133\4\0\65\142\12\143\1\0\35\143\2\0\1\133\12\134"+ + "\6\0\12\134\6\0\16\142\122\0\5\133\57\132\21\133\7\132\4\0"+ + "\12\134\21\0\11\133\14\0\3\133\36\132\12\133\3\0\2\132\12\134"+ + "\6\0\46\132\16\133\14\0\44\132\24\133\10\0\12\134\3\0\3\132"+ + "\12\134\44\132\122\0\3\133\1\0\25\133\4\132\1\133\4\132\1\133"+ + "\15\0\300\132\47\133\25\0\4\133\u0116\132\2\0\6\132\2\0\46\132"+ + "\2\0\6\132\2\0\10\132\1\0\1\132\1\0\1\132\1\0\1\132"+ + "\1\0\37\132\2\0\65\132\1\0\7\132\1\0\1\132\3\0\3\132"+ + "\1\0\7\132\3\0\4\132\2\0\6\132\4\0\15\132\5\0\3\132"+ + "\1\0\7\132\17\0\2\133\2\133\10\0\2\140\12\0\1\140\2\0"+ + "\1\136\2\0\5\133\20\0\2\141\3\0\1\137\17\0\1\141\13\0"+ + "\5\133\5\0\6\133\1\0\1\132\15\0\1\132\20\0\15\132\63\0"+ + "\41\133\21\0\1\132\4\0\1\132\2\0\12\132\1\0\1\132\3\0"+ + "\5\132\6\0\1\132\1\0\1\132\1\0\1\132\1\0\4\132\1\0"+ + "\13\132\2\0\4\132\5\0\5\132\4\0\1\132\21\0\51\132\u032d\0"+ + "\64\132\u0716\0\57\132\1\0\57\132\1\0\205\132\6\0\4\132\3\133"+ + "\16\0\46\132\12\0\66\132\11\0\1\132\17\0\1\133\27\132\11\0"+ + "\7\132\1\0\7\132\1\0\7\132\1\0\7\132\1\0\7\132\1\0"+ + "\7\132\1\0\7\132\1\0\7\132\1\0\40\133\57\0\1\132\120\0"+ + "\32\144\1\0\131\144\14\0\326\144\57\0\1\132\1\0\1\144\31\0"+ + "\11\144\6\133\1\0\5\135\2\0\3\144\1\132\1\132\4\0\126\145"+ + "\2\0\2\133\2\135\3\145\133\135\1\0\4\135\5\0\51\132\3\0"+ + "\136\132\21\0\33\132\65\0\20\135\320\0\57\135\1\0\130\135\250\0"+ + "\u19b6\144\112\0\u51cc\144\64\0\u048d\132\103\0\56\132\2\0\u010d\132\3\0"+ + "\20\132\12\134\2\132\24\0\57\132\4\133\11\0\2\133\1\0\31\132"+ + "\10\0\120\132\2\133\45\0\11\132\2\0\147\132\2\0\4\132\1\0"+ + "\2\132\16\0\12\132\120\0\10\132\1\133\3\132\1\133\4\132\1\133"+ + "\27\132\5\133\30\0\64\132\14\0\2\133\62\132\21\133\13\0\12\134"+ + "\6\0\22\133\6\132\3\0\1\132\4\0\12\134\34\132\10\133\2\0"+ + "\27\132\15\133\14\0\35\132\3\0\4\133\57\132\16\133\16\0\1\132"+ + "\12\134\46\0\51\132\16\133\11\0\3\132\1\133\10\132\2\133\2\0"+ + "\12\134\6\0\33\142\1\143\4\0\60\142\1\143\1\142\3\143\2\142"+ + "\2\143\5\142\2\143\1\142\1\143\1\142\30\0\5\142\41\0\6\132"+ + "\2\0\6\132\2\0\6\132\11\0\7\132\1\0\7\132\221\0\43\132"+ + "\10\133\1\0\2\133\2\0\12\134\6\0\u2ba4\132\14\0\27\132\4\0"+ + "\61\132\4\0\1\31\1\25\1\46\1\43\1\13\3\0\1\7\1\5"+ + "\2\0\1\3\1\1\14\0\1\11\21\0\1\112\7\0\1\65\1\17"+ + "\6\0\1\130\3\0\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\121\1\120\1\120\1\120\1\125\1\123"+ + "\17\0\1\114\u02c1\0\1\70\277\0\1\113\1\71\1\2\3\124\2\35"+ + "\1\124\1\35\2\124\1\14\21\124\2\60\7\73\1\72\7\73\7\52"+ + "\1\15\1\52\1\75\2\45\1\44\1\75\1\45\1\44\10\75\2\63"+ + "\5\61\2\54\5\61\1\6\10\37\5\21\3\27\12\106\20\27\3\42"+ + "\32\30\1\26\2\24\2\110\1\111\2\110\2\111\2\110\1\111\3\24"+ + "\1\16\2\24\12\64\1\74\1\41\1\34\1\64\6\41\1\34\66\41"+ + "\5\115\6\103\1\51\4\103\2\51\10\103\1\51\7\100\1\12\2\100"+ + "\32\103\1\12\4\100\1\12\5\102\1\101\1\102\3\101\7\102\1\101"+ + "\23\102\5\67\3\102\6\67\2\67\6\66\10\66\2\100\7\66\36\100"+ + "\4\66\102\100\15\115\1\77\2\115\1\131\3\117\1\115\2\117\5\115"+ + "\4\117\4\116\1\115\3\116\1\115\5\116\26\56\4\23\1\105\2\104"+ + "\4\122\1\104\2\122\3\76\33\122\35\55\3\122\35\126\3\122\6\126"+ + "\2\33\31\126\1\33\17\126\6\122\4\22\1\10\37\22\1\10\4\22"+ + "\25\62\1\127\11\62\21\55\5\62\1\57\12\40\13\62\4\55\1\50"+ + "\6\55\12\122\17\55\1\47\3\53\15\20\11\36\1\32\24\36\2\20"+ + "\11\36\1\32\31\36\1\32\4\20\4\36\2\32\2\107\1\4\5\107"+ + "\52\4\u1900\0\u012e\144\2\0\76\144\2\0\152\144\46\0\7\132\14\0"+ + "\5\132\5\0\1\132\1\133\12\132\1\0\15\132\1\0\5\132\1\0"+ + "\1\132\1\0\2\132\1\0\2\132\1\0\154\132\41\0\u016b\132\22\0"+ + "\100\132\2\0\66\132\50\0\14\132\4\0\20\133\1\137\2\0\1\136"+ + "\1\137\13\0\7\133\14\0\2\141\30\0\3\141\1\137\1\0\1\140"+ + "\1\0\1\137\1\136\32\0\5\132\1\0\207\132\2\0\1\133\7\0"+ + "\1\140\4\0\1\137\1\0\1\140\1\0\12\134\1\136\1\137\5\0"+ + "\32\132\4\0\1\141\1\0\32\132\13\0\70\135\2\133\37\132\3\0"+ + "\6\132\2\0\6\132\2\0\6\132\2\0\3\132\34\0\3\133\4\0"; /** * Translates characters to character classes @@ -191,11 +206,11 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\0\1\1\1\2\1\3\1\2\1\1\1\4\1\5"+ - "\1\6\1\2\1\0\1\2\1\0\1\3\2\0"; + "\1\0\23\1\1\2\1\3\1\2\1\1\1\4\1\5"+ + "\1\6\15\0\1\2\1\0\1\2\10\0\1\3\61\0"; private static int [] zzUnpackAction() { - int [] result = new int[16]; + int [] result = new int[101]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -220,11 +235,22 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\15\0\32\0\47\0\64\0\101\0\116\0\15"+ - "\0\15\0\133\0\150\0\165\0\202\0\217\0\101\0\234"; + "\0\0\0\146\0\314\0\u0132\0\u0198\0\u01fe\0\u0264\0\u02ca"+ + "\0\u0330\0\u0396\0\u03fc\0\u0462\0\u04c8\0\u052e\0\u0594\0\u05fa"+ + "\0\u0660\0\u06c6\0\u072c\0\u0792\0\u07f8\0\u085e\0\u08c4\0\u092a"+ + "\0\u0990\0\146\0\146\0\314\0\u0132\0\u0198\0\u01fe\0\u0264"+ + "\0\u09f6\0\u0a5c\0\u0ac2\0\u0b28\0\u0462\0\u0b8e\0\u0bf4\0\u0c5a"+ + "\0\u0cc0\0\u0d26\0\u0d8c\0\u0df2\0\u0330\0\u0396\0\u0e58\0\u0ebe"+ + "\0\u0f24\0\u0f8a\0\u0ff0\0\u1056\0\u10bc\0\u1122\0\u1188\0\u11ee"+ + "\0\u1254\0\u12ba\0\u1320\0\u1386\0\u13ec\0\u1452\0\u14b8\0\u092a"+ + "\0\u151e\0\u1584\0\u15ea\0\u1650\0\u16b6\0\u171c\0\u1782\0\u17e8"+ + "\0\u184e\0\u18b4\0\u191a\0\u1980\0\u19e6\0\u1a4c\0\u1ab2\0\u1b18"+ + "\0\u1b7e\0\u1be4\0\u1c4a\0\u1cb0\0\u1d16\0\u1d7c\0\u1de2\0\u1e48"+ + "\0\u1eae\0\u1f14\0\u1f7a\0\u1fe0\0\u2046\0\u20ac\0\u2112\0\u2178"+ + "\0\u21de\0\u2244\0\u22aa\0\u2310\0\u2376"; private static int [] zzUnpackRowMap() { - int [] result = new int[16]; + int [] result = new int[101]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -247,21 +273,280 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\1\2\1\3\1\2\1\4\1\5\3\2\1\6\2\7"+ - "\1\10\1\11\16\0\2\3\1\12\1\0\1\13\1\0"+ - "\1\13\1\14\1\0\1\3\3\0\1\3\2\4\2\0"+ - "\2\15\1\16\1\0\1\4\4\0\1\5\1\0\1\5"+ - "\3\0\1\14\1\0\1\5\3\0\1\3\1\17\1\4"+ - "\1\5\3\0\1\17\1\0\1\17\13\0\2\7\3\0"+ - "\1\3\2\12\2\0\2\20\1\14\1\0\1\12\3\0"+ - "\1\3\1\13\7\0\1\13\3\0\1\3\1\14\1\12"+ - "\1\5\3\0\1\14\1\0\1\14\4\0\1\15\1\4"+ - "\6\0\1\15\3\0\1\3\1\16\1\4\1\5\3\0"+ - "\1\16\1\0\1\16\4\0\1\20\1\12\6\0\1\20"+ - "\2\0"; + "\1\2\1\3\1\2\1\4\1\2\1\5\1\2\1\6"+ + "\1\2\1\7\1\2\1\10\3\2\1\11\5\2\1\12"+ + "\3\2\1\13\11\2\1\14\2\2\1\15\43\2\1\16"+ + "\1\2\1\17\3\2\1\20\1\21\1\2\1\22\1\2"+ + "\1\23\2\2\1\24\1\2\1\25\1\2\1\26\1\27"+ + "\3\2\1\30\2\31\1\32\1\33\150\0\1\25\11\0"+ + "\1\25\20\0\1\25\22\0\1\25\10\0\3\25\17\0"+ + "\1\25\10\0\1\25\23\0\1\25\1\0\1\25\1\0"+ + "\1\25\1\0\1\25\1\0\1\25\1\0\3\25\1\0"+ + "\5\25\1\0\3\25\1\0\11\25\1\0\2\25\1\0"+ + "\16\25\1\0\2\25\1\0\21\25\1\0\1\25\1\0"+ + "\3\25\2\0\1\25\1\0\1\25\1\0\2\25\1\0"+ + "\1\25\16\0\1\25\3\0\1\25\5\0\2\25\3\0"+ + "\1\25\13\0\1\25\1\0\1\25\4\0\2\25\4\0"+ + "\1\25\1\0\1\25\3\0\2\25\1\0\1\25\5\0"+ + "\3\25\1\0\1\25\15\0\1\25\10\0\1\25\23\0"+ + "\1\25\3\0\1\25\1\0\1\25\1\0\1\25\1\0"+ + "\3\25\2\0\4\25\1\0\3\25\2\0\3\25\1\0"+ + "\4\25\1\0\2\25\2\0\3\25\1\0\11\25\1\0"+ + "\2\25\1\0\16\25\1\0\2\25\1\0\1\25\1\0"+ + "\3\25\2\0\1\25\1\0\1\25\1\0\2\25\1\0"+ + "\1\25\16\0\1\25\3\0\1\25\3\0\1\25\1\0"+ + "\3\25\2\0\1\25\1\0\2\25\1\0\3\25\3\0"+ + "\2\25\1\0\1\25\1\0\2\25\1\0\2\25\3\0"+ + "\2\25\1\0\1\25\1\0\1\25\1\0\2\25\1\0"+ + "\2\25\1\0\2\25\1\0\5\25\1\0\5\25\1\0"+ + "\2\25\1\0\2\25\1\0\1\25\1\0\3\25\4\0"+ + "\1\25\4\0\1\25\30\0\3\25\5\0\1\25\1\0"+ + "\1\25\1\0\1\25\4\0\1\25\14\0\1\25\5\0"+ + "\1\25\11\0\2\25\12\0\1\26\1\0\2\25\12\0"+ + "\1\25\23\0\1\25\1\0\1\26\7\0\2\25\2\0"+ + "\5\25\2\0\2\25\4\0\6\25\1\0\2\25\4\0"+ + "\5\25\1\0\5\25\1\0\2\25\1\0\3\25\1\0"+ + "\4\25\1\0\5\25\1\26\1\0\1\25\1\0\1\25"+ + "\1\0\3\25\2\0\1\25\1\0\1\25\1\0\1\25"+ + "\2\0\1\25\16\0\1\25\3\0\1\25\5\0\2\25"+ + "\3\0\1\25\4\0\3\25\4\0\1\25\1\0\1\25"+ + "\2\0\1\25\1\0\2\25\4\0\1\25\1\0\1\25"+ + "\3\0\2\25\1\0\1\25\5\0\3\25\1\0\1\25"+ + "\10\0\1\25\1\0\2\26\1\0\1\25\10\0\1\25"+ + "\23\0\1\25\3\0\1\25\6\0\2\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\1\0\11\25\2\0\1\25"+ + "\4\0\1\25\4\0\6\25\2\0\1\25\1\0\1\25"+ + "\1\0\3\25\3\0\2\25\4\0\3\25\1\0\1\25"+ + "\10\0\1\25\1\0\2\25\20\0\1\25\11\0\2\25"+ + "\17\0\1\25\6\0\2\25\4\0\1\25\5\0\1\25"+ + "\2\0\1\25\5\0\3\25\1\0\1\25\15\0\1\25"+ + "\10\0\1\25\23\0\1\25\3\0\1\25\5\0\1\25"+ + "\32\0\15\25\5\0\3\25\1\0\1\25\5\0\1\25"+ + "\7\0\1\25\2\0\1\25\5\0\1\25\2\0\1\25"+ + "\1\0\1\25\105\0\1\33\21\0\1\27\34\0\1\32"+ + "\3\0\1\32\3\0\1\32\1\0\3\32\2\0\1\32"+ + "\2\0\1\32\1\0\3\32\3\0\2\32\1\0\1\32"+ + "\1\0\2\32\1\0\2\32\3\0\2\32\1\0\1\32"+ + "\3\0\2\32\1\0\2\32\1\0\2\32\1\0\5\32"+ + "\1\0\5\32\2\0\1\32\1\0\2\32\1\0\1\32"+ + "\1\0\3\32\4\0\1\32\4\0\1\32\16\0\1\32"+ + "\1\0\1\32\1\0\1\32\1\0\1\32\1\0\1\32"+ + "\1\0\3\32\1\0\5\32\1\0\3\32\1\0\11\32"+ + "\1\0\2\32\1\0\16\32\1\0\2\32\1\0\21\32"+ + "\1\0\1\32\1\0\3\32\2\0\1\32\1\0\1\32"+ + "\1\0\2\32\1\0\1\32\16\0\1\32\1\0\1\32"+ + "\1\0\1\32\3\0\1\32\1\0\3\32\1\0\2\32"+ + "\1\0\2\32\1\0\3\32\1\0\11\32\1\0\2\32"+ + "\1\0\16\32\1\0\2\32\1\0\21\32\1\0\1\32"+ + "\1\0\3\32\2\0\1\32\1\0\1\32\1\0\2\32"+ + "\1\0\1\32\16\0\1\32\11\0\1\32\20\0\1\32"+ + "\33\0\1\32\21\0\1\32\10\0\1\32\23\0\1\32"+ + "\1\0\1\32\1\0\1\32\1\0\1\32\1\0\1\32"+ + "\1\0\3\32\1\0\5\32\1\0\3\32\1\0\6\32"+ + "\1\0\2\32\1\0\2\32\1\0\10\32\1\0\5\32"+ + "\1\0\2\32\1\0\21\32\1\0\1\32\1\0\3\32"+ + "\2\0\1\32\1\0\1\32\1\0\2\32\1\0\1\32"+ + "\145\0\1\33\15\0\1\34\1\0\1\35\1\0\1\36"+ + "\1\0\1\37\1\0\1\40\1\0\1\41\3\0\1\42"+ + "\5\0\1\43\3\0\1\44\11\0\1\45\2\0\1\46"+ + "\16\0\1\47\2\0\1\50\41\0\2\25\1\51\1\0"+ + "\1\52\1\0\1\52\1\53\1\0\1\25\3\0\1\34"+ + "\1\0\1\35\1\0\1\36\1\0\1\37\1\0\1\40"+ + "\1\0\1\54\3\0\1\55\5\0\1\56\3\0\1\57"+ + "\11\0\1\45\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\1\25\2\26\2\0\2\63\1\64\1\0\1\26"+ + "\15\0\1\65\15\0\1\66\14\0\1\67\16\0\1\70"+ + "\2\0\1\71\21\0\1\72\20\0\1\27\1\0\1\27"+ + "\3\0\1\53\1\0\1\27\3\0\1\34\1\0\1\35"+ + "\1\0\1\36\1\0\1\37\1\0\1\40\1\0\1\73"+ + "\3\0\1\55\5\0\1\56\3\0\1\74\11\0\1\45"+ + "\2\0\1\75\16\0\1\76\2\0\1\77\21\0\1\72"+ + "\17\0\1\25\1\100\1\26\1\27\3\0\1\100\1\0"+ + "\1\100\144\0\2\31\4\0\1\25\11\0\3\25\5\0"+ + "\1\25\1\0\1\25\1\0\1\25\4\0\1\25\4\0"+ + "\1\25\1\0\2\25\4\0\1\25\5\0\1\25\3\0"+ + "\1\25\4\0\5\25\10\0\1\51\1\0\2\25\1\0"+ + "\1\25\10\0\1\25\23\0\1\25\1\0\1\51\7\0"+ + "\2\25\2\0\5\25\2\0\2\25\4\0\6\25\1\0"+ + "\2\25\4\0\5\25\1\0\5\25\1\0\2\25\1\0"+ + "\3\25\1\0\4\25\1\0\5\25\1\51\1\0\1\25"+ + "\1\0\1\25\1\0\3\25\2\0\1\25\1\0\1\25"+ + "\1\0\1\25\2\0\1\25\16\0\1\25\3\0\1\25"+ + "\5\0\2\25\3\0\1\25\4\0\3\25\4\0\1\25"+ + "\1\0\1\25\2\0\1\25\1\0\2\25\4\0\1\25"+ + "\1\0\1\25\3\0\2\25\1\0\1\25\5\0\3\25"+ + "\1\0\1\25\10\0\1\25\1\0\2\51\1\0\1\25"+ + "\10\0\1\25\23\0\1\25\3\0\1\25\6\0\2\25"+ + "\5\0\1\25\1\0\1\25\1\0\1\25\1\0\11\25"+ + "\2\0\1\25\4\0\1\25\4\0\6\25\2\0\1\25"+ + "\1\0\1\25\1\0\3\25\1\0\1\25\1\0\2\25"+ + "\4\0\3\25\1\0\1\25\10\0\1\25\1\0\2\25"+ + "\20\0\1\25\3\0\1\25\5\0\1\25\32\0\15\25"+ + "\5\0\3\25\1\0\1\25\5\0\3\25\5\0\1\25"+ + "\2\0\2\25\4\0\1\25\2\0\1\25\1\0\1\25"+ + "\102\0\2\25\6\0\1\25\55\0\1\25\3\0\1\25"+ + "\2\0\1\25\3\0\1\25\5\0\1\25\7\0\1\25"+ + "\4\0\2\25\3\0\2\25\1\0\1\25\4\0\1\25"+ + "\1\0\1\25\2\0\2\25\1\0\3\25\1\0\1\25"+ + "\2\0\4\25\2\0\1\25\40\0\1\34\1\0\1\35"+ + "\1\0\1\36\1\0\1\37\1\0\1\40\1\0\1\101"+ + "\3\0\1\42\5\0\1\43\3\0\1\102\11\0\1\45"+ + "\2\0\1\103\16\0\1\104\2\0\1\105\41\0\1\25"+ + "\2\51\2\0\2\106\1\53\1\0\1\51\3\0\1\34"+ + "\1\0\1\35\1\0\1\36\1\0\1\37\1\0\1\40"+ + "\1\0\1\107\3\0\1\110\5\0\1\111\3\0\1\112"+ + "\11\0\1\45\2\0\1\113\16\0\1\114\2\0\1\115"+ + "\41\0\1\25\1\52\7\0\1\52\3\0\1\34\1\0"+ + "\1\35\1\0\1\36\1\0\1\37\1\0\1\40\1\0"+ + "\1\116\3\0\1\42\5\0\1\43\3\0\1\117\11\0"+ + "\1\45\2\0\1\120\16\0\1\121\2\0\1\122\21\0"+ + "\1\72\17\0\1\25\1\53\1\51\1\27\3\0\1\53"+ + "\1\0\1\53\4\0\1\26\11\0\3\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\4\0\1\25\4\0\1\26"+ + "\1\0\2\26\4\0\1\25\5\0\1\25\3\0\1\26"+ + "\4\0\1\26\2\25\2\26\10\0\1\26\1\0\2\25"+ + "\1\0\1\26\10\0\1\25\23\0\1\25\3\0\1\25"+ + "\6\0\2\25\5\0\1\25\1\0\1\25\1\0\1\25"+ + "\1\0\11\25\2\0\1\25\4\0\1\25\4\0\6\25"+ + "\2\0\1\25\1\0\1\25\1\0\3\25\1\0\1\26"+ + "\1\0\2\25\4\0\3\25\1\0\1\25\10\0\1\25"+ + "\1\0\2\25\20\0\1\25\3\0\1\25\5\0\1\25"+ + "\32\0\15\25\5\0\3\25\1\0\1\25\5\0\1\25"+ + "\2\26\5\0\1\25\2\0\1\25\1\26\4\0\1\25"+ + "\2\0\1\25\1\0\1\25\102\0\2\26\6\0\1\26"+ + "\55\0\1\26\3\0\1\26\2\0\1\26\3\0\1\26"+ + "\5\0\1\26\7\0\1\26\4\0\2\26\3\0\2\26"+ + "\1\0\1\26\4\0\1\26\1\0\1\26\2\0\2\26"+ + "\1\0\3\26\1\0\1\26\2\0\4\26\2\0\1\26"+ + "\52\0\1\123\3\0\1\124\5\0\1\125\3\0\1\126"+ + "\14\0\1\127\16\0\1\130\2\0\1\131\42\0\1\63"+ + "\1\26\6\0\1\63\3\0\1\34\1\0\1\35\1\0"+ + "\1\36\1\0\1\37\1\0\1\40\1\0\1\132\3\0"+ + "\1\55\5\0\1\56\3\0\1\133\11\0\1\45\2\0"+ + "\1\134\16\0\1\135\2\0\1\136\21\0\1\72\17\0"+ + "\1\25\1\64\1\26\1\27\3\0\1\64\1\0\1\64"+ + "\4\0\1\27\37\0\1\27\1\0\2\27\16\0\1\27"+ + "\4\0\1\27\2\0\2\27\15\0\1\27\131\0\1\27"+ + "\152\0\2\27\11\0\1\27\114\0\2\27\6\0\1\27"+ + "\55\0\1\27\3\0\1\27\2\0\1\27\3\0\1\27"+ + "\5\0\1\27\7\0\1\27\4\0\2\27\3\0\2\27"+ + "\1\0\1\27\4\0\1\27\1\0\1\27\2\0\2\27"+ + "\1\0\3\27\1\0\1\27\2\0\4\27\2\0\1\27"+ + "\152\0\1\27\34\0\1\100\11\0\3\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\4\0\1\25\4\0\1\100"+ + "\1\0\2\100\4\0\1\25\5\0\1\25\3\0\1\100"+ + "\4\0\1\100\2\25\2\100\10\0\1\26\1\0\2\25"+ + "\1\0\1\100\10\0\1\25\23\0\1\25\3\0\1\25"+ + "\6\0\2\25\5\0\1\25\1\0\1\25\1\0\1\25"+ + "\1\0\11\25\2\0\1\25\4\0\1\25\4\0\6\25"+ + "\2\0\1\25\1\0\1\25\1\0\3\25\1\0\1\100"+ + "\1\0\2\25\4\0\3\25\1\0\1\25\10\0\1\25"+ + "\1\0\2\25\20\0\1\25\3\0\1\25\5\0\1\25"+ + "\32\0\15\25\5\0\3\25\1\0\1\25\5\0\1\25"+ + "\2\100\5\0\1\25\2\0\1\25\1\100\4\0\1\25"+ + "\2\0\1\25\1\0\1\25\102\0\2\100\6\0\1\100"+ + "\55\0\1\100\3\0\1\100\2\0\1\100\3\0\1\100"+ + "\5\0\1\100\7\0\1\100\4\0\2\100\3\0\2\100"+ + "\1\0\1\100\4\0\1\100\1\0\1\100\2\0\2\100"+ + "\1\0\3\100\1\0\1\100\2\0\4\100\2\0\1\100"+ + "\41\0\1\51\11\0\3\25\5\0\1\25\1\0\1\25"+ + "\1\0\1\25\4\0\1\25\4\0\1\51\1\0\2\51"+ + "\4\0\1\25\5\0\1\25\3\0\1\51\4\0\1\51"+ + "\2\25\2\51\10\0\1\51\1\0\2\25\1\0\1\51"+ + "\10\0\1\25\23\0\1\25\3\0\1\25\6\0\2\25"+ + "\5\0\1\25\1\0\1\25\1\0\1\25\1\0\11\25"+ + "\2\0\1\25\4\0\1\25\4\0\6\25\2\0\1\25"+ + "\1\0\1\25\1\0\3\25\1\0\1\51\1\0\2\25"+ + "\4\0\3\25\1\0\1\25\10\0\1\25\1\0\2\25"+ + "\20\0\1\25\3\0\1\25\5\0\1\25\32\0\15\25"+ + "\5\0\3\25\1\0\1\25\5\0\1\25\2\51\5\0"+ + "\1\25\2\0\1\25\1\51\4\0\1\25\2\0\1\25"+ + "\1\0\1\25\102\0\2\51\6\0\1\51\55\0\1\51"+ + "\3\0\1\51\2\0\1\51\3\0\1\51\5\0\1\51"+ + "\7\0\1\51\4\0\2\51\3\0\2\51\1\0\1\51"+ + "\4\0\1\51\1\0\1\51\2\0\2\51\1\0\3\51"+ + "\1\0\1\51\2\0\4\51\2\0\1\51\52\0\1\137"+ + "\3\0\1\140\5\0\1\141\3\0\1\142\14\0\1\143"+ + "\16\0\1\144\2\0\1\145\42\0\1\106\1\51\6\0"+ + "\1\106\4\0\1\52\11\0\3\25\5\0\1\25\1\0"+ + "\1\25\1\0\1\25\4\0\1\25\4\0\1\52\1\0"+ + "\2\52\4\0\1\25\5\0\1\25\3\0\1\52\4\0"+ + "\1\52\2\25\2\52\12\0\2\25\1\0\1\52\10\0"+ + "\1\25\23\0\1\25\11\0\2\25\2\0\5\25\2\0"+ + "\2\25\4\0\6\25\1\0\2\25\4\0\5\25\1\0"+ + "\5\25\1\0\2\25\1\0\3\25\1\0\4\25\1\0"+ + "\5\25\2\0\1\25\1\0\1\25\1\0\3\25\2\0"+ + "\1\25\1\0\1\25\1\0\1\25\2\0\1\25\16\0"+ + "\1\25\3\0\1\25\5\0\2\25\3\0\1\25\4\0"+ + "\3\25\4\0\1\25\1\0\1\25\2\0\1\25\1\0"+ + "\2\25\4\0\1\25\1\0\1\25\3\0\2\25\1\0"+ + "\1\25\5\0\3\25\1\0\1\25\10\0\1\25\4\0"+ + "\1\25\10\0\1\25\23\0\1\25\3\0\1\25\6\0"+ + "\2\25\5\0\1\25\1\0\1\25\1\0\1\25\1\0"+ + "\11\25\2\0\1\25\4\0\1\25\4\0\6\25\2\0"+ + "\1\25\1\0\1\25\1\0\3\25\1\0\1\52\1\0"+ + "\2\25\4\0\3\25\1\0\1\25\10\0\1\25\1\0"+ + "\2\25\20\0\1\25\3\0\1\25\5\0\1\25\32\0"+ + "\15\25\5\0\3\25\1\0\1\25\5\0\1\25\2\52"+ + "\5\0\1\25\2\0\1\25\1\52\4\0\1\25\2\0"+ + "\1\25\1\0\1\25\102\0\2\52\6\0\1\52\55\0"+ + "\1\52\3\0\1\52\2\0\1\52\3\0\1\52\5\0"+ + "\1\52\7\0\1\52\4\0\2\52\3\0\2\52\1\0"+ + "\1\52\4\0\1\52\1\0\1\52\2\0\2\52\1\0"+ + "\3\52\1\0\1\52\2\0\4\52\2\0\1\52\41\0"+ + "\1\53\11\0\3\25\5\0\1\25\1\0\1\25\1\0"+ + "\1\25\4\0\1\25\4\0\1\53\1\0\2\53\4\0"+ + "\1\25\5\0\1\25\3\0\1\53\4\0\1\53\2\25"+ + "\2\53\10\0\1\51\1\0\2\25\1\0\1\53\10\0"+ + "\1\25\23\0\1\25\3\0\1\25\6\0\2\25\5\0"+ + "\1\25\1\0\1\25\1\0\1\25\1\0\11\25\2\0"+ + "\1\25\4\0\1\25\4\0\6\25\2\0\1\25\1\0"+ + "\1\25\1\0\3\25\1\0\1\53\1\0\2\25\4\0"+ + "\3\25\1\0\1\25\10\0\1\25\1\0\2\25\20\0"+ + "\1\25\3\0\1\25\5\0\1\25\32\0\15\25\5\0"+ + "\3\25\1\0\1\25\5\0\1\25\2\53\5\0\1\25"+ + "\2\0\1\25\1\53\4\0\1\25\2\0\1\25\1\0"+ + "\1\25\102\0\2\53\6\0\1\53\55\0\1\53\3\0"+ + "\1\53\2\0\1\53\3\0\1\53\5\0\1\53\7\0"+ + "\1\53\4\0\2\53\3\0\2\53\1\0\1\53\4\0"+ + "\1\53\1\0\1\53\2\0\2\53\1\0\3\53\1\0"+ + "\1\53\2\0\4\53\2\0\1\53\41\0\1\63\37\0"+ + "\1\63\1\0\2\63\16\0\1\63\4\0\1\63\2\0"+ + "\2\63\10\0\1\26\4\0\1\63\36\0\1\26\102\0"+ + "\1\26\146\0\2\26\133\0\1\63\152\0\2\63\11\0"+ + "\1\63\114\0\2\63\6\0\1\63\55\0\1\63\3\0"+ + "\1\63\2\0\1\63\3\0\1\63\5\0\1\63\7\0"+ + "\1\63\4\0\2\63\3\0\2\63\1\0\1\63\4\0"+ + "\1\63\1\0\1\63\2\0\2\63\1\0\3\63\1\0"+ + "\1\63\2\0\4\63\2\0\1\63\41\0\1\64\11\0"+ + "\3\25\5\0\1\25\1\0\1\25\1\0\1\25\4\0"+ + "\1\25\4\0\1\64\1\0\2\64\4\0\1\25\5\0"+ + "\1\25\3\0\1\64\4\0\1\64\2\25\2\64\10\0"+ + "\1\26\1\0\2\25\1\0\1\64\10\0\1\25\23\0"+ + "\1\25\3\0\1\25\6\0\2\25\5\0\1\25\1\0"+ + "\1\25\1\0\1\25\1\0\11\25\2\0\1\25\4\0"+ + "\1\25\4\0\6\25\2\0\1\25\1\0\1\25\1\0"+ + "\3\25\1\0\1\64\1\0\2\25\4\0\3\25\1\0"+ + "\1\25\10\0\1\25\1\0\2\25\20\0\1\25\3\0"+ + "\1\25\5\0\1\25\32\0\15\25\5\0\3\25\1\0"+ + "\1\25\5\0\1\25\2\64\5\0\1\25\2\0\1\25"+ + "\1\64\4\0\1\25\2\0\1\25\1\0\1\25\102\0"+ + "\2\64\6\0\1\64\55\0\1\64\3\0\1\64\2\0"+ + "\1\64\3\0\1\64\5\0\1\64\7\0\1\64\4\0"+ + "\2\64\3\0\2\64\1\0\1\64\4\0\1\64\1\0"+ + "\1\64\2\0\2\64\1\0\3\64\1\0\1\64\2\0"+ + "\4\64\2\0\1\64\41\0\1\106\37\0\1\106\1\0"+ + "\2\106\16\0\1\106\4\0\1\106\2\0\2\106\10\0"+ + "\1\51\4\0\1\106\36\0\1\51\102\0\1\51\146\0"+ + "\2\51\133\0\1\106\152\0\2\106\11\0\1\106\114\0"+ + "\2\106\6\0\1\106\55\0\1\106\3\0\1\106\2\0"+ + "\1\106\3\0\1\106\5\0\1\106\7\0\1\106\4\0"+ + "\2\106\3\0\2\106\1\0\1\106\4\0\1\106\1\0"+ + "\1\106\2\0\2\106\1\0\3\106\1\0\1\106\2\0"+ + "\4\106\2\0\1\106\37\0"; private static int [] zzUnpackTrans() { - int [] result = new int[169]; + int [] result = new int[9180]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -299,11 +584,11 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\5\1\2\11\1\1\1\0\1\1\1\0"+ - "\1\1\2\0"; + "\1\0\1\11\27\1\2\11\15\0\1\1\1\0\1\1"+ + "\10\0\1\1\61\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[16]; + int [] result = new int[101]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -434,7 +719,7 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 2174) { + while (i < 2640) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -713,28 +998,28 @@ public final class StandardTokenizerImpl implements StandardTokenizerInterface { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 1: - { /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ - } - case 7: break; - case 6: - { return HIRAGANA_TYPE; - } - case 8: break; case 2: { return WORD_TYPE; } - case 9: break; + case 7: break; + case 4: + { return SOUTH_EAST_ASIAN_TYPE; + } + case 8: break; case 5: { return IDEOGRAPHIC_TYPE; } + case 9: break; + case 1: + { /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ + } case 10: break; case 3: { return NUMERIC_TYPE; } case 11: break; - case 4: - { return SOUTH_EAST_ASIAN_TYPE; + case 6: + { return HIRAGANA_TYPE; } case 12: break; default: diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex index 7cb8ee498f4..8c805923466 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerImpl.jflex @@ -33,14 +33,6 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; *
  7. <IDEOGRAPHIC>: A single CJKV ideographic character
  8. *
  9. <HIRAGANA>: A single hiragana character
  10. * - * WARNING: Because JFlex does not support Unicode supplementary - * characters (characters above the Basic Multilingual Plane, which contains - * those up to and including U+FFFF), this scanner will not recognize them - * properly. If you need to be able to process text containing supplementary - * characters, consider using the ICU4J-backed implementation in modules/analysis/icu - * (org.apache.lucene.analysis.icu.segmentation.ICUTokenizer) - * instead of this class, since the ICU4J-backed implementation does not have - * this limitation. */ %% @@ -53,15 +45,29 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; %function getNextToken %char +%include src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro +ALetter = ([\p{WB:ALetter}] | {ALetterSupp}) +Format = ([\p{WB:Format}] | {FormatSupp}) +Numeric = ([\p{WB:Numeric}] | {NumericSupp}) +Extend = ([\p{WB:Extend}] | {ExtendSupp}) +Katakana = ([\p{WB:Katakana}] | {KatakanaSupp}) +MidLetter = ([\p{WB:MidLetter}] | {MidLetterSupp}) +MidNum = ([\p{WB:MidNum}] | {MidNumSupp}) +MidNumLet = ([\p{WB:MidNumLet}] | {MidNumLetSupp}) +ExtendNumLet = ([\p{WB:ExtendNumLet}] | {ExtendNumLetSupp}) +ComplexContext = ([\p{LB:Complex_Context}] | {ComplexContextSupp}) +Han = ([\p{Script:Han}] | {HanSupp}) +Hiragana = ([\p{Script:Hiragana}] | {HiraganaSupp}) + // UAX#29 WB4. X (Extend | Format)* --> X // -ALetterEx = \p{WB:ALetter} [\p{WB:Format}\p{WB:Extend}]* +ALetterEx = {ALetter} ({Format} | {Extend})* // TODO: Convert hard-coded full-width numeric range to property intersection (something like [\p{Full-Width}&&\p{Numeric}]) once JFlex supports it -NumericEx = [\p{WB:Numeric}\uFF10-\uFF19] [\p{WB:Format}\p{WB:Extend}]* -KatakanaEx = \p{WB:Katakana} [\p{WB:Format}\p{WB:Extend}]* -MidLetterEx = [\p{WB:MidLetter}\p{WB:MidNumLet}] [\p{WB:Format}\p{WB:Extend}]* -MidNumericEx = [\p{WB:MidNum}\p{WB:MidNumLet}] [\p{WB:Format}\p{WB:Extend}]* -ExtendNumLetEx = \p{WB:ExtendNumLet} [\p{WB:Format}\p{WB:Extend}]* +NumericEx = ({Numeric} | [\uFF10-\uFF19]) ({Format} | {Extend})* +KatakanaEx = {Katakana} ({Format} | {Extend})* +MidLetterEx = ({MidLetter} | {MidNumLet}) ({Format} | {Extend})* +MidNumericEx = ({MidNum} | {MidNumLet}) ({Format} | {Extend})* +ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* %{ @@ -156,12 +162,12 @@ ExtendNumLetEx = \p{WB:ExtendNumLet} [\p{WB:Format}\p{WB:Extend}] // // http://www.unicode.org/reports/tr14/#SA // -\p{LB:Complex_Context}+ { return SOUTH_EAST_ASIAN_TYPE; } +{ComplexContext}+ { return SOUTH_EAST_ASIAN_TYPE; } // UAX#29 WB14. Any 梅 Any // -\p{Script:Han} { return IDEOGRAPHIC_TYPE; } -\p{Script:Hiragana} { return HIRAGANA_TYPE; } +{Han} { return IDEOGRAPHIC_TYPE; } +{Hiragana} { return HIRAGANA_TYPE; } // UAX#29 WB3. CR 脳 LF diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.java index 4ba30beba26..f440611eeb6 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.5.0-SNAPSHOT on 12/4/10 7:24 PM */ +/* The following code was generated by JFlex 1.5.0-SNAPSHOT on 1/6/11 12:09 AM */ package org.apache.lucene.analysis.standard; @@ -47,14 +47,6 @@ import org.apache.lucene.util.AttributeSource; *
  11. <IDEOGRAPHIC>: A single CJKV ideographic character
  12. *
  13. <HIRAGANA>: A single hiragana character
  14. * - * WARNING: Because JFlex does not support Unicode supplementary - * characters (characters above the Basic Multilingual Plane, which contains - * those up to and including U+FFFF), this scanner will not recognize them - * properly. If you need to be able to process text containing supplementary - * characters, consider using the ICU4J-backed implementation in modules/analysis/icu - * (org.apache.lucene.analysis.icu.segmentation.ICUTokenizer) - * instead of this class, since the ICU4J-backed implementation does not have - * this limitation. */ public final class UAX29URLEmailTokenizer extends Tokenizer { @@ -82,123 +74,147 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\1\101\10\77\2\101\2\77\1\101\23\77\1\102\1\76\1\71\1\102"+ - "\1\62\1\60\1\65\2\63\2\102\1\64\1\44\1\11\1\70\1\45"+ - "\1\50\1\55\1\51\1\54\1\46\1\47\1\56\1\53\1\52\1\57"+ - "\1\74\1\77\1\75\1\77\1\67\1\66\1\12\1\36\1\13\1\14"+ - "\1\15\1\20\1\21\1\37\1\22\1\40\1\43\1\23\1\24\1\25"+ - "\1\17\1\27\1\26\1\16\1\30\1\31\1\32\1\41\1\33\1\34"+ - "\1\42\1\35\1\72\1\100\1\73\1\103\1\61\1\103\1\12\1\36"+ - "\1\13\1\14\1\15\1\20\1\21\1\37\1\22\1\40\1\43\1\23"+ - "\1\24\1\25\1\17\1\27\1\26\1\16\1\30\1\31\1\32\1\41"+ - "\1\33\1\34\1\42\1\35\3\103\1\60\1\104\52\0\1\1\2\0"+ - "\1\2\7\0\1\1\1\0\1\5\2\0\1\1\5\0\27\1\1\0"+ - "\37\1\1\0\u01ca\1\4\0\14\1\16\0\5\1\7\0\1\1\1\0"+ - "\1\1\21\0\160\2\5\1\1\0\2\1\2\0\4\1\1\6\7\0"+ - "\1\1\1\5\3\1\1\0\1\1\1\0\24\1\1\0\123\1\1\0"+ - "\213\1\1\0\7\2\236\1\11\0\46\1\2\0\1\1\7\0\47\1"+ - "\1\0\1\6\7\0\55\2\1\0\1\2\1\0\2\2\1\0\2\2"+ - "\1\0\1\2\10\0\33\1\5\0\4\1\1\5\13\0\4\2\10\0"+ - "\2\6\2\0\13\2\5\0\53\1\25\2\12\3\1\0\1\3\1\6"+ - "\1\0\2\1\1\2\143\1\1\0\1\1\10\2\1\0\6\2\2\1"+ - "\2\2\1\0\4\2\2\1\12\3\3\1\2\0\1\1\17\0\1\2"+ - "\1\1\1\2\36\1\33\2\2\0\131\1\13\2\1\1\16\0\12\3"+ - "\41\1\11\2\2\1\2\0\1\6\1\0\1\1\5\0\26\1\4\2"+ - "\1\1\11\2\1\1\3\2\1\1\5\2\22\0\31\1\3\2\244\0"+ - "\4\2\66\1\3\2\1\1\22\2\1\1\7\2\12\1\2\2\2\0"+ - "\12\3\1\0\7\1\1\0\7\1\1\0\3\2\1\0\10\1\2\0"+ - "\2\1\2\0\26\1\1\0\7\1\1\0\1\1\3\0\4\1\2\0"+ - "\1\2\1\1\7\2\2\0\2\2\2\0\3\2\1\1\10\0\1\2"+ - "\4\0\2\1\1\0\3\1\2\2\2\0\12\3\2\1\17\0\3\2"+ - "\1\0\6\1\4\0\2\1\2\0\26\1\1\0\7\1\1\0\2\1"+ - "\1\0\2\1\1\0\2\1\2\0\1\2\1\0\5\2\4\0\2\2"+ - "\2\0\3\2\3\0\1\2\7\0\4\1\1\0\1\1\7\0\12\3"+ - "\2\2\3\1\1\2\13\0\3\2\1\0\11\1\1\0\3\1\1\0"+ - "\26\1\1\0\7\1\1\0\2\1\1\0\5\1\2\0\1\2\1\1"+ - "\10\2\1\0\3\2\1\0\3\2\2\0\1\1\17\0\2\1\2\2"+ - "\2\0\12\3\21\0\3\2\1\0\10\1\2\0\2\1\2\0\26\1"+ - "\1\0\7\1\1\0\2\1\1\0\5\1\2\0\1\2\1\1\7\2"+ - "\2\0\2\2\2\0\3\2\10\0\2\2\4\0\2\1\1\0\3\1"+ - "\2\2\2\0\12\3\1\0\1\1\20\0\1\2\1\1\1\0\6\1"+ - "\3\0\3\1\1\0\4\1\3\0\2\1\1\0\1\1\1\0\2\1"+ - "\3\0\2\1\3\0\3\1\3\0\14\1\4\0\5\2\3\0\3\2"+ - "\1\0\4\2\2\0\1\1\6\0\1\2\16\0\12\3\21\0\3\2"+ - "\1\0\10\1\1\0\3\1\1\0\27\1\1\0\12\1\1\0\5\1"+ - "\3\0\1\1\7\2\1\0\3\2\1\0\4\2\7\0\2\2\1\0"+ - "\2\1\6\0\2\1\2\2\2\0\12\3\22\0\2\2\1\0\10\1"+ - "\1\0\3\1\1\0\27\1\1\0\12\1\1\0\5\1\2\0\1\2"+ - "\1\1\7\2\1\0\3\2\1\0\4\2\7\0\2\2\7\0\1\1"+ - "\1\0\2\1\2\2\2\0\12\3\1\0\2\1\17\0\2\2\1\0"+ - "\10\1\1\0\3\1\1\0\51\1\2\0\1\1\7\2\1\0\3\2"+ - "\1\0\4\2\1\1\10\0\1\2\10\0\2\1\2\2\2\0\12\3"+ - "\12\0\6\1\2\0\2\2\1\0\22\1\3\0\30\1\1\0\11\1"+ - "\1\0\1\1\2\0\7\1\3\0\1\2\4\0\6\2\1\0\1\2"+ - "\1\0\10\2\22\0\2\2\15\0\60\105\1\106\2\105\7\106\5\0"+ - "\7\105\10\106\1\0\12\3\47\0\2\105\1\0\1\105\2\0\2\105"+ - "\1\0\1\105\2\0\1\105\6\0\4\105\1\0\7\105\1\0\3\105"+ - "\1\0\1\105\1\0\1\105\2\0\2\105\1\0\4\105\1\106\2\105"+ - "\6\106\1\0\2\106\1\105\2\0\5\105\1\0\1\105\1\0\6\106"+ - "\2\0\12\3\2\0\2\105\42\0\1\1\27\0\2\2\6\0\12\3"+ - "\13\0\1\2\1\0\1\2\1\0\1\2\4\0\2\2\10\1\1\0"+ - "\44\1\4\0\24\2\1\0\2\2\5\1\13\2\1\0\44\2\11\0"+ - "\1\2\71\0\53\105\24\106\1\105\12\3\6\0\6\105\4\106\4\105"+ - "\3\106\1\105\3\106\2\105\7\106\3\105\4\106\15\105\14\106\1\105"+ - "\1\106\12\3\4\106\2\105\46\1\12\0\53\1\1\0\1\1\3\0"+ - "\u0149\1\1\0\4\1\2\0\7\1\1\0\1\1\1\0\4\1\2\0"+ - "\51\1\1\0\4\1\2\0\41\1\1\0\4\1\2\0\7\1\1\0"+ - "\1\1\1\0\4\1\2\0\17\1\1\0\71\1\1\0\4\1\2\0"+ - "\103\1\2\0\3\2\40\0\20\1\20\0\125\1\14\0\u026c\1\2\0"+ - "\21\1\1\0\32\1\5\0\113\1\3\0\3\1\17\0\15\1\1\0"+ - "\4\1\3\2\13\0\22\1\3\2\13\0\22\1\2\2\14\0\15\1"+ - "\1\0\3\1\1\0\2\2\14\0\64\105\40\106\3\0\1\105\4\0"+ - "\1\105\1\106\2\0\12\3\41\0\3\2\2\0\12\3\6\0\130\1"+ - "\10\0\51\1\1\2\1\1\5\0\106\1\12\0\35\1\3\0\14\2"+ - "\4\0\14\2\12\0\12\3\36\105\2\0\5\105\13\0\54\105\4\0"+ - "\21\106\7\105\2\106\6\0\12\3\1\105\3\0\2\105\40\0\27\1"+ - "\5\2\4\0\65\105\12\106\1\0\35\106\2\0\1\2\12\3\6\0"+ - "\12\3\6\0\16\105\122\0\5\2\57\1\21\2\7\1\4\0\12\3"+ - "\21\0\11\2\14\0\3\2\36\1\12\2\3\0\2\1\12\3\6\0"+ - "\46\1\16\2\14\0\44\1\24\2\10\0\12\3\3\0\3\1\12\3"+ - "\44\1\122\0\3\2\1\0\25\2\4\1\1\2\4\1\1\2\15\0"+ - "\300\1\47\2\25\0\4\2\u0116\1\2\0\6\1\2\0\46\1\2\0"+ - "\6\1\2\0\10\1\1\0\1\1\1\0\1\1\1\0\1\1\1\0"+ - "\37\1\2\0\65\1\1\0\7\1\1\0\1\1\3\0\3\1\1\0"+ - "\7\1\3\0\4\1\2\0\6\1\4\0\15\1\5\0\3\1\1\0"+ - "\7\1\17\0\4\2\10\0\2\7\12\0\1\7\2\0\1\5\2\0"+ - "\5\2\20\0\2\10\3\0\1\6\17\0\1\10\13\0\5\2\5\0"+ - "\6\2\1\0\1\1\15\0\1\1\20\0\15\1\63\0\41\2\21\0"+ - "\1\1\4\0\1\1\2\0\12\1\1\0\1\1\3\0\5\1\6\0"+ - "\1\1\1\0\1\1\1\0\1\1\1\0\4\1\1\0\13\1\2\0"+ - "\4\1\5\0\5\1\4\0\1\1\21\0\51\1\u032d\0\64\1\u0716\0"+ - "\57\1\1\0\57\1\1\0\205\1\6\0\4\1\3\2\16\0\46\1"+ - "\12\0\66\1\11\0\1\1\17\0\1\2\27\1\11\0\7\1\1\0"+ - "\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0"+ - "\7\1\1\0\7\1\1\0\40\2\57\0\1\1\120\0\32\107\1\0"+ - "\131\107\14\0\326\107\57\0\1\1\1\0\1\107\31\0\11\107\6\2"+ - "\1\0\5\4\2\0\3\107\1\1\1\1\4\0\126\110\2\0\2\2"+ - "\2\4\3\110\133\4\1\0\4\4\5\0\51\1\3\0\136\1\21\0"+ - "\33\1\65\0\20\4\320\0\57\4\1\0\130\4\250\0\u19b6\107\112\0"+ - "\u51cc\107\64\0\u048d\1\103\0\56\1\2\0\u010d\1\3\0\20\1\12\3"+ - "\2\1\24\0\57\1\4\2\11\0\2\2\1\0\31\1\10\0\120\1"+ - "\2\2\45\0\11\1\2\0\147\1\2\0\4\1\1\0\2\1\16\0"+ - "\12\1\120\0\10\1\1\2\3\1\1\2\4\1\1\2\27\1\5\2"+ - "\30\0\64\1\14\0\2\2\62\1\21\2\13\0\12\3\6\0\22\2"+ - "\6\1\3\0\1\1\4\0\12\3\34\1\10\2\2\0\27\1\15\2"+ - "\14\0\35\1\3\0\4\2\57\1\16\2\16\0\1\1\12\3\46\0"+ - "\51\1\16\2\11\0\3\1\1\2\10\1\2\2\2\0\12\3\6\0"+ - "\33\105\1\106\4\0\60\105\1\106\1\105\3\106\2\105\2\106\5\105"+ - "\2\106\1\105\1\106\1\105\30\0\5\105\41\0\6\1\2\0\6\1"+ - "\2\0\6\1\11\0\7\1\1\0\7\1\221\0\43\1\10\2\1\0"+ - "\2\2\2\0\12\3\6\0\u2ba4\1\14\0\27\1\4\0\61\1\u2104\0"+ - "\u012e\107\2\0\76\107\2\0\152\107\46\0\7\1\14\0\5\1\5\0"+ - "\1\1\1\2\12\1\1\0\15\1\1\0\5\1\1\0\1\1\1\0"+ - "\2\1\1\0\2\1\1\0\154\1\41\0\u016b\1\22\0\100\1\2\0"+ - "\66\1\50\0\14\1\4\0\20\2\1\6\2\0\1\5\1\6\13\0"+ - "\7\2\14\0\2\10\30\0\3\10\1\6\1\0\1\7\1\0\1\6"+ - "\1\5\32\0\5\1\1\0\207\1\2\0\1\2\7\0\1\7\4\0"+ - "\1\6\1\0\1\7\1\0\12\3\1\5\1\6\5\0\32\1\4\0"+ - "\1\10\1\0\32\1\13\0\70\4\2\2\37\1\3\0\6\1\2\0"+ - "\6\1\2\0\6\1\2\0\3\1\34\0\3\2\4\0"; + "\1\236\10\234\2\236\2\234\1\236\23\234\1\237\1\233\1\226\1\237"+ + "\1\217\1\215\1\222\2\220\2\237\1\221\1\201\1\146\1\225\1\202"+ + "\1\205\1\212\1\206\1\211\1\203\1\204\1\213\1\210\1\207\1\214"+ + "\1\231\1\234\1\232\1\234\1\224\1\223\1\147\1\173\1\150\1\151"+ + "\1\152\1\155\1\156\1\174\1\157\1\175\1\200\1\160\1\161\1\162"+ + "\1\154\1\164\1\163\1\153\1\165\1\166\1\167\1\176\1\170\1\171"+ + "\1\177\1\172\1\227\1\235\1\230\1\240\1\216\1\240\1\147\1\173"+ + "\1\150\1\151\1\152\1\155\1\156\1\174\1\157\1\175\1\200\1\160"+ + "\1\161\1\162\1\154\1\164\1\163\1\153\1\165\1\166\1\167\1\176"+ + "\1\170\1\171\1\177\1\172\3\240\1\215\1\241\52\0\1\132\2\0"+ + "\1\133\7\0\1\132\1\0\1\136\2\0\1\132\5\0\27\132\1\0"+ + "\37\132\1\0\u01ca\132\4\0\14\132\16\0\5\132\7\0\1\132\1\0"+ + "\1\132\21\0\160\133\5\132\1\0\2\132\2\0\4\132\1\137\7\0"+ + "\1\132\1\136\3\132\1\0\1\132\1\0\24\132\1\0\123\132\1\0"+ + "\213\132\1\0\7\133\236\132\11\0\46\132\2\0\1\132\7\0\47\132"+ + "\1\0\1\137\7\0\55\133\1\0\1\133\1\0\2\133\1\0\2\133"+ + "\1\0\1\133\10\0\33\132\5\0\4\132\1\136\13\0\4\133\10\0"+ + "\2\137\2\0\13\133\5\0\53\132\25\133\12\134\1\0\1\134\1\137"+ + "\1\0\2\132\1\133\143\132\1\0\1\132\7\133\1\133\1\0\6\133"+ + "\2\132\2\133\1\0\4\133\2\132\12\134\3\132\2\0\1\132\17\0"+ + "\1\133\1\132\1\133\36\132\33\133\2\0\131\132\13\133\1\132\16\0"+ + "\12\134\41\132\11\133\2\132\2\0\1\137\1\0\1\132\5\0\26\132"+ + "\4\133\1\132\11\133\1\132\3\133\1\132\5\133\22\0\31\132\3\133"+ + "\244\0\4\133\66\132\3\133\1\132\22\133\1\132\7\133\12\132\2\133"+ + "\2\0\12\134\1\0\7\132\1\0\7\132\1\0\3\133\1\0\10\132"+ + "\2\0\2\132\2\0\26\132\1\0\7\132\1\0\1\132\3\0\4\132"+ + "\2\0\1\133\1\132\7\133\2\0\2\133\2\0\3\133\1\132\10\0"+ + "\1\133\4\0\2\132\1\0\3\132\2\133\2\0\12\134\2\132\17\0"+ + "\3\133\1\0\6\132\4\0\2\132\2\0\26\132\1\0\7\132\1\0"+ + "\2\132\1\0\2\132\1\0\2\132\2\0\1\133\1\0\5\133\4\0"+ + "\2\133\2\0\3\133\3\0\1\133\7\0\4\132\1\0\1\132\7\0"+ + "\12\134\2\133\3\132\1\133\13\0\3\133\1\0\11\132\1\0\3\132"+ + "\1\0\26\132\1\0\7\132\1\0\2\132\1\0\5\132\2\0\1\133"+ + "\1\132\10\133\1\0\3\133\1\0\3\133\2\0\1\132\17\0\2\132"+ + "\2\133\2\0\12\134\21\0\3\133\1\0\10\132\2\0\2\132\2\0"+ + "\26\132\1\0\7\132\1\0\2\132\1\0\5\132\2\0\1\133\1\132"+ + "\7\133\2\0\2\133\2\0\3\133\10\0\2\133\4\0\2\132\1\0"+ + "\3\132\2\133\2\0\12\134\1\0\1\132\20\0\1\133\1\132\1\0"+ + "\6\132\3\0\3\132\1\0\4\132\3\0\2\132\1\0\1\132\1\0"+ + "\2\132\3\0\2\132\3\0\3\132\3\0\14\132\4\0\5\133\3\0"+ + "\3\133\1\0\4\133\2\0\1\132\6\0\1\133\16\0\12\134\21\0"+ + "\3\133\1\0\10\132\1\0\3\132\1\0\27\132\1\0\12\132\1\0"+ + "\5\132\3\0\1\132\7\133\1\0\3\133\1\0\4\133\7\0\2\133"+ + "\1\0\2\132\6\0\2\132\2\133\2\0\12\134\22\0\2\133\1\0"+ + "\10\132\1\0\3\132\1\0\27\132\1\0\12\132\1\0\5\132\2\0"+ + "\1\133\1\132\7\133\1\0\3\133\1\0\4\133\7\0\2\133\7\0"+ + "\1\132\1\0\2\132\2\133\2\0\12\134\1\0\2\132\17\0\2\133"+ + "\1\0\10\132\1\0\3\132\1\0\51\132\2\0\1\132\7\133\1\0"+ + "\3\133\1\0\4\133\1\132\10\0\1\133\10\0\2\132\2\133\2\0"+ + "\12\134\12\0\6\132\2\0\2\133\1\0\22\132\3\0\30\132\1\0"+ + "\11\132\1\0\1\132\2\0\7\132\3\0\1\133\4\0\6\133\1\0"+ + "\1\133\1\0\10\133\22\0\2\133\15\0\60\142\1\143\2\142\7\143"+ + "\5\0\7\142\10\143\1\0\12\134\47\0\2\142\1\0\1\142\2\0"+ + "\2\142\1\0\1\142\2\0\1\142\6\0\4\142\1\0\7\142\1\0"+ + "\3\142\1\0\1\142\1\0\1\142\2\0\2\142\1\0\4\142\1\143"+ + "\2\142\6\143\1\0\2\143\1\142\2\0\5\142\1\0\1\142\1\0"+ + "\6\143\2\0\12\134\2\0\2\142\42\0\1\132\27\0\2\133\6\0"+ + "\12\134\13\0\1\133\1\0\1\133\1\0\1\133\4\0\2\133\10\132"+ + "\1\0\44\132\4\0\24\133\1\0\2\133\5\132\13\133\1\0\44\133"+ + "\11\0\1\133\71\0\53\142\24\143\1\142\12\134\6\0\6\142\4\143"+ + "\4\142\3\143\1\142\3\143\2\142\7\143\3\142\4\143\15\142\14\143"+ + "\1\142\1\143\12\134\4\143\2\142\46\132\12\0\53\132\1\0\1\132"+ + "\3\0\u0149\132\1\0\4\132\2\0\7\132\1\0\1\132\1\0\4\132"+ + "\2\0\51\132\1\0\4\132\2\0\41\132\1\0\4\132\2\0\7\132"+ + "\1\0\1\132\1\0\4\132\2\0\17\132\1\0\71\132\1\0\4\132"+ + "\2\0\103\132\2\0\3\133\40\0\20\132\20\0\125\132\14\0\u026c\132"+ + "\2\0\21\132\1\0\32\132\5\0\113\132\3\0\3\132\17\0\15\132"+ + "\1\0\4\132\3\133\13\0\22\132\3\133\13\0\22\132\2\133\14\0"+ + "\15\132\1\0\3\132\1\0\2\133\14\0\64\142\2\143\36\143\3\0"+ + "\1\142\4\0\1\142\1\143\2\0\12\134\41\0\3\133\2\0\12\134"+ + "\6\0\130\132\10\0\51\132\1\133\1\132\5\0\106\132\12\0\35\132"+ + "\3\0\14\133\4\0\14\133\12\0\12\134\36\142\2\0\5\142\13\0"+ + "\54\142\4\0\21\143\7\142\2\143\6\0\12\134\1\142\3\0\2\142"+ + "\40\0\27\132\5\133\4\0\65\142\12\143\1\0\35\143\2\0\1\133"+ + "\12\134\6\0\12\134\6\0\16\142\122\0\5\133\57\132\21\133\7\132"+ + "\4\0\12\134\21\0\11\133\14\0\3\133\36\132\12\133\3\0\2\132"+ + "\12\134\6\0\46\132\16\133\14\0\44\132\24\133\10\0\12\134\3\0"+ + "\3\132\12\134\44\132\122\0\3\133\1\0\25\133\4\132\1\133\4\132"+ + "\1\133\15\0\300\132\47\133\25\0\4\133\u0116\132\2\0\6\132\2\0"+ + "\46\132\2\0\6\132\2\0\10\132\1\0\1\132\1\0\1\132\1\0"+ + "\1\132\1\0\37\132\2\0\65\132\1\0\7\132\1\0\1\132\3\0"+ + "\3\132\1\0\7\132\3\0\4\132\2\0\6\132\4\0\15\132\5\0"+ + "\3\132\1\0\7\132\17\0\2\133\2\133\10\0\2\140\12\0\1\140"+ + "\2\0\1\136\2\0\5\133\20\0\2\141\3\0\1\137\17\0\1\141"+ + "\13\0\5\133\5\0\6\133\1\0\1\132\15\0\1\132\20\0\15\132"+ + "\63\0\41\133\21\0\1\132\4\0\1\132\2\0\12\132\1\0\1\132"+ + "\3\0\5\132\6\0\1\132\1\0\1\132\1\0\1\132\1\0\4\132"+ + "\1\0\13\132\2\0\4\132\5\0\5\132\4\0\1\132\21\0\51\132"+ + "\u032d\0\64\132\u0716\0\57\132\1\0\57\132\1\0\205\132\6\0\4\132"+ + "\3\133\16\0\46\132\12\0\66\132\11\0\1\132\17\0\1\133\27\132"+ + "\11\0\7\132\1\0\7\132\1\0\7\132\1\0\7\132\1\0\7\132"+ + "\1\0\7\132\1\0\7\132\1\0\7\132\1\0\40\133\57\0\1\132"+ + "\120\0\32\144\1\0\131\144\14\0\326\144\57\0\1\132\1\0\1\144"+ + "\31\0\11\144\6\133\1\0\5\135\2\0\3\144\1\132\1\132\4\0"+ + "\126\145\2\0\2\133\2\135\3\145\133\135\1\0\4\135\5\0\51\132"+ + "\3\0\136\132\21\0\33\132\65\0\20\135\320\0\57\135\1\0\130\135"+ + "\250\0\u19b6\144\112\0\u51cc\144\64\0\u048d\132\103\0\56\132\2\0\u010d\132"+ + "\3\0\20\132\12\134\2\132\24\0\57\132\4\133\11\0\2\133\1\0"+ + "\31\132\10\0\120\132\2\133\45\0\11\132\2\0\147\132\2\0\4\132"+ + "\1\0\2\132\16\0\12\132\120\0\10\132\1\133\3\132\1\133\4\132"+ + "\1\133\27\132\5\133\30\0\64\132\14\0\2\133\62\132\21\133\13\0"+ + "\12\134\6\0\22\133\6\132\3\0\1\132\4\0\12\134\34\132\10\133"+ + "\2\0\27\132\15\133\14\0\35\132\3\0\4\133\57\132\16\133\16\0"+ + "\1\132\12\134\46\0\51\132\16\133\11\0\3\132\1\133\10\132\2\133"+ + "\2\0\12\134\6\0\33\142\1\143\4\0\60\142\1\143\1\142\3\143"+ + "\2\142\2\143\5\142\2\143\1\142\1\143\1\142\30\0\5\142\41\0"+ + "\6\132\2\0\6\132\2\0\6\132\11\0\7\132\1\0\7\132\221\0"+ + "\43\132\10\133\1\0\2\133\2\0\12\134\6\0\u2ba4\132\14\0\27\132"+ + "\4\0\61\132\4\0\1\31\1\25\1\46\1\43\1\13\3\0\1\7"+ + "\1\5\2\0\1\3\1\1\14\0\1\11\21\0\1\112\7\0\1\65"+ + "\1\17\6\0\1\130\3\0\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120\1\120"+ + "\1\120\1\120\1\120\1\120\1\120\1\121\1\120\1\120\1\120\1\125"+ + "\1\123\17\0\1\114\u02c1\0\1\70\277\0\1\113\1\71\1\2\3\124"+ + "\2\35\1\124\1\35\2\124\1\14\21\124\2\60\7\73\1\72\7\73"+ + "\7\52\1\15\1\52\1\75\2\45\1\44\1\75\1\45\1\44\10\75"+ + "\2\63\5\61\2\54\5\61\1\6\10\37\5\21\3\27\12\106\20\27"+ + "\3\42\32\30\1\26\2\24\2\110\1\111\2\110\2\111\2\110\1\111"+ + "\3\24\1\16\2\24\12\64\1\74\1\41\1\34\1\64\6\41\1\34"+ + "\66\41\5\115\6\103\1\51\4\103\2\51\10\103\1\51\7\100\1\12"+ + "\2\100\32\103\1\12\4\100\1\12\5\102\1\101\1\102\3\101\7\102"+ + "\1\101\23\102\5\67\3\102\6\67\2\67\6\66\10\66\2\100\7\66"+ + "\36\100\4\66\102\100\15\115\1\77\2\115\1\131\3\117\1\115\2\117"+ + "\5\115\4\117\4\116\1\115\3\116\1\115\5\116\26\56\4\23\1\105"+ + "\2\104\4\122\1\104\2\122\3\76\33\122\35\55\3\122\35\126\3\122"+ + "\6\126\2\33\31\126\1\33\17\126\6\122\4\22\1\10\37\22\1\10"+ + "\4\22\25\62\1\127\11\62\21\55\5\62\1\57\12\40\13\62\4\55"+ + "\1\50\6\55\12\122\17\55\1\47\3\53\15\20\11\36\1\32\24\36"+ + "\2\20\11\36\1\32\31\36\1\32\4\20\4\36\2\32\2\107\1\4"+ + "\5\107\52\4\u1900\0\u012e\144\2\0\76\144\2\0\152\144\46\0\7\132"+ + "\14\0\5\132\5\0\1\132\1\133\12\132\1\0\15\132\1\0\5\132"+ + "\1\0\1\132\1\0\2\132\1\0\2\132\1\0\154\132\41\0\u016b\132"+ + "\22\0\100\132\2\0\66\132\50\0\14\132\4\0\20\133\1\137\2\0"+ + "\1\136\1\137\13\0\7\133\14\0\2\141\30\0\3\141\1\137\1\0"+ + "\1\140\1\0\1\137\1\136\32\0\5\132\1\0\207\132\2\0\1\133"+ + "\7\0\1\140\4\0\1\137\1\0\1\140\1\0\12\134\1\136\1\137"+ + "\5\0\32\132\4\0\1\141\1\0\32\132\13\0\70\135\2\133\37\132"+ + "\3\0\6\132\2\0\6\132\2\0\6\132\2\0\3\132\34\0\3\133"+ + "\4\0"; /** * Translates characters to character classes @@ -211,25 +227,26 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\0\1\1\1\2\1\3\1\2\2\1\3\2\3\3"+ - "\3\1\1\4\1\5\1\6\1\2\1\0\1\2\1\0"+ - "\1\3\6\0\2\2\1\0\3\2\1\0\1\3\1\0"+ - "\2\3\1\2\1\3\11\0\32\2\3\0\4\2\32\0"+ - "\4\3\10\0\1\7\1\0\6\10\3\2\2\10\1\2"+ - "\4\10\1\2\2\10\2\0\1\2\1\0\1\2\6\10"+ - "\3\0\2\10\1\0\4\10\1\0\2\10\1\0\2\3"+ - "\10\0\1\10\32\0\1\10\1\0\3\10\6\2\1\0"+ - "\1\2\2\0\1\2\1\0\1\10\10\0\3\3\15\0"+ - "\3\10\6\7\3\0\2\7\1\0\4\7\1\0\2\7"+ - "\2\10\1\0\2\10\1\0\2\10\1\0\1\10\2\2"+ - "\7\0\2\3\20\0\1\7\10\0\1\10\3\0\1\2"+ - "\32\0\3\10\23\0\1\10\27\0\1\10\4\0\1\10"+ - "\6\0\1\10\4\0\2\10\36\0\1\10\51\0\1\10"+ - "\42\0\1\10\50\0\1\10\122\0\1\10\116\0\1\10"+ - "\107\0\1\10\74\0\1\10\51\0\1\10\333\0"; + "\1\0\23\1\1\2\1\3\1\2\1\1\1\4\1\5"+ + "\1\6\1\1\3\2\3\3\3\1\15\0\1\2\1\0"+ + "\1\2\10\0\1\3\21\0\2\2\1\0\3\2\1\0"+ + "\1\3\1\0\2\3\1\2\1\3\46\0\32\2\3\0"+ + "\4\2\32\0\4\3\17\0\1\7\1\0\6\10\3\2"+ + "\2\10\1\2\4\10\1\2\2\10\2\0\1\2\1\0"+ + "\1\2\6\10\3\0\2\10\1\0\4\10\1\0\2\10"+ + "\1\0\2\3\10\0\1\10\32\0\1\10\1\0\3\10"+ + "\6\2\1\0\1\2\2\0\1\2\1\0\1\10\10\0"+ + "\3\3\15\0\3\10\6\7\3\0\2\7\1\0\4\7"+ + "\1\0\2\7\2\10\1\0\2\10\1\0\2\10\1\0"+ + "\1\10\2\2\7\0\2\3\20\0\1\7\10\0\1\10"+ + "\3\0\1\2\32\0\3\10\23\0\1\10\27\0\1\10"+ + "\4\0\1\10\6\0\1\10\4\0\2\10\36\0\1\10"+ + "\51\0\1\10\42\0\1\10\51\0\1\10\122\0\1\10"+ + "\117\0\1\10\107\0\1\10\74\0\1\10\51\0\1\10"+ + "\333\0"; private static int [] zzUnpackAction() { - int [] result = new int[1117]; + int [] result = new int[1204]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -254,149 +271,160 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\111\0\222\0\333\0\u0124\0\u016d\0\u01b6\0\u01ff"+ - "\0\u0248\0\u0291\0\u02da\0\u0323\0\u036c\0\u03b5\0\u03fe\0\u0447"+ - "\0\u0490\0\111\0\111\0\u04d9\0\u0522\0\u056b\0\u05b4\0\u05fd"+ - "\0\u016d\0\u0646\0\u01b6\0\u068f\0\u06d8\0\u0721\0\u076a\0\u07b3"+ - "\0\u07fc\0\u0845\0\u088e\0\u08d7\0\u0920\0\u0969\0\u09b2\0\u09fb"+ - "\0\u0a44\0\u0a8d\0\u0ad6\0\u03b5\0\u0b1f\0\u0b68\0\u0447\0\u0bb1"+ - "\0\u0bfa\0\u0c43\0\u0c8c\0\u0cd5\0\u0d1e\0\u0d67\0\u0db0\0\u0df9"+ - "\0\u0e42\0\u0e8b\0\u0ed4\0\u0f1d\0\u0f66\0\u0faf\0\u0ff8\0\u1041"+ - "\0\u108a\0\u10d3\0\u111c\0\u1165\0\u11ae\0\u11f7\0\u1240\0\u1289"+ - "\0\u12d2\0\u131b\0\u1364\0\u13ad\0\u13f6\0\u143f\0\u1488\0\u14d1"+ - "\0\u151a\0\u1563\0\u15ac\0\u15f5\0\u163e\0\u1687\0\u16d0\0\u1719"+ - "\0\u1762\0\u17ab\0\u17f4\0\u183d\0\u1886\0\u18cf\0\u1918\0\u1961"+ - "\0\u19aa\0\u19f3\0\u1a3c\0\u1a85\0\u1ace\0\u1b17\0\u1b60\0\u1ba9"+ - "\0\u1bf2\0\u1c3b\0\u1c84\0\u1ccd\0\u1d16\0\u1d5f\0\u1da8\0\u1df1"+ - "\0\u1e3a\0\u1e83\0\u1ecc\0\u1f15\0\u1f5e\0\u1fa7\0\u1ff0\0\u2039"+ - "\0\u2082\0\u20cb\0\u2114\0\111\0\u215d\0\u21a6\0\u21ef\0\u2238"+ - "\0\u2281\0\u22ca\0\u2313\0\u235c\0\u23a5\0\u23ee\0\u2437\0\u2480"+ - "\0\u24c9\0\u2512\0\u255b\0\u25a4\0\u25ed\0\u2636\0\u267f\0\u26c8"+ - "\0\u2711\0\u275a\0\u27a3\0\u27ec\0\u2835\0\u287e\0\u28c7\0\u2910"+ - "\0\u2959\0\u29a2\0\u29eb\0\u2a34\0\u2a7d\0\u2ac6\0\u2b0f\0\u2b58"+ - "\0\u2ba1\0\u2bea\0\u2c33\0\u2c7c\0\u2cc5\0\u2d0e\0\u2d57\0\u2da0"+ - "\0\u2de9\0\u2e32\0\u2e7b\0\u2ec4\0\u2f0d\0\u2f56\0\u2f9f\0\u2fe8"+ - "\0\u3031\0\u307a\0\u30c3\0\u310c\0\u3155\0\u319e\0\u31e7\0\u3230"+ - "\0\u3279\0\u32c2\0\u330b\0\u3354\0\u339d\0\u33e6\0\u342f\0\u3478"+ - "\0\u34c1\0\u350a\0\u3553\0\u359c\0\u35e5\0\u362e\0\u3677\0\u36c0"+ - "\0\u3709\0\u3752\0\u379b\0\u37e4\0\u382d\0\u3876\0\u38bf\0\u3908"+ - "\0\u3951\0\u399a\0\u39e3\0\u3a2c\0\u3a75\0\u3abe\0\u3b07\0\u3b50"+ - "\0\u3b99\0\u3be2\0\u3c2b\0\u3c74\0\u3cbd\0\u3d06\0\u3d4f\0\u3d98"+ - "\0\u3de1\0\u3e2a\0\u3e73\0\u3ebc\0\u3f05\0\u3f4e\0\u3f97\0\u3fe0"+ - "\0\u4029\0\u4072\0\u40bb\0\u4104\0\u414d\0\u4196\0\u41df\0\u4228"+ - "\0\u4271\0\u42ba\0\u4303\0\u434c\0\u4395\0\u43de\0\u4427\0\u4470"+ - "\0\u44b9\0\u4502\0\u454b\0\u4594\0\u45dd\0\u4626\0\u466f\0\u46b8"+ - "\0\u4701\0\u474a\0\u4793\0\u47dc\0\u4825\0\u486e\0\u48b7\0\u4900"+ - "\0\u4949\0\u4992\0\u49db\0\u4a24\0\u4a6d\0\u4ab6\0\u4aff\0\u4b48"+ - "\0\u4b91\0\u4bda\0\u4c23\0\u4c6c\0\u4cb5\0\u4cfe\0\u4d47\0\u4d90"+ - "\0\u4dd9\0\u4e22\0\u4e6b\0\u4eb4\0\u4efd\0\u4f46\0\u4f8f\0\u4fd8"+ - "\0\u5021\0\u506a\0\u50b3\0\u50fc\0\u5145\0\u518e\0\u51d7\0\u5220"+ - "\0\u5269\0\u52b2\0\u52fb\0\u5344\0\u538d\0\u53d6\0\u541f\0\u5468"+ - "\0\u54b1\0\u54fa\0\u5543\0\u20cb\0\u558c\0\u55d5\0\u561e\0\u5667"+ - "\0\u56b0\0\u56f9\0\u5742\0\u578b\0\u57d4\0\u581d\0\u5866\0\u58af"+ - "\0\u58f8\0\u5941\0\u598a\0\u59d3\0\u5a1c\0\u5a65\0\u5aae\0\u5af7"+ - "\0\u5b40\0\u5b89\0\u5bd2\0\u5c1b\0\u5c64\0\u5cad\0\u5cf6\0\u5d3f"+ - "\0\u5d88\0\u5dd1\0\u5e1a\0\u5e63\0\u5eac\0\u5ef5\0\u5f3e\0\u5f87"+ - "\0\u5fd0\0\u6019\0\u6062\0\u60ab\0\u60f4\0\u613d\0\u6186\0\u61cf"+ - "\0\u6218\0\u6261\0\u62aa\0\u62f3\0\u633c\0\u6385\0\u63ce\0\u6417"+ - "\0\u6460\0\u64a9\0\u64f2\0\u653b\0\u6584\0\u65cd\0\u6616\0\u665f"+ - "\0\u66a8\0\u66f1\0\u673a\0\u6783\0\u67cc\0\u6815\0\u685e\0\u68a7"+ - "\0\u68f0\0\u6939\0\u6982\0\u69cb\0\u6a14\0\u6a5d\0\u6aa6\0\u6aef"+ - "\0\u6b38\0\u6b81\0\u6bca\0\u6c13\0\u6c5c\0\u6ca5\0\u6cee\0\u6d37"+ - "\0\u6d80\0\u6dc9\0\u6e12\0\u6e5b\0\u6ea4\0\u6eed\0\u6f36\0\u6f7f"+ - "\0\u6fc8\0\u7011\0\u705a\0\u70a3\0\u70ec\0\u7135\0\u717e\0\u71c7"+ - "\0\u7210\0\u03fe\0\u7259\0\u72a2\0\u72eb\0\u7334\0\u737d\0\u73c6"+ - "\0\u740f\0\u7458\0\u74a1\0\u74ea\0\u7533\0\u757c\0\u75c5\0\u760e"+ - "\0\u7657\0\u76a0\0\u76e9\0\u7732\0\u777b\0\u77c4\0\u780d\0\u7856"+ - "\0\u789f\0\u78e8\0\u7931\0\u797a\0\u79c3\0\u7a0c\0\u7a55\0\u7a9e"+ - "\0\u7ae7\0\u7b30\0\u7b79\0\u7bc2\0\u7c0b\0\u7c54\0\u7c9d\0\u7ce6"+ - "\0\u7d2f\0\u7d78\0\u7dc1\0\u7e0a\0\u7e53\0\u7e9c\0\u7ee5\0\u7f2e"+ - "\0\u7f77\0\u7fc0\0\u8009\0\u8052\0\u809b\0\u80e4\0\u812d\0\u8176"+ - "\0\u81bf\0\u8208\0\u8251\0\u829a\0\u82e3\0\u832c\0\u8375\0\u83be"+ - "\0\u8407\0\u8450\0\u8499\0\u84e2\0\u852b\0\u8574\0\u85bd\0\u8606"+ - "\0\u864f\0\u8698\0\u86e1\0\u872a\0\u8773\0\u87bc\0\u8805\0\u884e"+ - "\0\u8897\0\u88e0\0\u8929\0\u8972\0\u89bb\0\u8a04\0\u8a4d\0\u8a96"+ - "\0\u8adf\0\u8b28\0\u8b71\0\u8bba\0\u8c03\0\u8c4c\0\u8c95\0\u8cde"+ - "\0\u8d27\0\u8d70\0\u8db9\0\u8e02\0\u8e4b\0\u8e94\0\u8edd\0\u8f26"+ - "\0\u8f6f\0\u8fb8\0\u9001\0\u904a\0\u9093\0\u90dc\0\u9125\0\u916e"+ - "\0\u91b7\0\u9200\0\u9249\0\u9292\0\u92db\0\u9324\0\u936d\0\u93b6"+ - "\0\u93ff\0\u9448\0\u9491\0\u94da\0\u9523\0\u956c\0\u95b5\0\u95fe"+ - "\0\u9647\0\u9690\0\u96d9\0\u9722\0\u976b\0\u97b4\0\u97fd\0\u9846"+ - "\0\u988f\0\u98d8\0\u9921\0\u996a\0\u99b3\0\u99fc\0\u9a45\0\u9a8e"+ - "\0\u9ad7\0\u9b20\0\u9b69\0\u9bb2\0\u9bfb\0\u9c44\0\u9c8d\0\u9cd6"+ - "\0\u9d1f\0\u9d68\0\u9db1\0\u9dfa\0\u9e43\0\u9e8c\0\u9ed5\0\u9f1e"+ - "\0\u9f67\0\u9fb0\0\u9ff9\0\ua042\0\ua08b\0\ua0d4\0\ua11d\0\ua166"+ - "\0\ua1af\0\ua1f8\0\ua241\0\ua28a\0\ua2d3\0\ua31c\0\ua365\0\ua3ae"+ - "\0\ua3f7\0\ua440\0\ua489\0\ua4d2\0\ua51b\0\ua564\0\ua5ad\0\ua5f6"+ - "\0\ua63f\0\ua688\0\ua6d1\0\ua71a\0\ua763\0\ua7ac\0\ua7f5\0\ua83e"+ - "\0\ua887\0\ua8d0\0\ua919\0\ua962\0\ua9ab\0\ua9f4\0\uaa3d\0\uaa86"+ - "\0\uaacf\0\uab18\0\uab61\0\uabaa\0\uabf3\0\uac3c\0\uac85\0\uacce"+ - "\0\uad17\0\uad60\0\uada9\0\uadf2\0\uae3b\0\uae84\0\uaecd\0\uaf16"+ - "\0\uaf5f\0\uafa8\0\uaff1\0\ub03a\0\ub083\0\ub0cc\0\ub115\0\ub15e"+ - "\0\ub1a7\0\ub1f0\0\ub239\0\ub282\0\ub2cb\0\ub314\0\ub35d\0\ub3a6"+ - "\0\ub3ef\0\ub438\0\ub481\0\ub4ca\0\ub513\0\ub55c\0\ub5a5\0\ub5ee"+ - "\0\ub637\0\ub680\0\ub6c9\0\ub712\0\ub75b\0\ub7a4\0\ub7ed\0\ub836"+ - "\0\ub87f\0\ub8c8\0\ub911\0\ub95a\0\ub9a3\0\ub9ec\0\uba35\0\uba7e"+ - "\0\ubac7\0\ubb10\0\ubb59\0\ubba2\0\ubbeb\0\ubc34\0\ubc7d\0\ubcc6"+ - "\0\ubd0f\0\ubd58\0\ubda1\0\ubdea\0\ube33\0\ube7c\0\ubec5\0\ubf0e"+ - "\0\ubf57\0\ubfa0\0\ubfe9\0\uc032\0\uc07b\0\uc0c4\0\uc10d\0\uc156"+ - "\0\uc19f\0\uc1e8\0\uc231\0\uc27a\0\uc2c3\0\uc30c\0\uc355\0\uc39e"+ - "\0\uc3e7\0\uc430\0\uc479\0\uc4c2\0\uc50b\0\uc554\0\uc59d\0\uc5e6"+ - "\0\uc62f\0\uc678\0\uc6c1\0\uc70a\0\uc753\0\uc79c\0\uc7e5\0\uc82e"+ - "\0\uc877\0\uc8c0\0\uc909\0\uc952\0\uc99b\0\uc9e4\0\uca2d\0\uca76"+ - "\0\ucabf\0\ucb08\0\ucb51\0\ucb9a\0\ucbe3\0\ucc2c\0\ucc75\0\uccbe"+ - "\0\ucd07\0\ucd50\0\ucd99\0\ucde2\0\uce2b\0\uce74\0\ucebd\0\ucf06"+ - "\0\ucf4f\0\ucf98\0\ucfe1\0\ud02a\0\ud073\0\ud0bc\0\ud105\0\ud14e"+ - "\0\ud197\0\ud1e0\0\ud229\0\ud272\0\ud2bb\0\ud304\0\ud34d\0\ud396"+ - "\0\ud3df\0\ud428\0\ud471\0\ud4ba\0\ud503\0\ud54c\0\ud595\0\ud5de"+ - "\0\ud627\0\ud670\0\ud6b9\0\ud702\0\ud74b\0\ud794\0\ud7dd\0\ud826"+ - "\0\ud86f\0\ud8b8\0\ud901\0\ud94a\0\ud993\0\ud9dc\0\uda25\0\uda6e"+ - "\0\udab7\0\udb00\0\udb49\0\udb92\0\udbdb\0\udc24\0\udc6d\0\udcb6"+ - "\0\udcff\0\udd48\0\udd91\0\uddda\0\ude23\0\ude6c\0\udeb5\0\udefe"+ - "\0\udf47\0\udf90\0\udfd9\0\ue022\0\ue06b\0\ue0b4\0\ue0fd\0\ue146"+ - "\0\ue18f\0\ue1d8\0\ue221\0\ue26a\0\ue2b3\0\ue2fc\0\ue345\0\ue38e"+ - "\0\ue3d7\0\ue420\0\ue469\0\ue4b2\0\ue4fb\0\ue544\0\ue58d\0\ue5d6"+ - "\0\ue61f\0\ue668\0\ue6b1\0\ue6fa\0\ue743\0\ue78c\0\ue7d5\0\ue81e"+ - "\0\ue867\0\ue8b0\0\ue8f9\0\ue942\0\ue98b\0\ue9d4\0\uea1d\0\uea66"+ - "\0\ueaaf\0\ueaf8\0\ueb41\0\ueb8a\0\uebd3\0\uec1c\0\uec65\0\uecae"+ - "\0\uecf7\0\ued40\0\ued89\0\uedd2\0\uee1b\0\uee64\0\ueead\0\ueef6"+ - "\0\uef3f\0\uef88\0\uefd1\0\uf01a\0\uf063\0\uf0ac\0\uf0f5\0\uf13e"+ - "\0\uf187\0\uf1d0\0\uf219\0\uf262\0\uf2ab\0\uf2f4\0\uf33d\0\uf386"+ - "\0\uf3cf\0\uf418\0\uf461\0\uf4aa\0\uf4f3\0\uf53c\0\uf585\0\uf5ce"+ - "\0\uf617\0\uf660\0\uf6a9\0\uf6f2\0\uf73b\0\uf784\0\uf7cd\0\uf816"+ - "\0\uf85f\0\uf8a8\0\uf8f1\0\uf93a\0\uf983\0\uf9cc\0\ufa15\0\ufa5e"+ - "\0\ufaa7\0\ufaf0\0\ufb39\0\ufb82\0\ufbcb\0\ufc14\0\ufc5d\0\ufca6"+ - "\0\ufcef\0\ufd38\0\ufd81\0\ufdca\0\ufe13\0\ufe5c\0\ufea5\0\ufeee"+ - "\0\uff37\0\uff80\0\uffc9\1\22\1\133\1\244\1\355\1\u0136"+ - "\1\u017f\1\u01c8\1\u0211\1\u025a\1\u02a3\1\u02ec\1\u0335\1\u037e"+ - "\1\u03c7\1\u0410\1\u0459\1\u04a2\1\u04eb\1\u0534\1\u057d\1\u05c6"+ - "\1\u060f\1\u0658\1\u06a1\1\u06ea\1\u0733\1\u077c\1\u07c5\1\u080e"+ - "\1\u0857\1\u08a0\1\u08e9\1\u0932\1\u097b\1\u09c4\1\u0a0d\1\u0a56"+ - "\1\u0a9f\1\u0ae8\1\u0b31\1\u0b7a\1\u0bc3\1\u0c0c\1\u0c55\1\u0c9e"+ - "\1\u0ce7\1\u0d30\1\u0d79\1\u0dc2\1\u0e0b\1\u0e54\1\u0e9d\1\u0ee6"+ - "\1\u0f2f\1\u0f78\1\u0fc1\1\u100a\1\u1053\1\u109c\1\u10e5\1\u112e"+ - "\1\u1177\1\u11c0\1\u1209\1\u1252\1\u129b\1\u12e4\1\u132d\1\u1376"+ - "\1\u13bf\1\u1408\1\u1451\1\u149a\1\u14e3\1\u152c\1\u1575\1\u15be"+ - "\1\u1607\1\u1650\1\u1699\1\u16e2\1\u172b\1\u1774\1\u17bd\1\u1806"+ - "\1\u184f\1\u1898\1\u18e1\1\u192a\1\u1973\1\u19bc\1\u1a05\1\u1a4e"+ - "\1\u1a97\1\u1ae0\1\u1b29\1\u1b72\1\u1bbb\1\u1c04\1\u1c4d\1\u1c96"+ - "\1\u1cdf\1\u1d28\1\u1d71\1\u1dba\1\u1e03\1\u1e4c\1\u1e95\1\u1ede"+ - "\1\u1f27\1\u1f70\1\u1fb9\1\u2002\1\u204b\1\u2094\1\u20dd\1\u2126"+ - "\1\u216f\1\u21b8\1\u2201\1\u224a\1\u2293\1\u22dc\1\u2325\1\u236e"+ - "\1\u23b7\1\u2400\1\u2449\1\u2492\1\u24db\1\u2524\1\u256d\1\u25b6"+ - "\1\u25ff\1\u2648\1\u2691\1\u26da\1\u2723\1\u276c\1\u27b5\1\u27fe"+ - "\1\u2847\1\u2890\1\u28d9\1\u2922\1\u296b\1\u29b4\1\u29fd\1\u2a46"+ - "\1\u2a8f\1\u2ad8\1\u2b21\1\u2b6a\1\u2bb3\1\u2bfc\1\u2c45\1\u2c8e"+ - "\1\u2cd7\1\u2d20\1\u2d69\1\u2db2\1\u2dfb\1\u2e44\1\u2e8d\1\u2ed6"+ - "\1\u2f1f\1\u2f68\1\u2fb1\1\u2ffa\1\u3043\1\u308c\1\u30d5\1\u311e"+ - "\1\u3167\1\u31b0\1\u31f9\1\u3242\1\u328b\1\u32d4\1\u331d\1\u3366"+ - "\1\u33af\1\u33f8\1\u3441\1\u348a\1\u34d3\1\u351c\1\u3565\1\u35ae"+ - "\1\u35f7\1\u3640\1\u3689\1\u36d2\1\u371b\1\u3764\1\u37ad\1\u37f6"+ - "\1\u383f\1\u3888\1\u38d1\1\u391a\1\u3963\1\u39ac\1\u39f5\1\u3a3e"+ - "\1\u3a87\1\u3ad0\1\u3b19\1\u3b62\1\u3bab"; + "\0\0\0\242\0\u0144\0\u01e6\0\u0288\0\u032a\0\u03cc\0\u046e"+ + "\0\u0510\0\u05b2\0\u0654\0\u06f6\0\u0798\0\u083a\0\u08dc\0\u097e"+ + "\0\u0a20\0\u0ac2\0\u0b64\0\u0c06\0\u0ca8\0\u0d4a\0\u0dec\0\u0e8e"+ + "\0\u0f30\0\242\0\242\0\u0fd2\0\u1074\0\u1116\0\u11b8\0\u125a"+ + "\0\u12fc\0\u139e\0\u1440\0\u14e2\0\u1584\0\u0144\0\u01e6\0\u0288"+ + "\0\u032a\0\u03cc\0\u1626\0\u16c8\0\u176a\0\u180c\0\u06f6\0\u18ae"+ + "\0\u1950\0\u19f2\0\u1a94\0\u1b36\0\u1bd8\0\u1c7a\0\u0510\0\u05b2"+ + "\0\u1d1c\0\u1dbe\0\u1e60\0\u1f02\0\u1fa4\0\u2046\0\u20e8\0\u218a"+ + "\0\u222c\0\u22ce\0\u2370\0\u2412\0\u24b4\0\u2556\0\u25f8\0\u269a"+ + "\0\u273c\0\u0e8e\0\u27de\0\u0fd2\0\u2880\0\u2922\0\u29c4\0\u2a66"+ + "\0\u2b08\0\u2baa\0\u2c4c\0\u2cee\0\u2d90\0\u2e32\0\u2ed4\0\u2f76"+ + "\0\u3018\0\u30ba\0\u315c\0\u31fe\0\u1440\0\u32a0\0\u3342\0\u1584"+ + "\0\u33e4\0\u3486\0\u3528\0\u35ca\0\u366c\0\u370e\0\u37b0\0\u3852"+ + "\0\u38f4\0\u3996\0\u3a38\0\u3ada\0\u3b7c\0\u3c1e\0\u3cc0\0\u3d62"+ + "\0\u3e04\0\u3ea6\0\u3f48\0\u3fea\0\u408c\0\u412e\0\u41d0\0\u4272"+ + "\0\u4314\0\u43b6\0\u4458\0\u44fa\0\u459c\0\u463e\0\u46e0\0\u4782"+ + "\0\u4824\0\u48c6\0\u4968\0\u4a0a\0\u4aac\0\u4b4e\0\u4bf0\0\u4c92"+ + "\0\u4d34\0\u4dd6\0\u4e78\0\u4f1a\0\u4fbc\0\u505e\0\u5100\0\u51a2"+ + "\0\u5244\0\u52e6\0\u5388\0\u542a\0\u54cc\0\u556e\0\u5610\0\u56b2"+ + "\0\u5754\0\u57f6\0\u5898\0\u593a\0\u59dc\0\u5a7e\0\u5b20\0\u5bc2"+ + "\0\u5c64\0\u5d06\0\u5da8\0\u5e4a\0\u5eec\0\u5f8e\0\u6030\0\u60d2"+ + "\0\u6174\0\u6216\0\u62b8\0\u635a\0\u63fc\0\u649e\0\u6540\0\u65e2"+ + "\0\u6684\0\u6726\0\u67c8\0\u686a\0\u690c\0\u69ae\0\u6a50\0\u6af2"+ + "\0\u6b94\0\u6c36\0\u6cd8\0\u6d7a\0\u6e1c\0\u6ebe\0\u6f60\0\u7002"+ + "\0\u70a4\0\u7146\0\u71e8\0\u728a\0\u732c\0\u73ce\0\u7470\0\u7512"+ + "\0\u75b4\0\u7656\0\u76f8\0\u779a\0\u783c\0\u78de\0\u7980\0\u7a22"+ + "\0\242\0\u7ac4\0\u7b66\0\u7c08\0\u7caa\0\u7d4c\0\u7dee\0\u7e90"+ + "\0\u7f32\0\u7fd4\0\u8076\0\u8118\0\u81ba\0\u825c\0\u82fe\0\u83a0"+ + "\0\u8442\0\u84e4\0\u8586\0\u8628\0\u86ca\0\u876c\0\u880e\0\u88b0"+ + "\0\u8952\0\u89f4\0\u8a96\0\u8b38\0\u8bda\0\u8c7c\0\u8d1e\0\u8dc0"+ + "\0\u8e62\0\u8f04\0\u8fa6\0\u9048\0\u90ea\0\u918c\0\u922e\0\u92d0"+ + "\0\u9372\0\u9414\0\u94b6\0\u9558\0\u95fa\0\u969c\0\u973e\0\u97e0"+ + "\0\u9882\0\u9924\0\u99c6\0\u9a68\0\u9b0a\0\u9bac\0\u9c4e\0\u9cf0"+ + "\0\u9d92\0\u9e34\0\u9ed6\0\u9f78\0\ua01a\0\ua0bc\0\ua15e\0\ua200"+ + "\0\ua2a2\0\ua344\0\ua3e6\0\ua488\0\ua52a\0\ua5cc\0\ua66e\0\ua710"+ + "\0\ua7b2\0\ua854\0\ua8f6\0\ua998\0\uaa3a\0\uaadc\0\uab7e\0\uac20"+ + "\0\uacc2\0\uad64\0\uae06\0\uaea8\0\uaf4a\0\uafec\0\ub08e\0\ub130"+ + "\0\ub1d2\0\ub274\0\ub316\0\ub3b8\0\ub45a\0\ub4fc\0\ub59e\0\ub640"+ + "\0\ub6e2\0\ub784\0\ub826\0\ub8c8\0\ub96a\0\uba0c\0\ubaae\0\ubb50"+ + "\0\ubbf2\0\ubc94\0\ubd36\0\ubdd8\0\ube7a\0\ubf1c\0\ubfbe\0\uc060"+ + "\0\uc102\0\uc1a4\0\uc246\0\uc2e8\0\uc38a\0\uc42c\0\uc4ce\0\uc570"+ + "\0\uc612\0\uc6b4\0\uc756\0\uc7f8\0\uc89a\0\uc93c\0\uc9de\0\uca80"+ + "\0\ucb22\0\ucbc4\0\ucc66\0\ucd08\0\ucdaa\0\uce4c\0\uceee\0\ucf90"+ + "\0\ud032\0\ud0d4\0\ud176\0\ud218\0\ud2ba\0\ud35c\0\ud3fe\0\ud4a0"+ + "\0\ud542\0\ud5e4\0\ud686\0\ud728\0\ud7ca\0\ud86c\0\ud90e\0\ud9b0"+ + "\0\uda52\0\udaf4\0\udb96\0\udc38\0\udcda\0\udd7c\0\ude1e\0\udec0"+ + "\0\udf62\0\ue004\0\ue0a6\0\ue148\0\ue1ea\0\ue28c\0\ue32e\0\ue3d0"+ + "\0\ue472\0\ue514\0\ue5b6\0\ue658\0\ue6fa\0\ue79c\0\ue83e\0\ue8e0"+ + "\0\ue982\0\uea24\0\ueac6\0\ueb68\0\uec0a\0\uecac\0\ued4e\0\uedf0"+ + "\0\u7980\0\uee92\0\uef34\0\uefd6\0\uf078\0\uf11a\0\uf1bc\0\uf25e"+ + "\0\uf300\0\uf3a2\0\uf444\0\uf4e6\0\uf588\0\uf62a\0\uf6cc\0\uf76e"+ + "\0\uf810\0\uf8b2\0\uf954\0\uf9f6\0\ufa98\0\ufb3a\0\ufbdc\0\ufc7e"+ + "\0\ufd20\0\ufdc2\0\ufe64\0\uff06\0\uffa8\1\112\1\354\1\u018e"+ + "\1\u0230\1\u02d2\1\u0374\1\u0416\1\u04b8\1\u055a\1\u05fc\1\u069e"+ + "\1\u0740\1\u07e2\1\u0884\1\u0926\1\u09c8\1\u0a6a\1\u0b0c\1\u0bae"+ + "\1\u0c50\1\u0cf2\1\u0d94\1\u0e36\1\u0ed8\1\u0f7a\1\u101c\1\u10be"+ + "\1\u1160\1\u1202\1\u12a4\1\u1346\1\u13e8\1\u148a\1\u152c\1\u15ce"+ + "\1\u1670\1\u1712\1\u17b4\1\u1856\1\u18f8\1\u199a\1\u1a3c\1\u1ade"+ + "\1\u1b80\1\u1c22\1\u1cc4\1\u1d66\1\u1e08\1\u1eaa\1\u1f4c\1\u1fee"+ + "\1\u2090\1\u2132\1\u21d4\1\u2276\1\u2318\1\u23ba\1\u245c\1\u24fe"+ + "\1\u25a0\1\u2642\1\u26e4\1\u2786\1\u2828\1\u28ca\1\u296c\1\u2a0e"+ + "\1\u2ab0\1\u2b52\1\u2bf4\1\u2c96\1\u2d38\1\u2dda\0\u14e2\1\u2e7c"+ + "\1\u2f1e\1\u2fc0\1\u3062\1\u3104\1\u31a6\1\u3248\1\u32ea\1\u338c"+ + "\1\u342e\1\u34d0\1\u3572\1\u3614\1\u36b6\1\u3758\1\u37fa\1\u389c"+ + "\1\u393e\1\u39e0\1\u3a82\1\u3b24\1\u3bc6\1\u3c68\1\u3d0a\1\u3dac"+ + "\1\u3e4e\1\u3ef0\1\u3f92\1\u4034\1\u40d6\1\u4178\1\u421a\1\u42bc"+ + "\1\u435e\1\u4400\1\u44a2\1\u4544\1\u45e6\1\u4688\1\u472a\1\u47cc"+ + "\1\u486e\1\u4910\1\u49b2\1\u4a54\1\u4af6\1\u4b98\1\u4c3a\1\u4cdc"+ + "\1\u4d7e\1\u4e20\1\u4ec2\1\u4f64\1\u5006\1\u50a8\1\u514a\1\u51ec"+ + "\1\u528e\1\u5330\1\u53d2\1\u5474\1\u5516\1\u55b8\1\u565a\1\u56fc"+ + "\1\u579e\1\u5840\1\u58e2\1\u5984\1\u5a26\1\u5ac8\1\u5b6a\1\u5c0c"+ + "\1\u5cae\1\u5d50\1\u5df2\1\u5e94\1\u5f36\1\u5fd8\1\u607a\1\u611c"+ + "\1\u61be\1\u6260\1\u6302\1\u63a4\1\u6446\1\u64e8\1\u658a\1\u662c"+ + "\1\u66ce\1\u6770\1\u6812\1\u68b4\1\u6956\1\u69f8\1\u6a9a\1\u6b3c"+ + "\1\u6bde\1\u6c80\1\u6d22\1\u6dc4\1\u6e66\1\u6f08\1\u6faa\1\u704c"+ + "\1\u70ee\1\u7190\1\u7232\1\u72d4\1\u7376\1\u7418\1\u74ba\1\u755c"+ + "\1\u75fe\1\u76a0\1\u7742\1\u77e4\1\u7886\1\u7928\1\u79ca\1\u7a6c"+ + "\1\u7b0e\1\u7bb0\1\u7c52\1\u7cf4\1\u7d96\1\u7e38\1\u7eda\1\u7f7c"+ + "\1\u801e\1\u80c0\1\u8162\1\u8204\1\u82a6\1\u8348\1\u83ea\1\u848c"+ + "\1\u852e\1\u85d0\1\u8672\1\u8714\1\u87b6\1\u8858\1\u88fa\1\u899c"+ + "\1\u8a3e\1\u8ae0\1\u8b82\1\u8c24\1\u8cc6\1\u8d68\1\u8e0a\1\u8eac"+ + "\1\u8f4e\1\u8ff0\1\u9092\1\u9134\1\u91d6\1\u9278\1\u931a\1\u93bc"+ + "\1\u945e\1\u9500\1\u95a2\1\u9644\1\u96e6\1\u9788\1\u982a\1\u98cc"+ + "\1\u996e\1\u9a10\1\u9ab2\1\u9b54\1\u9bf6\1\u9c98\1\u9d3a\1\u9ddc"+ + "\1\u9e7e\1\u9f20\1\u9fc2\1\ua064\1\ua106\1\ua1a8\1\ua24a\1\ua2ec"+ + "\1\ua38e\1\ua430\1\ua4d2\1\ua574\1\ua616\1\ua6b8\1\ua75a\1\ua7fc"+ + "\1\ua89e\1\ua940\1\ua9e2\1\uaa84\1\uab26\1\uabc8\1\uac6a\1\uad0c"+ + "\1\uadae\1\uae50\1\uaef2\1\uaf94\1\ub036\1\ub0d8\1\ub17a\1\ub21c"+ + "\1\ub2be\1\ub360\1\ub402\1\ub4a4\1\ub546\1\ub5e8\1\ub68a\1\ub72c"+ + "\1\ub7ce\1\ub870\1\ub912\1\ub9b4\1\uba56\1\ubaf8\1\ubb9a\1\ubc3c"+ + "\1\ubcde\1\ubd80\1\ube22\1\ubec4\1\ubf66\1\uc008\1\uc0aa\1\uc14c"+ + "\1\uc1ee\1\uc290\1\uc332\1\uc3d4\1\uc476\1\uc518\1\uc5ba\1\uc65c"+ + "\1\uc6fe\1\uc7a0\1\uc842\1\uc8e4\1\uc986\1\uca28\1\ucaca\1\ucb6c"+ + "\1\ucc0e\1\uccb0\1\ucd52\1\ucdf4\1\uce96\1\ucf38\1\ucfda\1\ud07c"+ + "\1\ud11e\1\ud1c0\1\ud262\1\ud304\1\ud3a6\1\ud448\1\ud4ea\1\ud58c"+ + "\1\ud62e\1\ud6d0\1\ud772\1\ud814\1\ud8b6\1\ud958\1\ud9fa\1\uda9c"+ + "\1\udb3e\1\udbe0\1\udc82\1\udd24\1\uddc6\1\ude68\1\udf0a\1\udfac"+ + "\1\ue04e\1\ue0f0\1\ue192\1\ue234\1\ue2d6\1\ue378\1\ue41a\1\ue4bc"+ + "\1\ue55e\1\ue600\1\ue6a2\1\ue744\1\ue7e6\1\ue888\1\ue92a\1\ue9cc"+ + "\1\uea6e\1\ueb10\1\uebb2\1\uec54\1\uecf6\1\ued98\1\uee3a\1\ueedc"+ + "\1\uef7e\1\uf020\1\uf0c2\1\uf164\1\uf206\1\uf2a8\1\uf34a\1\uf3ec"+ + "\1\uf48e\1\uf530\1\uf5d2\1\uf674\1\uf716\1\uf7b8\1\uf85a\1\uf8fc"+ + "\1\uf99e\1\ufa40\1\ufae2\1\ufb84\1\ufc26\1\ufcc8\1\ufd6a\1\ufe0c"+ + "\1\ufeae\1\uff50\1\ufff2\2\224\2\u0136\2\u01d8\2\u027a\2\u031c"+ + "\2\u03be\2\u0460\2\u0502\2\u05a4\2\u0646\2\u06e8\2\u078a\2\u082c"+ + "\2\u08ce\2\u0970\2\u0a12\2\u0ab4\2\u0b56\2\u0bf8\2\u0c9a\2\u0d3c"+ + "\2\u0dde\2\u0e80\2\u0f22\2\u0fc4\2\u1066\2\u1108\2\u11aa\2\u124c"+ + "\2\u12ee\2\u1390\2\u1432\2\u14d4\2\u1576\2\u1618\2\u16ba\2\u175c"+ + "\2\u17fe\2\u18a0\2\u1942\2\u19e4\2\u1a86\2\u1b28\2\u1bca\2\u1c6c"+ + "\2\u1d0e\2\u1db0\2\u1e52\2\u1ef4\2\u1f96\2\u2038\2\u20da\2\u217c"+ + "\2\u221e\2\u22c0\2\u2362\2\u2404\2\u24a6\2\u2548\2\u25ea\2\u268c"+ + "\2\u272e\2\u27d0\2\u2872\2\u2914\2\u29b6\2\u2a58\2\u2afa\2\u2b9c"+ + "\2\u2c3e\2\u2ce0\2\u2d82\2\u2e24\2\u2ec6\2\u2f68\2\u300a\2\u30ac"+ + "\2\u314e\2\u31f0\2\u3292\2\u3334\2\u33d6\2\u3478\2\u351a\2\u35bc"+ + "\2\u365e\2\u3700\2\u37a2\2\u3844\2\u38e6\2\u3988\2\u3a2a\2\u3acc"+ + "\2\u3b6e\2\u3c10\2\u3cb2\2\u3d54\2\u3df6\2\u3e98\2\u3f3a\2\u3fdc"+ + "\2\u407e\2\u4120\2\u41c2\2\u4264\2\u4306\2\u43a8\2\u444a\2\u44ec"+ + "\2\u458e\2\u4630\2\u46d2\2\u4774\2\u4816\2\u48b8\2\u495a\2\u49fc"+ + "\2\u4a9e\2\u4b40\2\u4be2\2\u4c84\2\u4d26\2\u4dc8\2\u4e6a\2\u4f0c"+ + "\2\u4fae\2\u5050\2\u50f2\2\u5194\2\u5236\2\u52d8\2\u537a\2\u541c"+ + "\2\u54be\2\u5560\2\u5602\2\u56a4\2\u5746\2\u57e8\2\u588a\2\u592c"+ + "\2\u59ce\2\u5a70\2\u5b12\2\u5bb4\2\u5c56\2\u5cf8\2\u5d9a\2\u5e3c"+ + "\2\u5ede\2\u5f80\2\u6022\2\u60c4\2\u6166\2\u6208\2\u62aa\2\u634c"+ + "\2\u63ee\2\u6490\2\u6532\2\u65d4\2\u6676\2\u6718\2\u67ba\2\u685c"+ + "\2\u68fe\2\u69a0\2\u6a42\2\u6ae4\2\u6b86\2\u6c28\2\u6cca\2\u6d6c"+ + "\2\u6e0e\2\u6eb0\2\u6f52\2\u6ff4\2\u7096\2\u7138\2\u71da\2\u727c"+ + "\2\u731e\2\u73c0\2\u7462\2\u7504\2\u75a6\2\u7648\2\u76ea\2\u778c"+ + "\2\u782e\2\u78d0\2\u7972\2\u7a14\2\u7ab6\2\u7b58\2\u7bfa\2\u7c9c"+ + "\2\u7d3e\2\u7de0\2\u7e82\2\u7f24\2\u7fc6\2\u8068\2\u810a\2\u81ac"+ + "\2\u824e\2\u82f0\2\u8392\2\u8434\2\u84d6\2\u8578\2\u861a\2\u86bc"+ + "\2\u875e\2\u8800\2\u88a2\2\u8944\2\u89e6\2\u8a88\2\u8b2a\2\u8bcc"+ + "\2\u8c6e\2\u8d10\2\u8db2\2\u8e54\2\u8ef6\2\u8f98\2\u903a\2\u90dc"+ + "\2\u917e\2\u9220\2\u92c2\2\u9364\2\u9406\2\u94a8\2\u954a\2\u95ec"+ + "\2\u968e\2\u9730\2\u97d2\2\u9874\2\u9916\2\u99b8\2\u9a5a\2\u9afc"+ + "\2\u9b9e\2\u9c40\2\u9ce2\2\u9d84\2\u9e26\2\u9ec8\2\u9f6a\2\ua00c"+ + "\2\ua0ae\2\ua150\2\ua1f2\2\ua294\2\ua336\2\ua3d8\2\ua47a\2\ua51c"+ + "\2\ua5be\2\ua660\2\ua702\2\ua7a4\2\ua846\2\ua8e8\2\ua98a\2\uaa2c"+ + "\2\uaace\2\uab70\2\uac12\2\uacb4\2\uad56\2\uadf8\2\uae9a\2\uaf3c"+ + "\2\uafde\2\ub080\2\ub122\2\ub1c4\2\ub266\2\ub308\2\ub3aa\2\ub44c"+ + "\2\ub4ee\2\ub590\2\ub632\2\ub6d4\2\ub776\2\ub818\2\ub8ba\2\ub95c"+ + "\2\ub9fe\2\ubaa0\2\ubb42\2\ubbe4\2\ubc86\2\ubd28\2\ubdca\2\ube6c"+ + "\2\ubf0e\2\ubfb0\2\uc052\2\uc0f4\2\uc196\2\uc238\2\uc2da\2\uc37c"+ + "\2\uc41e\2\uc4c0\2\uc562\2\uc604\2\uc6a6\2\uc748\2\uc7ea\2\uc88c"+ + "\2\uc92e\2\uc9d0\2\uca72\2\ucb14\2\ucbb6\2\ucc58\2\uccfa\2\ucd9c"+ + "\2\uce3e\2\ucee0\2\ucf82\2\ud024\2\ud0c6\2\ud168\2\ud20a\2\ud2ac"+ + "\2\ud34e\2\ud3f0\2\ud492\2\ud534\2\ud5d6\2\ud678\2\ud71a\2\ud7bc"+ + "\2\ud85e\2\ud900\2\ud9a2\2\uda44\2\udae6\2\udb88\2\udc2a\2\udccc"+ + "\2\udd6e\2\ude10\2\udeb2\2\udf54\2\udff6\2\ue098\2\ue13a\2\ue1dc"+ + "\2\ue27e\2\ue320\2\ue3c2\2\ue464\2\ue506\2\ue5a8\2\ue64a\2\ue6ec"+ + "\2\ue78e\2\ue830\2\ue8d2\2\ue974\2\uea16\2\ueab8\2\ueb5a\2\uebfc"+ + "\2\uec9e\2\ued40\2\uede2\2\uee84"; private static int [] zzUnpackRowMap() { - int [] result = new int[1117]; + int [] result = new int[1204]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -419,1848 +447,2475 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\1\2\1\3\1\2\1\4\1\5\3\2\1\6\1\7"+ - "\6\10\1\11\16\10\1\12\4\10\1\7\1\13\2\14"+ - "\1\13\4\14\1\15\1\14\1\2\1\7\1\16\1\7"+ - "\1\2\2\7\1\2\3\7\1\17\2\2\1\7\1\20"+ - "\3\2\2\7\1\2\2\21\1\22\1\23\112\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\25\32\3"+ - "\1\0\12\24\1\25\1\0\1\26\3\0\1\25\20\0"+ - "\1\3\3\0\1\3\2\4\2\0\2\27\1\30\1\27"+ - "\32\3\1\0\12\4\2\0\1\30\2\0\2\27\6\0"+ - "\1\27\11\0\1\4\4\0\1\5\1\0\1\5\3\0"+ - "\1\26\50\0\1\26\24\0\1\5\3\0\1\3\1\31"+ - "\1\4\1\5\3\0\1\31\1\0\32\3\1\0\12\4"+ - "\2\0\1\31\24\0\1\31\13\0\1\32\45\33\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\6\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\35\32\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\10\10\1\42\6\10"+ - "\1\43\12\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\17\10\1\44\12\10\1\36"+ - "\12\37\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\1\3\2\4\2\0\2\27\1\30\1\45\32\10"+ - "\1\36\12\14\1\0\1\33\1\46\1\33\1\0\2\47"+ - "\1\34\3\33\2\0\1\27\1\33\4\0\2\33\2\0"+ - "\1\4\3\0\1\3\2\4\2\0\2\27\1\30\1\45"+ - "\32\10\1\36\12\50\1\0\1\33\1\46\1\33\1\0"+ - "\2\47\1\34\3\33\2\0\1\27\1\33\4\0\2\33"+ - "\2\0\1\4\3\0\1\3\2\4\2\0\2\27\1\30"+ - "\1\45\32\10\1\36\1\14\1\51\1\50\2\14\2\50"+ - "\2\14\1\50\1\0\1\33\1\46\1\33\1\0\2\47"+ - "\1\34\3\33\2\0\1\27\1\33\4\0\2\33\2\0"+ - "\1\4\3\0\1\3\1\31\1\4\1\5\3\0\1\31"+ - "\1\32\32\52\1\33\12\53\1\0\1\33\1\54\1\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\31\14\0\4\55\2\0\1\55\15\0\1\55"+ - "\6\0\12\55\1\56\42\0\65\57\1\60\1\57\1\61"+ - "\1\0\2\57\112\0\2\21\3\0\1\3\2\24\2\0"+ - "\2\62\1\26\1\62\32\3\1\0\12\24\2\0\1\26"+ - "\2\0\2\62\6\0\1\62\11\0\1\24\3\0\1\3"+ - "\1\25\7\0\32\3\42\0\1\25\3\0\1\3\1\26"+ - "\1\24\1\5\3\0\1\26\1\0\32\3\1\0\12\24"+ - "\2\0\1\26\24\0\1\26\4\0\1\27\1\4\41\0"+ - "\12\4\27\0\1\27\3\0\1\3\1\30\1\4\1\5"+ - "\3\0\1\30\1\0\32\3\1\0\12\4\2\0\1\30"+ - "\24\0\1\30\13\0\1\32\45\33\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\1\57\3\0\2\33"+ - "\17\0\32\63\1\0\12\63\13\0\1\64\17\0\1\3"+ - "\1\25\6\0\1\32\1\65\1\66\1\67\1\70\1\71"+ - "\1\72\1\73\1\74\1\75\1\76\1\77\1\100\1\101"+ - "\1\102\1\103\1\104\1\105\1\106\1\107\1\110\1\111"+ - "\1\112\1\113\1\114\1\115\1\116\1\33\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\1\57"+ - "\3\0\2\33\2\0\1\25\13\0\1\32\32\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\6\0\1\3\2\24\2\0\2\62"+ - "\1\26\1\120\32\10\1\36\12\37\1\0\1\33\1\40"+ - "\1\33\1\0\2\121\1\34\3\33\2\0\1\62\1\33"+ - "\4\0\2\33\2\0\1\24\3\0\1\3\1\26\1\24"+ - "\1\5\3\0\1\26\1\32\32\52\1\33\12\122\1\0"+ - "\1\33\1\40\1\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\26\3\0\1\3\1\25"+ - "\6\0\1\32\32\52\13\33\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\25"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\11\10\1\123\20\10\1\36\12\37\1\25\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\3\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\35\15\10\1\124"+ - "\14\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\17\10\1\125\12\10\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\4\0"+ - "\1\27\1\4\5\0\1\32\1\126\1\127\1\130\1\131"+ - "\1\132\1\133\1\134\1\135\1\136\1\137\1\140\1\141"+ - "\1\142\1\143\1\144\1\145\1\146\1\147\1\150\1\151"+ - "\1\152\1\153\1\154\1\155\1\156\1\157\1\33\1\160"+ - "\2\161\1\160\4\161\1\162\1\161\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\1\57\3\0\2\33"+ - "\2\0\1\27\3\0\1\3\1\30\1\4\1\5\3\0"+ - "\1\30\1\32\32\52\1\33\12\53\1\0\1\33\1\46"+ - "\1\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\30\4\0\1\27\1\4\5\0\1\32"+ - "\33\33\12\53\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\27\3\0\1\3"+ - "\2\4\2\0\2\27\1\30\1\45\32\10\1\36\12\163"+ - "\1\0\1\33\1\46\1\33\1\0\2\47\1\34\3\33"+ - "\2\0\1\27\1\33\4\0\2\33\2\0\1\4\3\0"+ - "\1\3\2\4\2\0\2\27\1\30\1\45\32\10\1\36"+ - "\2\50\1\163\2\50\2\163\2\50\1\163\1\0\1\33"+ - "\1\46\1\33\1\0\2\47\1\34\3\33\2\0\1\27"+ - "\1\33\4\0\2\33\2\0\1\4\3\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\164\32\52\1\33"+ - "\12\122\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\1\3\2\4\2\0\2\27\1\30\1\165\32\52"+ - "\1\33\12\53\1\0\1\33\1\46\1\33\1\0\2\47"+ - "\1\34\3\33\2\0\1\27\1\33\4\0\2\33\2\0"+ - "\1\4\14\0\4\166\2\0\1\166\15\0\1\166\6\0"+ - "\12\166\1\167\110\0\1\170\42\0\1\171\54\0\1\34"+ - "\33\0\74\57\6\0\1\62\1\24\41\0\12\24\27\0"+ - "\1\62\13\0\1\172\32\63\1\173\12\63\43\0\61\64"+ - "\1\0\1\174\4\64\1\175\1\0\3\64\5\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\1\10"+ - "\2\176\1\177\1\200\10\176\1\10\1\201\5\176\6\10"+ - "\1\36\12\37\1\25\1\33\1\40\1\33\1\0\1\33"+ - "\1\41\1\34\3\33\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\35\1\202\2\176\1\10\1\176\1\203\6\176"+ - "\4\10\1\176\1\10\2\176\1\10\1\176\1\10\3\176"+ - "\1\36\12\37\1\25\1\33\1\40\1\33\1\0\1\33"+ - "\1\41\1\34\3\33\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\35\3\10\1\176\1\10\1\176\4\10\1\176"+ - "\10\10\1\176\2\10\1\176\2\10\1\176\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\1\10\1\176\1\204\2\176\2\10\1\176\6\10\3\176"+ - "\11\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\3\10\1\176\1\10\1\176\10\10"+ - "\1\176\1\10\2\176\10\10\1\36\12\37\1\25\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\3\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\35\4\10\1\205"+ - "\5\10\1\176\17\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\4\10\2\176\2\10"+ - "\1\176\1\10\1\176\13\10\1\176\2\10\1\176\1\36"+ - "\12\37\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\1\176\1\10\3\176\1\206\14\176\2\10\2\176"+ - "\2\10\1\176\1\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\2\10\4\176\3\10"+ - "\2\176\1\207\1\176\1\10\2\176\12\10\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\2\176\2\10\1\176\3\10\1\176\5\10\3\176\3\10"+ - "\1\176\2\10\3\176\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\5\176\1\210\1\10"+ - "\1\176\1\211\7\176\1\212\3\176\1\10\1\176\1\10"+ - "\3\176\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\1\213\1\176\1\10\1\202\6\176"+ - "\3\10\1\176\2\10\1\176\2\10\1\176\6\10\1\36"+ - "\12\37\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\1\176\31\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\1\176\2\10\1\176"+ - "\1\214\1\10\2\176\1\10\3\176\2\10\2\176\1\10"+ - "\1\176\3\10\1\176\2\10\2\176\1\36\12\37\1\25"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\6\176"+ - "\1\10\5\176\3\10\2\176\2\10\7\176\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\1\10\2\176\1\211\1\215\3\176\1\10\3\176\1\10"+ - "\1\176\1\10\1\176\1\10\1\176\1\10\1\176\1\10"+ - "\3\176\1\10\1\176\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\1\176\6\10\1\176"+ - "\6\10\1\176\4\10\1\176\4\10\2\176\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\6\10\1\176\7\10\1\176\13\10\1\36\12\37\1\25"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\13\10"+ - "\1\216\16\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\1\176\11\10\1\176\6\10"+ - "\1\176\10\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\1\176\1\10\6\176\1\217"+ - "\1\10\2\176\2\10\2\176\1\10\1\176\1\10\6\176"+ - "\1\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\4\10\1\176\5\10\2\176\3\10"+ - "\2\176\10\10\1\176\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\3\10\1\176\1\10"+ - "\1\220\4\10\1\176\2\10\1\176\14\10\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\2\176\1\10\1\176\3\10\2\176\2\10\1\176\4\10"+ - "\1\176\11\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\3\10\1\176\13\10\1\176"+ - "\12\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\3\10\2\176\2\10\2\176\1\10"+ - "\2\176\1\10\1\176\3\10\1\176\1\10\1\176\1\10"+ - "\1\176\2\10\1\176\1\10\1\36\12\37\1\25\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\13\0\1\221\32\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\7\0\1\62\1\24\5\0"+ - "\1\32\1\126\1\127\1\130\1\131\1\132\1\133\1\134"+ - "\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144"+ - "\1\145\1\146\1\147\1\150\1\151\1\152\1\153\1\154"+ - "\1\155\1\156\1\157\1\33\12\37\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\1\57\3\0\2\33"+ - "\2\0\1\62\4\0\1\62\1\24\5\0\1\32\33\33"+ - "\12\122\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\62\3\0\1\3\2\24"+ - "\2\0\2\62\1\26\1\222\32\52\1\33\12\122\1\0"+ - "\1\33\1\40\1\33\1\0\2\121\1\34\3\33\2\0"+ - "\1\62\1\33\4\0\2\33\2\0\1\24\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\3\10"+ - "\1\223\26\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\32\10\1\36\12\37\1\224"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\15\10"+ - "\1\225\14\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\13\0\1\221\1\117\2\226\1\227"+ - "\1\230\10\226\1\117\1\231\5\226\6\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\1\232\2\226\1\117\1\226"+ - "\1\233\6\226\4\117\1\226\1\117\2\226\1\117\1\226"+ - "\1\117\3\226\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\3\117\1\226\1\117\1\226\4\117\1\226\10\117\1\226"+ - "\2\117\1\226\2\117\1\226\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\1\117\1\226\1\234\2\226\2\117\1\226"+ - "\6\117\3\226\11\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\3\117\1\226\1\117\1\226\10\117\1\226\1\117"+ - "\2\226\10\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\4\117\1\235\5\117\1\226\17\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\4\117\2\226\2\117\1\226\1\117"+ - "\1\226\13\117\1\226\2\117\1\226\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\226\1\117\3\226\1\236\14\226"+ - "\2\117\2\226\2\117\1\226\1\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\2\117\4\226\3\117\2\226\1\237"+ - "\1\226\1\117\2\226\12\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\2\226\2\117\1\226\3\117\1\226\5\117"+ - "\3\226\3\117\1\226\2\117\3\226\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\5\226\1\240\1\117\1\226\1\241"+ - "\7\226\1\242\3\226\1\117\1\226\1\117\3\226\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\1\243\1\226\1\117"+ - "\1\232\6\226\3\117\1\226\2\117\1\226\2\117\1\226"+ - "\6\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\1\226"+ - "\31\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\1\226"+ - "\2\117\1\226\1\244\1\117\2\226\1\117\3\226\2\117"+ - "\2\226\1\117\1\226\3\117\1\226\2\117\2\226\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\6\226\1\117\5\226"+ - "\3\117\2\226\2\117\7\226\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\1\117\2\226\1\241\1\245\3\226\1\117"+ - "\3\226\1\117\1\226\1\117\1\226\1\117\1\226\1\117"+ - "\1\226\1\117\3\226\1\117\1\226\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\226\6\117\1\226\6\117\1\226"+ - "\4\117\1\226\4\117\2\226\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\6\117\1\226\7\117\1\226\13\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\13\117\1\246\16\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\226\11\117"+ - "\1\226\6\117\1\226\10\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\1\226\1\117\6\226\1\247\1\117\2\226"+ - "\2\117\2\226\1\117\1\226\1\117\6\226\1\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\4\117\1\226\5\117"+ - "\2\226\3\117\2\226\10\117\1\226\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\3\117\1\226\1\117\1\250\4\117"+ - "\1\226\2\117\1\226\14\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\2\226\1\117\1\226\3\117\2\226\2\117"+ - "\1\226\4\117\1\226\11\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\3\117\1\226\13\117\1\226\12\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\3\117\2\226\2\117"+ - "\2\226\1\117\2\226\1\117\1\226\3\117\1\226\1\117"+ - "\1\226\1\117\1\226\2\117\1\226\1\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\6\0\1\3\2\4\2\0\2\27\1\30"+ - "\1\251\32\10\1\36\12\161\1\0\1\33\1\46\1\33"+ - "\1\0\2\47\1\34\3\33\2\0\1\27\1\33\4\0"+ - "\2\33\2\0\1\4\3\0\1\3\2\4\2\0\2\27"+ - "\1\30\1\251\32\10\1\36\12\252\1\0\1\33\1\46"+ - "\1\33\1\0\2\47\1\34\3\33\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\3\0\1\3\2\4\2\0"+ - "\2\27\1\30\1\251\32\10\1\36\1\161\1\253\1\252"+ - "\2\161\2\252\2\161\1\252\1\0\1\33\1\46\1\33"+ - "\1\0\2\47\1\34\3\33\2\0\1\27\1\33\4\0"+ - "\2\33\2\0\1\4\3\0\1\3\2\4\2\0\2\27"+ - "\1\30\1\254\32\10\1\36\12\163\1\0\1\33\1\46"+ - "\1\33\1\0\2\47\1\34\3\33\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\3\0\1\3\1\25\6\0"+ - "\1\32\32\52\13\33\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\1\57\3\0\2\33\2\0\1\25"+ - "\4\0\1\27\1\4\5\0\1\32\33\33\12\53\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\1\57"+ - "\3\0\2\33\2\0\1\27\14\0\4\255\2\0\1\255"+ - "\15\0\1\255\6\0\12\255\1\167\43\0\4\256\2\0"+ - "\1\256\15\0\1\256\6\0\12\256\1\257\43\0\4\260"+ - "\2\0\1\260\15\0\1\260\6\0\1\261\2\262\1\261"+ - "\4\262\1\263\1\262\14\0\1\264\26\0\46\33\1\0"+ - "\3\33\1\0\2\33\1\0\3\33\3\0\1\33\1\57"+ - "\3\0\2\33\17\0\1\265\1\266\1\267\1\270\1\271"+ - "\1\272\1\273\1\274\1\275\1\276\1\277\1\300\1\301"+ - "\1\302\1\303\1\304\1\305\1\306\1\307\1\310\1\311"+ - "\1\312\1\313\1\314\1\315\1\316\1\0\12\63\44\0"+ - "\32\63\1\173\12\63\43\0\74\64\5\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\317\32\10\1\36"+ - "\12\37\1\320\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\1\321\1\322\1\323\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\317\4\10\1\324\25\10\1\36\12\37"+ - "\1\320\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\317\15\10\1\101\14\10\1\36\12\37\1\320"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\317\10\10\1\101\21\10\1\36\12\37\1\320\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\1\321\1\322"+ - "\1\323\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\317"+ - "\17\10\1\176\12\10\1\36\12\37\1\320\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\1\321\1\322\1\323"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\317\5\10"+ - "\1\325\4\10\1\176\17\10\1\36\12\37\1\320\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\1\321\1\322"+ - "\1\323\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\20\10\1\176\11\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\7\10\1\176\22\10"+ - "\1\36\12\37\1\25\1\33\1\40\1\33\1\0\1\33"+ - "\1\41\1\34\3\33\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\35\27\10\1\176\2\10\1\36\12\37\1\25"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\317\6\10"+ - "\1\324\10\10\1\176\12\10\1\36\12\37\1\320\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\1\321\1\322"+ - "\1\323\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\317"+ - "\24\10\1\326\5\10\1\36\12\37\1\320\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\1\321\1\322\1\323"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\11\10"+ - "\1\176\20\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\317\16\10\1\327\13\10\1\36"+ - "\12\37\1\320\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\1\321\1\322\1\323\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\317\12\10\1\330\17\10\1\36\12\37"+ - "\1\320\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\317\5\10\1\176\24\10\1\36\12\37\1\320"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\317\1\331\31\10\1\36\12\37\1\320\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\1\321\1\322\1\323"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\32\10"+ - "\1\332\12\37\1\25\1\33\1\40\1\33\1\0\1\33"+ - "\1\41\1\34\3\33\3\0\1\33\4\0\2\33\2\0"+ - "\1\3\3\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\317\23\10\1\176\6\10\1\36\12\37\1\320"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\317\24\10\1\333\5\10\1\36\12\37\1\320\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\1\321\1\322"+ - "\1\323\3\0\1\33\4\0\2\33\2\0\1\3\13\0"+ - "\1\32\1\126\1\127\1\130\1\131\1\132\1\133\1\134"+ - "\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144"+ - "\1\145\1\146\1\147\1\150\1\151\1\152\1\153\1\154"+ - "\1\155\1\156\1\157\1\33\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\1\57\3\0\2\33"+ - "\7\0\1\62\1\24\5\0\1\32\33\33\12\122\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\1\57"+ - "\3\0\2\33\2\0\1\62\3\0\2\3\1\24\1\0"+ - "\1\25\1\0\1\25\1\26\1\35\32\10\1\36\12\37"+ - "\1\334\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\1\3\1\25\7\0\32\3\24\0\1\335\15\0\1\25"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\16\10\1\336\13\10\1\36\12\37\1\337\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\13\0\1\340\32\117"+ - "\1\36\12\117\1\341\3\33\1\0\2\33\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\16\0\1\340"+ - "\4\117\1\342\25\117\1\36\12\117\1\341\3\33\1\0"+ - "\2\33\1\34\1\321\1\322\1\323\3\0\1\33\4\0"+ - "\2\33\16\0\1\340\15\117\1\142\14\117\1\36\12\117"+ - "\1\341\3\33\1\0\2\33\1\34\1\321\1\322\1\323"+ - "\3\0\1\33\4\0\2\33\16\0\1\340\10\117\1\142"+ - "\21\117\1\36\12\117\1\341\3\33\1\0\2\33\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\4\0\2\33\16\0"+ - "\1\340\17\117\1\226\12\117\1\36\12\117\1\341\3\33"+ - "\1\0\2\33\1\34\1\321\1\322\1\323\3\0\1\33"+ - "\4\0\2\33\16\0\1\340\5\117\1\343\4\117\1\226"+ - "\17\117\1\36\12\117\1\341\3\33\1\0\2\33\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\20\117\1\226\11\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\7\117\1\226\22\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\27\117\1\226\2\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\340\6\117\1\342\10\117\1\226"+ - "\12\117\1\36\12\117\1\341\3\33\1\0\2\33\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\4\0\2\33\16\0"+ - "\1\340\24\117\1\344\5\117\1\36\12\117\1\341\3\33"+ - "\1\0\2\33\1\34\1\321\1\322\1\323\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\11\117\1\226\20\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\340\16\117\1\345\13\117"+ - "\1\36\12\117\1\341\3\33\1\0\2\33\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\16\0\1\340"+ - "\12\117\1\346\17\117\1\36\12\117\1\341\3\33\1\0"+ - "\2\33\1\34\1\321\1\322\1\323\3\0\1\33\4\0"+ - "\2\33\16\0\1\340\5\117\1\226\24\117\1\36\12\117"+ - "\1\341\3\33\1\0\2\33\1\34\1\321\1\322\1\323"+ - "\3\0\1\33\4\0\2\33\16\0\1\340\1\347\31\117"+ - "\1\36\12\117\1\341\3\33\1\0\2\33\1\34\1\321"+ - "\1\322\1\323\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\332\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\340\23\117"+ - "\1\226\6\117\1\36\12\117\1\341\3\33\1\0\2\33"+ - "\1\34\1\321\1\322\1\323\3\0\1\33\4\0\2\33"+ - "\16\0\1\340\24\117\1\350\5\117\1\36\12\117\1\341"+ - "\3\33\1\0\2\33\1\34\1\321\1\322\1\323\3\0"+ - "\1\33\4\0\2\33\7\0\1\27\1\4\5\0\1\32"+ - "\1\126\1\127\1\130\1\131\1\132\1\133\1\134\1\135"+ - "\1\136\1\137\1\140\1\141\1\142\1\143\1\144\1\145"+ - "\1\146\1\147\1\150\1\151\1\152\1\153\1\154\1\155"+ - "\1\156\1\157\1\33\1\351\2\352\1\351\4\352\1\353"+ - "\1\352\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\1\57\3\0\2\33\2\0\1\27\3\0\1\3"+ - "\2\4\2\0\2\27\1\30\1\251\32\10\1\36\12\163"+ - "\1\0\1\33\1\46\1\33\1\0\2\47\1\34\3\33"+ - "\2\0\1\27\1\33\4\0\2\33\2\0\1\4\3\0"+ - "\1\3\2\4\2\0\2\27\1\30\1\251\32\10\1\36"+ - "\2\252\1\163\2\252\2\163\2\252\1\163\1\0\1\33"+ - "\1\46\1\33\1\0\2\47\1\34\3\33\2\0\1\27"+ - "\1\33\4\0\2\33\2\0\1\4\4\0\1\27\1\4"+ - "\5\0\1\32\1\126\1\127\1\130\1\131\1\132\1\133"+ - "\1\134\1\135\1\136\1\137\1\140\1\141\1\142\1\143"+ - "\1\144\1\145\1\146\1\147\1\150\1\151\1\152\1\153"+ - "\1\154\1\155\1\156\1\157\1\33\12\163\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\1\57\3\0"+ - "\2\33\2\0\1\27\14\0\4\354\2\0\1\354\15\0"+ - "\1\354\6\0\12\354\1\167\43\0\4\355\2\0\1\355"+ - "\15\0\1\355\6\0\12\355\1\356\43\0\4\357\2\0"+ - "\1\357\15\0\1\357\6\0\1\360\2\361\1\360\4\361"+ - "\1\362\1\361\14\0\1\264\27\0\4\363\2\0\1\363"+ - "\15\0\1\363\6\0\12\363\1\364\13\0\1\264\26\0"+ - "\1\365\4\363\2\0\1\363\15\0\1\363\6\0\12\366"+ - "\1\364\13\0\1\264\26\0\1\365\4\363\2\0\1\363"+ - "\15\0\1\363\6\0\12\367\1\364\13\0\1\264\26\0"+ - "\1\365\4\363\2\0\1\363\15\0\1\363\6\0\1\366"+ - "\1\370\1\367\2\366\2\367\2\366\1\367\1\364\13\0"+ - "\1\264\74\0\1\341\7\0\1\371\1\372\1\373\30\0"+ - "\1\172\1\63\2\374\1\375\1\376\10\374\1\63\1\377"+ - "\5\374\6\63\1\173\12\63\43\0\1\172\1\u0100\2\374"+ - "\1\63\1\374\1\u0101\6\374\4\63\1\374\1\63\2\374"+ - "\1\63\1\374\1\63\3\374\1\173\12\63\43\0\1\172"+ - "\3\63\1\374\1\63\1\374\4\63\1\374\10\63\1\374"+ - "\2\63\1\374\2\63\1\374\1\173\12\63\43\0\1\172"+ - "\1\63\1\374\1\u0102\2\374\2\63\1\374\6\63\3\374"+ - "\11\63\1\173\12\63\43\0\1\172\3\63\1\374\1\63"+ - "\1\374\10\63\1\374\1\63\2\374\10\63\1\173\12\63"+ - "\43\0\1\172\4\63\1\u0103\5\63\1\374\17\63\1\173"+ - "\12\63\43\0\1\172\4\63\2\374\2\63\1\374\1\63"+ - "\1\374\13\63\1\374\2\63\1\374\1\173\12\63\43\0"+ - "\1\172\1\374\1\63\3\374\1\u0104\14\374\2\63\2\374"+ - "\2\63\1\374\1\63\1\173\12\63\43\0\1\172\2\63"+ - "\4\374\3\63\2\374\1\u0105\1\374\1\63\2\374\12\63"+ - "\1\173\12\63\43\0\1\172\2\374\2\63\1\374\3\63"+ - "\1\374\5\63\3\374\3\63\1\374\2\63\3\374\1\173"+ - "\12\63\43\0\1\172\5\374\1\u0106\1\63\1\374\1\u0107"+ - "\7\374\1\u0108\3\374\1\63\1\374\1\63\3\374\1\173"+ - "\12\63\43\0\1\172\1\u0109\1\374\1\63\1\u0100\6\374"+ - "\3\63\1\374\2\63\1\374\2\63\1\374\6\63\1\173"+ - "\12\63\43\0\1\172\1\374\31\63\1\173\12\63\43\0"+ - "\1\172\1\374\2\63\1\374\1\u010a\1\63\2\374\1\63"+ - "\3\374\2\63\2\374\1\63\1\374\3\63\1\374\2\63"+ - "\2\374\1\173\12\63\43\0\1\172\6\374\1\63\5\374"+ - "\3\63\2\374\2\63\7\374\1\173\12\63\43\0\1\172"+ - "\1\63\2\374\1\u0107\1\u010b\3\374\1\63\3\374\1\63"+ - "\1\374\1\63\1\374\1\63\1\374\1\63\1\374\1\63"+ - "\3\374\1\63\1\374\1\173\12\63\43\0\1\172\1\374"+ - "\6\63\1\374\6\63\1\374\4\63\1\374\4\63\2\374"+ - "\1\173\12\63\43\0\1\172\6\63\1\374\7\63\1\374"+ - "\13\63\1\173\12\63\43\0\1\172\13\63\1\u010c\16\63"+ - "\1\173\12\63\43\0\1\172\1\374\11\63\1\374\6\63"+ - "\1\374\10\63\1\173\12\63\43\0\1\172\1\374\1\63"+ - "\6\374\1\u010d\1\63\2\374\2\63\2\374\1\63\1\374"+ - "\1\63\6\374\1\63\1\173\12\63\43\0\1\172\4\63"+ - "\1\374\5\63\2\374\3\63\2\374\10\63\1\374\1\173"+ - "\12\63\43\0\1\172\3\63\1\374\1\63\1\u010e\4\63"+ - "\1\374\2\63\1\374\14\63\1\173\12\63\43\0\1\172"+ - "\2\374\1\63\1\374\3\63\2\374\2\63\1\374\4\63"+ - "\1\374\11\63\1\173\12\63\43\0\1\172\3\63\1\374"+ - "\13\63\1\374\12\63\1\173\12\63\43\0\1\172\3\63"+ - "\2\374\2\63\2\374\1\63\2\374\1\63\1\374\3\63"+ - "\1\374\1\63\1\374\1\63\1\374\2\63\1\374\1\63"+ - "\1\173\12\63\33\0\1\3\1\25\6\0\1\32\1\65"+ - "\1\66\1\67\1\70\1\71\1\72\1\73\1\74\1\75"+ - "\1\76\1\77\1\100\1\101\1\102\1\103\1\104\1\105"+ - "\1\106\1\107\1\110\1\111\1\112\1\113\1\114\1\115"+ - "\1\116\1\33\12\117\1\341\3\33\1\0\2\33\1\34"+ - "\1\321\1\322\1\323\3\0\1\33\1\57\3\0\2\33"+ - "\2\0\1\25\3\0\1\3\1\25\7\0\32\3\1\0"+ - "\12\u010f\27\0\1\25\13\0\1\u0110\45\321\1\371\2\321"+ - "\1\u0111\1\371\2\321\1\u0112\2\321\1\323\2\0\1\371"+ - "\1\321\4\0\1\321\1\33\16\0\1\u0113\45\322\1\372"+ - "\2\322\1\u0114\1\0\2\33\1\u0115\1\321\1\322\1\323"+ - "\2\0\1\372\1\322\4\0\2\33\16\0\1\u0116\45\323"+ - "\1\373\2\323\1\u0117\1\373\2\323\1\u0118\2\323\1\33"+ - "\2\0\1\373\1\323\4\0\1\323\1\33\6\0\2\3"+ - "\1\24\1\0\1\25\1\0\1\25\1\26\1\35\5\10"+ - "\1\176\24\10\1\36\12\37\1\25\1\33\1\40\1\33"+ - "\1\0\1\33\1\41\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\2\0\1\3\3\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\15\10\1\176\14\10\1\36"+ - "\12\37\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\10\10\1\176\21\10\1\36\12\37\1\25\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\3\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\35\3\10\1\u0119"+ - "\26\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\3\0\2\3\1\24\1\0\1\25\1\0"+ - "\1\25\1\26\1\35\3\10\1\176\26\10\1\36\12\37"+ - "\1\25\1\33\1\40\1\33\1\0\1\33\1\41\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\2\0\1\3\3\0"+ - "\2\3\1\24\1\0\1\25\1\0\1\25\1\26\1\35"+ - "\27\10\1\u011a\2\10\1\36\12\37\1\25\1\33\1\40"+ - "\1\33\1\0\1\33\1\41\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\2\0\1\3\13\0\1\32\32\117\1\u011b"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\6\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\16\10\1\176\13\10\1\36"+ - "\12\37\1\25\1\33\1\40\1\33\1\0\1\33\1\41"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\2\0\1\3"+ - "\3\0\1\3\1\25\7\0\32\3\24\0\1\u011c\15\0"+ - "\1\25\72\0\1\u011d\21\0\2\3\1\24\1\0\1\25"+ - "\1\0\1\25\1\26\1\35\32\10\1\36\12\37\1\337"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\3\0\1\3"+ - "\1\25\7\0\32\3\24\0\1\u011e\15\0\1\25\13\0"+ - "\1\32\1\126\1\127\1\130\1\131\1\132\1\133\1\134"+ - "\1\135\1\136\1\137\1\140\1\141\1\142\1\143\1\144"+ - "\1\145\1\146\1\147\1\150\1\151\1\152\1\153\1\154"+ - "\1\155\1\156\1\157\1\33\12\117\1\341\3\33\1\0"+ - "\2\33\1\34\1\321\1\322\1\323\3\0\1\33\1\57"+ - "\3\0\2\33\52\0\12\u010f\43\0\1\221\5\117\1\226"+ - "\24\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\15\117"+ - "\1\226\14\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\10\117\1\226\21\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\3\117\1\u011f\26\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\3\117\1\226\26\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\27\117\1\u0120\2\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\16\117\1\226\13\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\6\0\1\3\2\4\2\0\2\27"+ - "\1\30\1\u0121\32\10\1\36\12\352\1\0\1\33\1\46"+ - "\1\33\1\0\2\47\1\34\3\33\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\3\0\1\3\2\4\2\0"+ - "\2\27\1\30\1\u0121\32\10\1\36\12\u0122\1\0\1\33"+ - "\1\46\1\33\1\0\2\47\1\34\3\33\2\0\1\27"+ - "\1\33\4\0\2\33\2\0\1\4\3\0\1\3\2\4"+ - "\2\0\2\27\1\30\1\u0121\32\10\1\36\1\352\1\u0123"+ - "\1\u0122\2\352\2\u0122\2\352\1\u0122\1\0\1\33\1\46"+ - "\1\33\1\0\2\47\1\34\3\33\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\61\0\1\167\43\0\4\u0124"+ - "\2\0\1\u0124\15\0\1\u0124\6\0\12\u0124\1\356\43\0"+ - "\4\u0125\2\0\1\u0125\15\0\1\u0125\6\0\12\u0125\1\u0126"+ - "\43\0\4\u0127\2\0\1\u0127\15\0\1\u0127\6\0\12\u0127"+ - "\1\u0128\13\0\1\264\26\0\1\365\4\u0127\2\0\1\u0127"+ - "\15\0\1\u0127\6\0\12\u0129\1\u0128\13\0\1\264\26\0"+ - "\1\365\4\u0127\2\0\1\u0127\15\0\1\u0127\6\0\12\u012a"+ - "\1\u0128\13\0\1\264\26\0\1\365\4\u0127\2\0\1\u0127"+ - "\15\0\1\u0127\6\0\1\u0129\1\u012b\1\u012a\2\u0129\2\u012a"+ - "\2\u0129\1\u012a\1\u0128\13\0\1\264\27\0\4\u012c\2\0"+ - "\1\u012c\15\0\1\u012c\6\0\12\u012c\1\364\13\0\1\264"+ - "\27\0\4\357\2\0\1\357\15\0\1\357\6\0\1\360"+ - "\2\361\1\360\4\361\1\362\1\361\77\0\1\u012d\2\u012e"+ - "\1\u012d\4\u012e\1\u012f\1\u012e\43\0\1\365\4\u012c\2\0"+ - "\1\u012c\15\0\1\u012c\6\0\12\u0130\1\364\13\0\1\264"+ - "\26\0\1\365\4\u012c\2\0\1\u012c\15\0\1\u012c\6\0"+ - "\12\u012c\1\364\13\0\1\264\26\0\1\365\4\u012c\2\0"+ - "\1\u012c\15\0\1\u012c\6\0\2\u0130\1\u012c\2\u0130\2\u012c"+ - "\2\u0130\1\u012c\1\364\13\0\1\264\26\0\51\371\1\u0131"+ - "\6\371\1\373\2\0\2\371\4\0\1\371\17\0\51\372"+ - "\1\u0132\3\0\1\372\1\371\1\372\1\373\2\0\2\372"+ - "\24\0\51\373\1\u0133\6\373\3\0\2\373\4\0\1\373"+ - "\17\0\1\u0134\32\63\1\173\12\63\43\0\1\u0134\4\63"+ - "\1\u0135\25\63\1\173\12\63\43\0\1\u0134\15\63\1\301"+ - "\14\63\1\173\12\63\43\0\1\u0134\10\63\1\301\21\63"+ - "\1\173\12\63\43\0\1\u0134\17\63\1\374\12\63\1\173"+ - "\12\63\43\0\1\u0134\5\63\1\u0136\4\63\1\374\17\63"+ - "\1\173\12\63\43\0\1\172\20\63\1\374\11\63\1\173"+ - "\12\63\43\0\1\172\7\63\1\374\22\63\1\173\12\63"+ - "\43\0\1\172\27\63\1\374\2\63\1\173\12\63\43\0"+ - "\1\u0134\6\63\1\u0135\10\63\1\374\12\63\1\173\12\63"+ - "\43\0\1\u0134\24\63\1\u0137\5\63\1\173\12\63\43\0"+ - "\1\172\11\63\1\374\20\63\1\173\12\63\43\0\1\u0134"+ - "\16\63\1\u0138\13\63\1\173\12\63\43\0\1\u0134\12\63"+ - "\1\u0139\17\63\1\173\12\63\43\0\1\u0134\5\63\1\374"+ - "\24\63\1\173\12\63\43\0\1\u0134\1\u013a\31\63\1\173"+ - "\12\63\43\0\1\172\32\63\1\u013b\12\63\43\0\1\u0134"+ - "\23\63\1\374\6\63\1\173\12\63\43\0\1\u0134\24\63"+ - "\1\u013c\5\63\1\173\12\63\77\0\12\u013d\10\0\1\371"+ - "\1\372\1\373\30\0\1\u0110\45\321\1\371\2\321\1\u0111"+ - "\1\371\2\321\1\u0112\2\321\1\323\2\0\1\371\1\321"+ - "\1\57\3\0\1\321\1\33\16\0\1\32\4\u013e\2\33"+ - "\1\u013e\15\33\1\u013e\6\33\12\u013e\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\51\371\1\u0131\6\371\1\373\1\64\1\0\2\371\4\0"+ - "\1\371\17\0\1\u0113\45\322\1\372\2\322\1\u0114\1\0"+ - "\2\33\1\u0115\1\321\1\322\1\323\2\0\1\372\1\322"+ - "\1\57\3\0\2\33\16\0\1\32\4\u013f\2\33\1\u013f"+ - "\15\33\1\u013f\6\33\12\u013f\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\51\372"+ - "\1\u0132\3\0\1\372\1\371\1\372\1\373\1\64\1\0"+ - "\2\372\24\0\1\u0116\45\323\1\373\2\323\1\u0117\1\373"+ - "\2\323\1\u0118\2\323\1\33\2\0\1\373\1\323\1\57"+ - "\3\0\1\323\1\33\16\0\1\32\4\u0140\2\33\1\u0140"+ - "\15\33\1\u0140\6\33\12\u0140\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\51\373"+ - "\1\u0133\6\373\1\0\1\64\1\0\2\373\4\0\1\373"+ - "\7\0\2\3\1\24\1\0\1\25\1\0\1\25\1\26"+ - "\1\35\20\10\1\u0141\11\10\1\36\12\37\1\25\1\33"+ - "\1\40\1\33\1\0\1\33\1\41\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\2\0\1\3\3\0\2\3\1\24"+ - "\1\0\1\25\1\0\1\25\1\26\1\35\3\10\1\211"+ - "\26\10\1\36\12\37\1\25\1\33\1\40\1\33\1\0"+ - "\1\33\1\41\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\2\0\1\3\13\0\1\32\2\117\1\u0142\2\117\1\u0143"+ - "\1\u0144\1\u0145\2\117\1\u0146\2\117\1\u0147\3\117\1\u0148"+ - "\1\u0149\1\u014a\1\117\1\u014b\1\u014c\1\117\1\u014d\1\u014e"+ - "\1\36\1\u014f\2\117\1\u0150\1\117\1\u0151\1\u0152\3\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\75\0\1\u0153\31\0\1\u0154\32\u0155\1\u0154"+ - "\12\u0155\1\u0156\2\u0154\1\u0157\3\u0154\1\u0158\3\0\1\u0159"+ - "\1\0\2\u0154\4\0\1\u0154\76\0\1\u015a\31\0\1\221"+ - "\20\117\1\u015b\11\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\3\117\1\241\26\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\7\0\1\27\1\4\5\0\1\32\1\126\1\127\1\130"+ - "\1\131\1\132\1\133\1\134\1\135\1\136\1\137\1\140"+ - "\1\141\1\142\1\143\1\144\1\145\1\146\1\147\1\150"+ - "\1\151\1\152\1\153\1\154\1\155\1\156\1\157\1\33"+ - "\1\u015c\2\u015d\1\u015c\4\u015d\1\u015e\1\u015d\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\1\57\3\0"+ - "\2\33\2\0\1\27\3\0\1\3\2\4\2\0\2\27"+ - "\1\30\1\u0121\32\10\1\36\12\163\1\0\1\33\1\46"+ - "\1\33\1\0\2\47\1\34\3\33\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\3\0\1\3\2\4\2\0"+ - "\2\27\1\30\1\u0121\32\10\1\36\2\u0122\1\163\2\u0122"+ - "\2\163\2\u0122\1\163\1\0\1\33\1\46\1\33\1\0"+ - "\2\47\1\34\3\33\2\0\1\27\1\33\4\0\2\33"+ - "\2\0\1\4\14\0\4\u015f\2\0\1\u015f\15\0\1\u015f"+ - "\6\0\12\u015f\1\356\43\0\4\u0160\2\0\1\u0160\15\0"+ - "\1\u0160\6\0\12\u0160\1\u0161\43\0\4\u0162\2\0\1\u0162"+ - "\15\0\1\u0162\6\0\1\u0163\2\u0164\1\u0163\4\u0164\1\u0165"+ - "\1\u0164\14\0\1\264\27\0\4\u0166\2\0\1\u0166\15\0"+ - "\1\u0166\6\0\12\u0166\1\u0128\13\0\1\264\27\0\4\u0162"+ - "\2\0\1\u0162\15\0\1\u0162\6\0\1\u0163\2\u0164\1\u0163"+ - "\4\u0164\1\u0165\1\u0164\43\0\1\365\4\u0166\2\0\1\u0166"+ - "\15\0\1\u0166\6\0\12\u0167\1\u0128\13\0\1\264\26\0"+ - "\1\365\4\u0166\2\0\1\u0166\15\0\1\u0166\6\0\12\u0166"+ - "\1\u0128\13\0\1\264\26\0\1\365\4\u0166\2\0\1\u0166"+ - "\15\0\1\u0166\6\0\2\u0167\1\u0166\2\u0167\2\u0166\2\u0167"+ - "\1\u0166\1\u0128\13\0\1\264\27\0\4\u0168\2\0\1\u0168"+ - "\15\0\1\u0168\6\0\12\u0168\1\364\13\0\1\264\26\0"+ - "\1\u0169\33\0\12\u012e\43\0\1\u0169\33\0\12\u016a\43\0"+ - "\1\u0169\33\0\1\u012e\1\u016b\1\u016a\2\u012e\2\u016a\2\u012e"+ - "\1\u016a\43\0\1\365\4\u0168\2\0\1\u0168\15\0\1\u0168"+ - "\6\0\12\u0168\1\364\13\0\1\264\27\0\4\u016c\2\0"+ - "\1\u016c\15\0\1\u016c\6\0\12\u016c\44\0\4\u016d\2\0"+ - "\1\u016d\15\0\1\u016d\6\0\12\u016d\44\0\4\u016e\2\0"+ - "\1\u016e\15\0\1\u016e\6\0\12\u016e\43\0\1\172\5\63"+ - "\1\374\24\63\1\173\12\63\43\0\1\172\15\63\1\374"+ - "\14\63\1\173\12\63\43\0\1\172\10\63\1\374\21\63"+ - "\1\173\12\63\43\0\1\172\3\63\1\u016f\26\63\1\173"+ - "\12\63\43\0\1\172\3\63\1\374\26\63\1\173\12\63"+ - "\43\0\1\172\27\63\1\u0170\2\63\1\173\12\63\44\0"+ - "\32\63\1\u0171\12\63\43\0\1\172\16\63\1\374\13\63"+ - "\1\173\12\63\77\0\12\u0172\10\0\1\371\1\372\1\373"+ - "\30\0\1\32\4\321\2\33\1\321\15\33\1\321\6\33"+ - "\12\321\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\32\4\322\2\33\1\322"+ - "\15\33\1\322\6\33\12\322\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\32"+ - "\4\323\2\33\1\323\15\33\1\323\6\33\12\323\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\6\0\2\3\1\24\1\0\1\25\1\0\1\25"+ - "\1\26\1\35\12\10\1\176\17\10\1\36\12\37\1\25"+ - "\1\33\1\40\1\33\1\0\1\33\1\41\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\2\0\1\3\13\0\1\221"+ - "\3\117\1\u0173\26\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\4\117\1\u0174\5\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\10\117\1\u0175\12\117\1\u0176\6\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\2\117"+ - "\1\u0177\7\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\7\117\1\u0178"+ - "\22\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\7\117"+ - "\1\u0179\22\117\1\36\3\117\1\u017a\6\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\7\117\1\u017b\22\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\31\117\1\u017c\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\117\1\u017d\30\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\7\117\1\u017e\1\117\1\u017f"+ - "\20\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\22\117"+ - "\1\u0180\7\117\1\36\2\117\1\u0181\7\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\7\117\1\u0182\22\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\7\117\1\u0183\5\117\1\u0184\14\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\23\117\1\u0185"+ - "\6\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\32\117"+ - "\1\36\3\117\1\u0186\6\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\17\117\1\u0187\12\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\1\u0188\11\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\17\0"+ - "\32\u0189\1\0\12\u0189\11\0\1\u018a\1\0\1\u018b\27\0"+ - "\46\u0154\1\u0156\2\u0154\1\u0157\3\u0154\1\u0158\5\0\2\u0154"+ - "\4\0\1\u0154\17\0\1\u018c\32\u0155\1\u018d\12\u0155\1\u018e"+ - "\2\u0154\1\u0157\3\u0154\1\u0158\1\0\1\u018f\3\0\2\u0154"+ - "\4\0\1\u0154\17\0\46\u0156\1\0\2\u0156\1\u0190\3\u0156"+ - "\1\u0158\5\0\2\u0156\4\0\1\u0156\20\0\4\u0191\2\0"+ - "\1\u0191\15\0\1\u0191\6\0\12\u0191\44\0\32\u0192\1\0"+ - "\12\u0192\13\0\1\u0159\30\0\4\u0193\2\0\1\u0193\15\0"+ - "\1\u0193\6\0\12\u0193\1\u0194\42\0\1\u0195\32\u0196\1\u0195"+ - "\12\u0196\1\u0197\2\u0195\1\u0198\3\u0195\1\u0199\3\0\1\u019a"+ - "\1\0\2\u0195\4\0\1\u0195\17\0\1\221\12\117\1\226"+ - "\17\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\6\0\1\3\2\4"+ - "\2\0\2\27\1\30\1\254\32\10\1\36\12\u015d\1\341"+ - "\1\33\1\46\1\33\1\0\2\47\1\34\1\321\1\322"+ - "\1\323\2\0\1\27\1\33\4\0\2\33\2\0\1\4"+ - "\3\0\1\3\2\4\2\0\2\27\1\30\1\254\32\10"+ - "\1\36\12\u019b\1\341\1\33\1\46\1\33\1\0\2\47"+ - "\1\34\1\321\1\322\1\323\2\0\1\27\1\33\4\0"+ - "\2\33\2\0\1\4\3\0\1\3\2\4\2\0\2\27"+ - "\1\30\1\254\32\10\1\36\1\u015d\1\u019c\1\u019b\2\u015d"+ - "\2\u019b\2\u015d\1\u019b\1\341\1\33\1\46\1\33\1\0"+ - "\2\47\1\34\1\321\1\322\1\323\2\0\1\27\1\33"+ - "\4\0\2\33\2\0\1\4\61\0\1\356\43\0\4\u019d"+ - "\2\0\1\u019d\15\0\1\u019d\6\0\12\u019d\1\u0161\43\0"+ - "\4\u019e\2\0\1\u019e\15\0\1\u019e\6\0\12\u019e\1\u019f"+ - "\43\0\4\u01a0\2\0\1\u01a0\15\0\1\u01a0\6\0\12\u01a0"+ - "\1\u01a1\13\0\1\264\26\0\1\365\4\u01a0\2\0\1\u01a0"+ - "\15\0\1\u01a0\6\0\12\u01a2\1\u01a1\13\0\1\264\26\0"+ - "\1\365\4\u01a0\2\0\1\u01a0\15\0\1\u01a0\6\0\12\u01a3"+ - "\1\u01a1\13\0\1\264\26\0\1\365\4\u01a0\2\0\1\u01a0"+ - "\15\0\1\u01a0\6\0\1\u01a2\1\u01a4\1\u01a3\2\u01a2\2\u01a3"+ - "\2\u01a2\1\u01a3\1\u01a1\13\0\1\264\27\0\4\u01a5\2\0"+ - "\1\u01a5\15\0\1\u01a5\6\0\12\u01a5\1\u0128\13\0\1\264"+ - "\26\0\1\365\4\u01a5\2\0\1\u01a5\15\0\1\u01a5\6\0"+ - "\12\u01a5\1\u0128\13\0\1\264\74\0\1\364\13\0\1\264"+ - "\62\0\1\u01a6\2\u01a7\1\u01a6\4\u01a7\1\u01a8\1\u01a7\43\0"+ - "\1\u0169\110\0\1\u0169\33\0\2\u016a\1\0\2\u016a\2\0"+ - "\2\u016a\45\0\4\371\2\0\1\371\15\0\1\371\6\0"+ - "\12\371\44\0\4\372\2\0\1\372\15\0\1\372\6\0"+ - "\12\372\44\0\4\373\2\0\1\373\15\0\1\373\6\0"+ - "\12\373\43\0\1\172\20\63\1\u01a9\11\63\1\173\12\63"+ - "\43\0\1\172\3\63\1\u0107\26\63\1\173\12\63\44\0"+ - "\2\63\1\u01aa\2\63\1\u01ab\1\u01ac\1\u01ad\2\63\1\u01ae"+ - "\2\63\1\u01af\3\63\1\u01b0\1\u01b1\1\u01b2\1\63\1\u01b3"+ - "\1\u01b4\1\63\1\u01b5\1\u01b6\1\173\1\u01b7\2\63\1\u01b8"+ - "\1\63\1\u01b9\1\u01ba\3\63\77\0\12\u01bb\10\0\1\371"+ - "\1\372\1\373\30\0\1\221\24\117\1\u01bc\5\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\1\117\1\u01bd\30\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\14\117\1\u01be"+ - "\15\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\1\117"+ - "\1\u01bf\30\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\21\117\1\u01c0\10\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\24\117\1\u01c1\5\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\24\117\1\u01c2\5\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\344\31\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\24\117\1\u01c3\5\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\1\117\1\u01c4\30\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\31\117\1\u01c5\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\24\117\1\u01c6\5\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\117\1\u01c7"+ - "\30\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\1\u01c8"+ - "\31\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\21\117"+ - "\1\u01c9\10\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\24\117\1\u01ca\5\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\24\117\1\u01cb\5\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\4\117\1\u01cc\25\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\21\117\1\u01cd\10\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\24\117\1\u01ce\5\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\7\117"+ - "\1\u01cf\2\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\u01d0\31\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\u01d1\32\u0189\1\u01d2"+ - "\12\u0189\11\0\1\u018a\31\0\51\u018a\1\u01d3\3\0\3\u018a"+ - "\1\373\3\0\1\u018a\25\0\4\u01d4\2\0\1\u01d4\15\0"+ - "\1\u01d4\6\0\12\u01d4\1\u01d5\42\0\1\u0154\32\u0155\1\u0154"+ - "\12\u0155\1\u0156\2\u0154\1\u0157\3\u0154\1\u0158\5\0\2\u0154"+ - "\4\0\1\u0154\17\0\1\u0154\32\u0155\1\u018d\12\u0155\1\u0156"+ - "\2\u0154\1\u0157\3\u0154\1\u0158\5\0\2\u0154\4\0\1\u0154"+ - "\17\0\34\u0156\12\u01d6\1\0\2\u0156\1\u0190\3\u0156\1\u0158"+ - "\5\0\2\u0156\4\0\1\u0156\17\0\51\u018f\1\u01d7\3\0"+ - "\3\u018f\1\373\2\0\1\u01d8\1\u018f\25\0\4\u01d9\2\0"+ - "\1\u01d9\15\0\1\u01d9\6\0\12\u01d9\44\0\4\u0154\2\0"+ - "\1\u0154\15\0\1\u0154\6\0\12\u0154\43\0\1\u01da\32\u0192"+ - "\1\u01db\12\u0192\1\u01dc\10\0\1\u018f\32\0\4\u01dd\2\0"+ - "\1\u01dd\15\0\1\u01dd\6\0\12\u01dd\1\u01de\110\0\1\u01df"+ - "\42\0\46\u0195\1\u0197\2\u0195\1\u0198\3\u0195\1\u0199\5\0"+ - "\2\u0195\4\0\1\u0195\17\0\1\u01e0\32\u0196\1\u01e1\12\u0196"+ - "\1\u01e2\2\u0195\1\u0198\3\u0195\1\u0199\1\371\1\372\1\373"+ - "\2\0\2\u0195\4\0\1\u0195\17\0\46\u0197\1\0\2\u0197"+ - "\1\u01e3\3\u0197\1\u0199\5\0\2\u0197\4\0\1\u0197\20\0"+ - "\4\u01e4\2\0\1\u01e4\15\0\1\u01e4\6\0\12\u01e4\44\0"+ - "\32\u01e5\1\0\12\u01e5\13\0\1\u019a\17\0\1\3\2\4"+ - "\2\0\2\27\1\30\1\254\32\10\1\36\12\163\1\341"+ - "\1\33\1\46\1\33\1\0\2\47\1\34\1\321\1\322"+ - "\1\323\2\0\1\27\1\33\4\0\2\33\2\0\1\4"+ - "\3\0\1\3\2\4\2\0\2\27\1\30\1\254\32\10"+ - "\1\36\2\u019b\1\163\2\u019b\2\163\2\u019b\1\163\1\341"+ - "\1\33\1\46\1\33\1\0\2\47\1\34\1\321\1\322"+ - "\1\323\2\0\1\27\1\33\4\0\2\33\2\0\1\4"+ - "\14\0\4\u01e6\2\0\1\u01e6\15\0\1\u01e6\6\0\12\u01e6"+ - "\1\u0161\43\0\4\u01e7\2\0\1\u01e7\15\0\1\u01e7\6\0"+ - "\12\u01e7\1\u01e8\43\0\4\u01e9\2\0\1\u01e9\15\0\1\u01e9"+ - "\6\0\1\u01ea\2\u01eb\1\u01ea\4\u01eb\1\u01ec\1\u01eb\14\0"+ - "\1\264\27\0\4\u01ed\2\0\1\u01ed\15\0\1\u01ed\6\0"+ - "\12\u01ed\1\u01a1\13\0\1\264\27\0\4\u01e9\2\0\1\u01e9"+ - "\15\0\1\u01e9\6\0\1\u01ea\2\u01eb\1\u01ea\4\u01eb\1\u01ec"+ - "\1\u01eb\43\0\1\365\4\u01ed\2\0\1\u01ed\15\0\1\u01ed"+ - "\6\0\12\u01ee\1\u01a1\13\0\1\264\26\0\1\365\4\u01ed"+ - "\2\0\1\u01ed\15\0\1\u01ed\6\0\12\u01ed\1\u01a1\13\0"+ - "\1\264\26\0\1\365\4\u01ed\2\0\1\u01ed\15\0\1\u01ed"+ - "\6\0\2\u01ee\1\u01ed\2\u01ee\2\u01ed\2\u01ee\1\u01ed\1\u01a1"+ - "\13\0\1\264\74\0\1\u0128\13\0\1\264\26\0\1\u01ef"+ - "\33\0\12\u01a7\43\0\1\u01ef\33\0\12\u01f0\43\0\1\u01ef"+ - "\33\0\1\u01a7\1\u01f1\1\u01f0\2\u01a7\2\u01f0\2\u01a7\1\u01f0"+ - "\43\0\1\172\12\63\1\374\17\63\1\173\12\63\43\0"+ - "\1\172\3\63\1\u01f2\26\63\1\173\12\63\43\0\1\172"+ - "\32\63\1\173\4\63\1\u01f3\5\63\43\0\1\172\10\63"+ - "\1\u01f4\12\63\1\u01f5\6\63\1\173\12\63\43\0\1\172"+ - "\32\63\1\173\2\63\1\u01f6\7\63\43\0\1\172\7\63"+ - "\1\u01f7\22\63\1\173\12\63\43\0\1\172\7\63\1\u01f8"+ - "\22\63\1\173\3\63\1\u01f9\6\63\43\0\1\172\7\63"+ - "\1\u01fa\22\63\1\173\12\63\43\0\1\172\31\63\1\u01fb"+ - "\1\173\12\63\43\0\1\172\1\63\1\u01fc\30\63\1\173"+ - "\12\63\43\0\1\172\7\63\1\u01fd\1\63\1\u01fe\20\63"+ - "\1\173\12\63\43\0\1\172\22\63\1\u01ff\7\63\1\173"+ - "\2\63\1\u0200\7\63\43\0\1\172\7\63\1\u0201\22\63"+ - "\1\173\12\63\43\0\1\172\7\63\1\u0202\5\63\1\u0203"+ - "\14\63\1\173\12\63\43\0\1\172\23\63\1\u0204\6\63"+ - "\1\173\12\63\43\0\1\172\32\63\1\173\3\63\1\u0205"+ - "\6\63\43\0\1\172\17\63\1\u0206\12\63\1\173\12\63"+ - "\43\0\1\172\32\63\1\173\1\u0207\11\63\77\0\12\u0208"+ - "\10\0\1\371\1\372\1\373\30\0\1\221\1\u0209\31\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\21\117\1\u020a"+ - "\10\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\16\117"+ - "\1\u020b\4\117\1\u020c\6\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\10\117\1\u020d\1\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\32\117\1\36\10\117\1\u020e\1\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\1\u020f\2\117\1\u0210\26\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\16\117\1\u0211"+ - "\13\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\25\117"+ - "\1\u0212\4\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\10\117\1\u0213\1\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\23\117\1\u0214\6\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\31\117\1\u0215\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\26\117\1\u0216\3\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\11\117\1\u0217\20\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\32\117\1\36\3\117\1\u0218"+ - "\6\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\10\117\1\u0219\21\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\3\117\1\u021a"+ - "\26\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\21\117"+ - "\1\u021b\6\117\1\u021c\1\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\12\117\1\u021d\17\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\32\117\1\36\1\117\1\u021e\10\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\24\117\1\u021f\5\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\31\117\1\u0220\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\17\0\32\u0189\1\0\12\u0189\44\0"+ - "\32\u0189\1\u01d2\12\u0189\44\0\4\u0221\2\0\1\u0221\15\0"+ - "\1\u0221\6\0\12\u0221\44\0\4\u0222\2\0\1\u0222\15\0"+ - "\1\u0222\6\0\12\u0222\1\u0223\110\0\1\u0224\42\0\34\u0156"+ - "\12\u0225\1\0\2\u0156\1\u0190\3\u0156\1\u0158\1\0\1\u018f"+ - "\3\0\2\u0156\4\0\1\u0156\20\0\4\u0226\2\0\1\u0226"+ - "\15\0\1\u0226\6\0\12\u0226\63\0\1\u0227\71\0\4\u0156"+ - "\2\0\1\u0156\15\0\1\u0156\6\0\12\u0156\44\0\32\u0192"+ - "\1\0\12\u0192\44\0\32\u0192\1\u01db\12\u0192\77\0\12\u0228"+ - "\44\0\4\u0229\2\0\1\u0229\15\0\1\u0229\6\0\12\u0229"+ - "\1\u01de\43\0\4\u022a\2\0\1\u022a\15\0\1\u022a\6\0"+ - "\12\u022a\1\u022b\43\0\4\u022c\2\0\1\u022c\15\0\1\u022c"+ - "\6\0\1\u022d\2\u022e\1\u022d\4\u022e\1\u022f\1\u022e\14\0"+ - "\1\u0230\26\0\1\u0195\32\u0196\1\u0195\12\u0196\1\u0197\2\u0195"+ - "\1\u0198\3\u0195\1\u0199\5\0\2\u0195\4\0\1\u0195\17\0"+ - "\1\u0195\32\u0196\1\u01e1\12\u0196\1\u0197\2\u0195\1\u0198\3\u0195"+ - "\1\u0199\5\0\2\u0195\4\0\1\u0195\17\0\34\u0197\12\u0231"+ - "\1\0\2\u0197\1\u01e3\3\u0197\1\u0199\5\0\2\u0197\4\0"+ - "\1\u0197\20\0\4\u0232\2\0\1\u0232\15\0\1\u0232\6\0"+ - "\12\u0232\44\0\4\u0195\2\0\1\u0195\15\0\1\u0195\6\0"+ - "\12\u0195\43\0\1\u0233\32\u01e5\1\u0234\12\u01e5\1\341\7\0"+ - "\1\371\1\372\1\373\76\0\1\u0161\43\0\4\u0235\2\0"+ - "\1\u0235\15\0\1\u0235\6\0\12\u0235\1\u01e8\43\0\4\u0236"+ - "\2\0\1\u0236\15\0\1\u0236\6\0\12\u0236\1\u0237\43\0"+ - "\4\u0238\2\0\1\u0238\15\0\1\u0238\6\0\12\u0238\1\u0239"+ - "\13\0\1\264\26\0\1\365\4\u0238\2\0\1\u0238\15\0"+ - "\1\u0238\6\0\12\u023a\1\u0239\13\0\1\264\26\0\1\365"+ - "\4\u0238\2\0\1\u0238\15\0\1\u0238\6\0\12\u023b\1\u0239"+ - "\13\0\1\264\26\0\1\365\4\u0238\2\0\1\u0238\15\0"+ - "\1\u0238\6\0\1\u023a\1\u023c\1\u023b\2\u023a\2\u023b\2\u023a"+ - "\1\u023b\1\u0239\13\0\1\264\27\0\4\u023d\2\0\1\u023d"+ - "\15\0\1\u023d\6\0\12\u023d\1\u01a1\13\0\1\264\26\0"+ - "\1\365\4\u023d\2\0\1\u023d\15\0\1\u023d\6\0\12\u023d"+ - "\1\u01a1\13\0\1\264\62\0\1\u023e\2\u023f\1\u023e\4\u023f"+ - "\1\u0240\1\u023f\43\0\1\u01ef\110\0\1\u01ef\33\0\2\u01f0"+ - "\1\0\2\u01f0\2\0\2\u01f0\44\0\1\172\24\63\1\u0241"+ - "\5\63\1\173\12\63\43\0\1\172\1\63\1\u0242\30\63"+ - "\1\173\12\63\43\0\1\172\14\63\1\u0243\15\63\1\173"+ - "\12\63\43\0\1\172\1\63\1\u0244\30\63\1\173\12\63"+ - "\43\0\1\172\21\63\1\u0245\10\63\1\173\12\63\43\0"+ - "\1\172\24\63\1\u0246\5\63\1\173\12\63\43\0\1\172"+ - "\24\63\1\u0247\5\63\1\173\12\63\43\0\1\172\1\u0137"+ - "\31\63\1\173\12\63\43\0\1\172\24\63\1\u0248\5\63"+ - "\1\173\12\63\43\0\1\172\1\63\1\u0249\30\63\1\173"+ - "\12\63\43\0\1\172\31\63\1\u024a\1\173\12\63\43\0"+ - "\1\172\24\63\1\u024b\5\63\1\173\12\63\43\0\1\172"+ - "\1\63\1\u024c\30\63\1\173\12\63\43\0\1\172\1\u024d"+ - "\31\63\1\173\12\63\43\0\1\172\21\63\1\u024e\10\63"+ - "\1\173\12\63\43\0\1\172\24\63\1\u024f\5\63\1\173"+ - "\12\63\43\0\1\172\24\63\1\u0250\5\63\1\173\12\63"+ - "\43\0\1\172\4\63\1\u0251\25\63\1\173\12\63\43\0"+ - "\1\172\21\63\1\u0252\10\63\1\173\12\63\43\0\1\172"+ - "\24\63\1\u0253\5\63\1\173\12\63\43\0\1\172\32\63"+ - "\1\173\7\63\1\u0254\2\63\43\0\1\172\1\u0255\31\63"+ - "\1\173\12\63\121\0\1\371\1\372\1\373\30\0\1\221"+ - "\32\117\1\36\1\u0256\11\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\7\117\1\u0257\2\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\6\117\1\350\3\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\5\117\1\350\4\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\117\1\u0258\30\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\32\117\1\36\1\117\1\u0259"+ - "\10\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\1\u025a\27\117\1\u025b"+ - "\1\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\4\117"+ - "\1\u025c\25\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\1\u025d\11\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\3\117\1\u025e\6\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\1\u025f\31\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\1\u0257\31\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\2\117\1\u0260\7\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\2\117\1\u0261\7\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\15\117\1\u0262\14\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\32\117\1\36\5\117\1\u0263"+ - "\4\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\10\117"+ - "\1\u0264\1\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\117\1\u0265"+ - "\30\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\32\117"+ - "\1\36\3\117\1\u0266\6\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\1\117\1\u0267\10\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\1\117\1\u0268\10\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\24\117\1\u0269\5\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\32\117\1\36\3\117\1\u026a\6\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\25\117\1\u026b\4\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\17\0\4\u018a\2\0\1\u018a\15\0"+ - "\1\u018a\6\0\12\u018a\44\0\4\u026c\2\0\1\u026c\15\0"+ - "\1\u026c\6\0\12\u026c\1\u0223\43\0\4\u026d\2\0\1\u026d"+ - "\15\0\1\u026d\6\0\12\u026d\1\u026e\43\0\4\u026f\2\0"+ - "\1\u026f\15\0\1\u026f\6\0\1\u0270\2\u0271\1\u0270\4\u0271"+ - "\1\u0272\1\u0271\14\0\1\u0273\26\0\34\u0156\12\u0274\1\0"+ - "\2\u0156\1\u0190\3\u0156\1\u0158\1\0\1\u018f\3\0\2\u0156"+ - "\4\0\1\u0156\20\0\4\u018f\2\0\1\u018f\15\0\1\u018f"+ - "\6\0\12\u018f\74\0\1\u0275\113\0\12\u0276\11\0\1\u018f"+ - "\32\0\4\u0277\2\0\1\u0277\15\0\1\u0277\6\0\12\u0277"+ - "\1\u01de\43\0\4\u0278\2\0\1\u0278\15\0\1\u0278\6\0"+ - "\12\u0278\1\u0279\43\0\4\u027a\2\0\1\u027a\15\0\1\u027a"+ - "\6\0\1\u027b\2\u027c\1\u027b\4\u027c\1\u027d\1\u027c\14\0"+ - "\1\u0230\27\0\4\u027e\2\0\1\u027e\15\0\1\u027e\6\0"+ - "\12\u027e\1\u027f\13\0\1\u0230\26\0\1\u0280\4\u027e\2\0"+ - "\1\u027e\15\0\1\u027e\6\0\12\u0281\1\u027f\13\0\1\u0230"+ - "\26\0\1\u0280\4\u027e\2\0\1\u027e\15\0\1\u027e\6\0"+ - "\12\u0282\1\u027f\13\0\1\u0230\26\0\1\u0280\4\u027e\2\0"+ - "\1\u027e\15\0\1\u027e\6\0\1\u0281\1\u0283\1\u0282\2\u0281"+ - "\2\u0282\2\u0281\1\u0282\1\u027f\13\0\1\u0230\74\0\1\u01dc"+ - "\10\0\1\u018f\31\0\34\u0197\12\u0284\1\0\2\u0197\1\u01e3"+ - "\3\u0197\1\u0199\1\371\1\372\1\373\2\0\2\u0197\4\0"+ - "\1\u0197\20\0\4\u0197\2\0\1\u0197\15\0\1\u0197\6\0"+ - "\12\u0197\44\0\32\u01e5\1\0\12\u01e5\44\0\32\u01e5\1\u0234"+ - "\12\u01e5\44\0\4\u0285\2\0\1\u0285\15\0\1\u0285\6\0"+ - "\12\u0285\1\u01e8\43\0\4\u0286\2\0\1\u0286\15\0\1\u0286"+ - "\6\0\12\u0286\1\u0287\43\0\4\u0288\2\0\1\u0288\15\0"+ - "\1\u0288\6\0\1\u0289\2\u028a\1\u0289\4\u028a\1\u028b\1\u028a"+ - "\14\0\1\264\27\0\4\u028c\2\0\1\u028c\15\0\1\u028c"+ - "\6\0\12\u028c\1\u0239\13\0\1\264\27\0\4\u0288\2\0"+ - "\1\u0288\15\0\1\u0288\6\0\1\u0289\2\u028a\1\u0289\4\u028a"+ - "\1\u028b\1\u028a\43\0\1\365\4\u028c\2\0\1\u028c\15\0"+ - "\1\u028c\6\0\12\u028d\1\u0239\13\0\1\264\26\0\1\365"+ - "\4\u028c\2\0\1\u028c\15\0\1\u028c\6\0\12\u028c\1\u0239"+ - "\13\0\1\264\26\0\1\365\4\u028c\2\0\1\u028c\15\0"+ - "\1\u028c\6\0\2\u028d\1\u028c\2\u028d\2\u028c\2\u028d\1\u028c"+ - "\1\u0239\13\0\1\264\74\0\1\u01a1\13\0\1\264\62\0"+ - "\12\u023f\14\0\1\264\62\0\12\u028e\14\0\1\264\62\0"+ - "\1\u023f\1\u028f\1\u028e\2\u023f\2\u028e\2\u023f\1\u028e\14\0"+ - "\1\264\26\0\1\172\1\u0290\31\63\1\173\12\63\43\0"+ - "\1\172\21\63\1\u0291\10\63\1\173\12\63\43\0\1\172"+ - "\16\63\1\u0292\4\63\1\u0293\6\63\1\173\12\63\43\0"+ - "\1\172\32\63\1\173\10\63\1\u0294\1\63\43\0\1\172"+ - "\32\63\1\173\10\63\1\u0295\1\63\43\0\1\172\1\u0296"+ - "\2\63\1\u0297\26\63\1\173\12\63\43\0\1\172\16\63"+ - "\1\u0298\13\63\1\173\12\63\43\0\1\172\25\63\1\u0299"+ - "\4\63\1\173\12\63\43\0\1\172\32\63\1\173\10\63"+ - "\1\u029a\1\63\43\0\1\172\23\63\1\u029b\6\63\1\173"+ - "\12\63\43\0\1\172\31\63\1\u029c\1\173\12\63\43\0"+ - "\1\172\26\63\1\u029d\3\63\1\173\12\63\43\0\1\172"+ - "\11\63\1\u029e\20\63\1\173\12\63\43\0\1\172\32\63"+ - "\1\173\3\63\1\u029f\6\63\43\0\1\172\10\63\1\u02a0"+ - "\21\63\1\173\12\63\43\0\1\172\3\63\1\u02a1\26\63"+ - "\1\173\12\63\43\0\1\172\21\63\1\u02a2\6\63\1\u02a3"+ - "\1\63\1\173\12\63\43\0\1\172\12\63\1\u02a4\17\63"+ - "\1\173\12\63\43\0\1\172\32\63\1\173\1\63\1\u02a5"+ - "\10\63\43\0\1\172\24\63\1\u02a6\5\63\1\173\12\63"+ - "\43\0\1\172\31\63\1\u02a7\1\173\12\63\43\0\1\221"+ - "\1\u02a8\31\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\25\117\1\226\4\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\5\117\1\u02a9\4\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\3\117\1\u02a8\6\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\12\117\1\u02aa\17\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\25\117\1\u02ab\4\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\15\117\1\u02ac\14\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\2\117\1\u0257"+ - "\27\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\1\117"+ - "\1\226\30\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\11\117\1\u02ad\20\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\1\u02ae\31\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\1\u02af\31\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\2\117\1\u02b0\27\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\4\117\1\235\5\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\u02b1\31\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\25\117\1\u02b2\4\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\32\117\1\36\4\117\1\u02a8"+ - "\5\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\11\117"+ - "\1\u02a8\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\2\117"+ - "\1\u02a8\7\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\16\117\1\u02b3"+ - "\13\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\32\117"+ - "\1\36\3\117\1\u02b4\6\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\24\117\1\u02b5\5\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\17\0"+ - "\4\u02b6\2\0\1\u02b6\15\0\1\u02b6\6\0\12\u02b6\1\u0223"+ - "\43\0\4\u02b7\2\0\1\u02b7\15\0\1\u02b7\6\0\12\u02b7"+ - "\1\u02b8\43\0\4\u02b9\2\0\1\u02b9\15\0\1\u02b9\6\0"+ - "\1\u02ba\2\u02bb\1\u02ba\4\u02bb\1\u02bc\1\u02bb\14\0\1\u0273"+ - "\27\0\4\u02bd\2\0\1\u02bd\15\0\1\u02bd\6\0\12\u02bd"+ - "\1\u02be\13\0\1\u0273\26\0\1\u02bf\4\u02bd\2\0\1\u02bd"+ - "\15\0\1\u02bd\6\0\12\u02c0\1\u02be\13\0\1\u0273\26\0"+ - "\1\u02bf\4\u02bd\2\0\1\u02bd\15\0\1\u02bd\6\0\12\u02c1"+ - "\1\u02be\13\0\1\u0273\26\0\1\u02bf\4\u02bd\2\0\1\u02bd"+ - "\15\0\1\u02bd\6\0\1\u02c0\1\u02c2\1\u02c1\2\u02c0\2\u02c1"+ - "\2\u02c0\1\u02c1\1\u02be\13\0\1\u0273\105\0\1\u018a\31\0"+ - "\34\u0156\12\u02c3\1\0\2\u0156\1\u0190\3\u0156\1\u0158\1\0"+ - "\1\u018f\3\0\2\u0156\4\0\1\u0156\35\0\1\u02c4\126\0"+ - "\12\u02c5\11\0\1\u018f\77\0\1\u01de\43\0\4\u02c6\2\0"+ - "\1\u02c6\15\0\1\u02c6\6\0\12\u02c6\1\u0279\43\0\4\u02c7"+ - "\2\0\1\u02c7\15\0\1\u02c7\6\0\12\u02c7\1\u02c8\43\0"+ - "\4\u02c9\2\0\1\u02c9\15\0\1\u02c9\6\0\12\u02c9\1\u02ca"+ - "\13\0\1\u0230\26\0\1\u0280\4\u02c9\2\0\1\u02c9\15\0"+ - "\1\u02c9\6\0\12\u02cb\1\u02ca\13\0\1\u0230\26\0\1\u0280"+ - "\4\u02c9\2\0\1\u02c9\15\0\1\u02c9\6\0\12\u02cc\1\u02ca"+ - "\13\0\1\u0230\26\0\1\u0280\4\u02c9\2\0\1\u02c9\15\0"+ - "\1\u02c9\6\0\1\u02cb\1\u02cd\1\u02cc\2\u02cb\2\u02cc\2\u02cb"+ - "\1\u02cc\1\u02ca\13\0\1\u0230\27\0\4\u02ce\2\0\1\u02ce"+ - "\15\0\1\u02ce\6\0\12\u02ce\1\u027f\13\0\1\u0230\27\0"+ - "\4\u027a\2\0\1\u027a\15\0\1\u027a\6\0\1\u027b\2\u027c"+ - "\1\u027b\4\u027c\1\u027d\1\u027c\77\0\1\u02cf\2\u02d0\1\u02cf"+ - "\4\u02d0\1\u02d1\1\u02d0\43\0\1\u0280\4\u02ce\2\0\1\u02ce"+ - "\15\0\1\u02ce\6\0\12\u02d2\1\u027f\13\0\1\u0230\26\0"+ - "\1\u0280\4\u02ce\2\0\1\u02ce\15\0\1\u02ce\6\0\12\u02ce"+ - "\1\u027f\13\0\1\u0230\26\0\1\u0280\4\u02ce\2\0\1\u02ce"+ - "\15\0\1\u02ce\6\0\2\u02d2\1\u02ce\2\u02d2\2\u02ce\2\u02d2"+ - "\1\u02ce\1\u027f\13\0\1\u0230\26\0\34\u0197\12\u02d3\1\0"+ - "\2\u0197\1\u01e3\3\u0197\1\u0199\1\371\1\372\1\373\2\0"+ - "\2\u0197\4\0\1\u0197\65\0\1\u01e8\43\0\4\u02d4\2\0"+ - "\1\u02d4\15\0\1\u02d4\6\0\12\u02d4\1\u0287\43\0\4\u02d5"+ - "\2\0\1\u02d5\15\0\1\u02d5\6\0\12\u02d5\1\u02d6\43\0"+ - "\4\u02d7\2\0\1\u02d7\15\0\1\u02d7\6\0\12\u02d7\1\u02d8"+ - "\13\0\1\264\26\0\1\365\4\u02d7\2\0\1\u02d7\15\0"+ - "\1\u02d7\6\0\12\u02d9\1\u02d8\13\0\1\264\26\0\1\365"+ - "\4\u02d7\2\0\1\u02d7\15\0\1\u02d7\6\0\12\u02da\1\u02d8"+ - "\13\0\1\264\26\0\1\365\4\u02d7\2\0\1\u02d7\15\0"+ - "\1\u02d7\6\0\1\u02d9\1\u02db\1\u02da\2\u02d9\2\u02da\2\u02d9"+ - "\1\u02da\1\u02d8\13\0\1\264\27\0\4\u02dc\2\0\1\u02dc"+ - "\15\0\1\u02dc\6\0\12\u02dc\1\u0239\13\0\1\264\26\0"+ - "\1\365\4\u02dc\2\0\1\u02dc\15\0\1\u02dc\6\0\12\u02dc"+ - "\1\u0239\13\0\1\264\110\0\1\264\62\0\2\u028e\1\0"+ - "\2\u028e\2\0\2\u028e\15\0\1\264\26\0\1\172\32\63"+ - "\1\173\1\u02dd\11\63\43\0\1\172\32\63\1\173\7\63"+ - "\1\u02de\2\63\43\0\1\172\32\63\1\173\6\63\1\u013c"+ - "\3\63\43\0\1\172\32\63\1\173\5\63\1\u013c\4\63"+ - "\43\0\1\172\1\63\1\u02df\30\63\1\173\12\63\43\0"+ - "\1\172\32\63\1\173\1\63\1\u02e0\10\63\43\0\1\172"+ - "\1\u02e1\27\63\1\u02e2\1\63\1\173\12\63\43\0\1\172"+ - "\4\63\1\u02e3\25\63\1\173\12\63\43\0\1\172\32\63"+ - "\1\173\1\u02e4\11\63\43\0\1\172\32\63\1\173\3\63"+ - "\1\u02e5\6\63\43\0\1\172\1\u02e6\31\63\1\173\12\63"+ - "\43\0\1\172\1\u02de\31\63\1\173\12\63\43\0\1\172"+ - "\32\63\1\173\2\63\1\u02e7\7\63\43\0\1\172\32\63"+ - "\1\173\2\63\1\u02e8\7\63\43\0\1\172\15\63\1\u02e9"+ - "\14\63\1\173\12\63\43\0\1\172\32\63\1\173\5\63"+ - "\1\u02ea\4\63\43\0\1\172\32\63\1\173\10\63\1\u02eb"+ - "\1\63\43\0\1\172\1\63\1\u02ec\30\63\1\173\12\63"+ - "\43\0\1\172\32\63\1\173\3\63\1\u02ed\6\63\43\0"+ - "\1\172\32\63\1\173\1\63\1\u02ee\10\63\43\0\1\172"+ - "\32\63\1\173\1\63\1\u02ef\10\63\43\0\1\172\24\63"+ - "\1\u02f0\5\63\1\173\12\63\43\0\1\172\32\63\1\173"+ - "\3\63\1\u02f1\6\63\43\0\1\172\25\63\1\u02f2\4\63"+ - "\1\173\12\63\43\0\1\221\2\117\1\226\27\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\3\117\1\u02f3\26\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\32\117\1\36"+ - "\11\117\1\u02f4\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\32\117\1\36"+ - "\11\117\1\u02f5\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\32\117\1\36"+ - "\7\117\1\u02f6\2\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\32\117"+ - "\1\36\4\117\1\u02f7\5\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\26\117\1\u02f8\3\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\30\117\1\u02f9\1\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\11\117\1\343\20\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\12\117\1\u02fa\17\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\17\117\1\236\12\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\4\117"+ - "\1\u02fb\5\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\30\117\1\u02fc"+ - "\1\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\30\117"+ - "\1\u02fd\1\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\64\0\1\u0223"+ - "\43\0\4\u02fe\2\0\1\u02fe\15\0\1\u02fe\6\0\12\u02fe"+ - "\1\u02b8\43\0\4\u02ff\2\0\1\u02ff\15\0\1\u02ff\6\0"+ - "\12\u02ff\1\u0300\43\0\4\u0301\2\0\1\u0301\15\0\1\u0301"+ - "\6\0\12\u0301\1\u0302\13\0\1\u0273\26\0\1\u02bf\4\u0301"+ - "\2\0\1\u0301\15\0\1\u0301\6\0\12\u0303\1\u0302\13\0"+ - "\1\u0273\26\0\1\u02bf\4\u0301\2\0\1\u0301\15\0\1\u0301"+ - "\6\0\12\u0304\1\u0302\13\0\1\u0273\26\0\1\u02bf\4\u0301"+ - "\2\0\1\u0301\15\0\1\u0301\6\0\1\u0303\1\u0305\1\u0304"+ - "\2\u0303\2\u0304\2\u0303\1\u0304\1\u0302\13\0\1\u0273\27\0"+ - "\4\u0306\2\0\1\u0306\15\0\1\u0306\6\0\12\u0306\1\u02be"+ - "\13\0\1\u0273\27\0\4\u02b9\2\0\1\u02b9\15\0\1\u02b9"+ - "\6\0\1\u02ba\2\u02bb\1\u02ba\4\u02bb\1\u02bc\1\u02bb\77\0"+ - "\1\u0307\2\u0308\1\u0307\4\u0308\1\u0309\1\u0308\43\0\1\u02bf"+ - "\4\u0306\2\0\1\u0306\15\0\1\u0306\6\0\12\u030a\1\u02be"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u0306\2\0\1\u0306\15\0"+ - "\1\u0306\6\0\12\u0306\1\u02be\13\0\1\u0273\26\0\1\u02bf"+ - "\4\u0306\2\0\1\u0306\15\0\1\u0306\6\0\2\u030a\1\u0306"+ - "\2\u030a\2\u0306\2\u030a\1\u0306\1\u02be\13\0\1\u0273\26\0"+ - "\34\u0156\12\u030b\1\0\2\u0156\1\u0190\3\u0156\1\u0158\1\0"+ - "\1\u018f\3\0\2\u0156\4\0\1\u0156\23\0\1\u030c\140\0"+ - "\12\u030d\11\0\1\u018f\32\0\4\u030e\2\0\1\u030e\15\0"+ - "\1\u030e\6\0\12\u030e\1\u0279\43\0\4\u030f\2\0\1\u030f"+ - "\15\0\1\u030f\6\0\12\u030f\1\u0310\43\0\4\u0311\2\0"+ - "\1\u0311\15\0\1\u0311\6\0\1\u0312\2\u0313\1\u0312\4\u0313"+ - "\1\u0314\1\u0313\14\0\1\u0230\27\0\4\u0315\2\0\1\u0315"+ - "\15\0\1\u0315\6\0\12\u0315\1\u02ca\13\0\1\u0230\27\0"+ - "\4\u0311\2\0\1\u0311\15\0\1\u0311\6\0\1\u0312\2\u0313"+ - "\1\u0312\4\u0313\1\u0314\1\u0313\43\0\1\u0280\4\u0315\2\0"+ - "\1\u0315\15\0\1\u0315\6\0\12\u0316\1\u02ca\13\0\1\u0230"+ - "\26\0\1\u0280\4\u0315\2\0\1\u0315\15\0\1\u0315\6\0"+ - "\12\u0315\1\u02ca\13\0\1\u0230\26\0\1\u0280\4\u0315\2\0"+ - "\1\u0315\15\0\1\u0315\6\0\2\u0316\1\u0315\2\u0316\2\u0315"+ - "\2\u0316\1\u0315\1\u02ca\13\0\1\u0230\27\0\4\u0317\2\0"+ - "\1\u0317\15\0\1\u0317\6\0\12\u0317\1\u027f\13\0\1\u0230"+ - "\26\0\1\u0318\33\0\12\u02d0\43\0\1\u0318\33\0\12\u0319"+ - "\43\0\1\u0318\33\0\1\u02d0\1\u031a\1\u0319\2\u02d0\2\u0319"+ - "\2\u02d0\1\u0319\43\0\1\u0280\4\u0317\2\0\1\u0317\15\0"+ - "\1\u0317\6\0\12\u0317\1\u027f\13\0\1\u0230\26\0\34\u0197"+ - "\12\u031b\1\0\2\u0197\1\u01e3\3\u0197\1\u0199\1\371\1\372"+ - "\1\373\2\0\2\u0197\4\0\1\u0197\20\0\4\u031c\2\0"+ - "\1\u031c\15\0\1\u031c\6\0\12\u031c\1\u0287\43\0\4\u031d"+ - "\2\0\1\u031d\15\0\1\u031d\6\0\12\u031d\1\u031e\43\0"+ - "\4\u031f\2\0\1\u031f\15\0\1\u031f\6\0\1\u0320\2\u0321"+ - "\1\u0320\4\u0321\1\u0322\1\u0321\14\0\1\264\27\0\4\u0323"+ - "\2\0\1\u0323\15\0\1\u0323\6\0\12\u0323\1\u02d8\13\0"+ - "\1\264\27\0\4\u031f\2\0\1\u031f\15\0\1\u031f\6\0"+ - "\1\u0320\2\u0321\1\u0320\4\u0321\1\u0322\1\u0321\43\0\1\365"+ - "\4\u0323\2\0\1\u0323\15\0\1\u0323\6\0\12\u0324\1\u02d8"+ - "\13\0\1\264\26\0\1\365\4\u0323\2\0\1\u0323\15\0"+ - "\1\u0323\6\0\12\u0323\1\u02d8\13\0\1\264\26\0\1\365"+ - "\4\u0323\2\0\1\u0323\15\0\1\u0323\6\0\2\u0324\1\u0323"+ - "\2\u0324\2\u0323\2\u0324\1\u0323\1\u02d8\13\0\1\264\74\0"+ - "\1\u0239\13\0\1\264\26\0\1\172\1\u0325\31\63\1\173"+ - "\12\63\43\0\1\172\25\63\1\374\4\63\1\173\12\63"+ - "\43\0\1\172\32\63\1\173\5\63\1\u0326\4\63\43\0"+ - "\1\172\32\63\1\173\3\63\1\u0325\6\63\43\0\1\172"+ - "\12\63\1\u0327\17\63\1\173\12\63\43\0\1\172\25\63"+ - "\1\u0328\4\63\1\173\12\63\43\0\1\172\15\63\1\u0329"+ - "\14\63\1\173\12\63\43\0\1\172\2\63\1\u02de\27\63"+ - "\1\173\12\63\43\0\1\172\1\63\1\374\30\63\1\173"+ - "\12\63\43\0\1\172\11\63\1\u032a\20\63\1\173\12\63"+ - "\43\0\1\172\1\u032b\31\63\1\173\12\63\43\0\1\172"+ - "\1\u032c\31\63\1\173\12\63\43\0\1\172\2\63\1\u032d"+ - "\27\63\1\173\12\63\43\0\1\172\32\63\1\173\4\63"+ - "\1\u0103\5\63\43\0\1\172\1\u032e\31\63\1\173\12\63"+ - "\43\0\1\172\25\63\1\u032f\4\63\1\173\12\63\43\0"+ - "\1\172\32\63\1\173\4\63\1\u0325\5\63\43\0\1\172"+ - "\32\63\1\173\11\63\1\u0325\43\0\1\172\32\63\1\173"+ - "\2\63\1\u0325\7\63\43\0\1\172\16\63\1\u0330\13\63"+ - "\1\173\12\63\43\0\1\172\32\63\1\173\3\63\1\u0331"+ - "\6\63\43\0\1\172\24\63\1\u0332\5\63\1\173\12\63"+ - "\43\0\1\221\32\117\1\36\10\117\1\u025e\1\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\1\u0333\31\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\7\117\1\u0334\22\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\1\u0335\31\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\25\117\1\u0336\4\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\11\117"+ - "\1\u0337\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\1\u0338\31\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\12\117\1\u0339\17\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\u033a\31\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\10\117\1\u033b"+ - "\21\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\31\117"+ - "\1\u033c\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\17\0\4\u033d\2\0"+ - "\1\u033d\15\0\1\u033d\6\0\12\u033d\1\u02b8\43\0\4\u033e"+ - "\2\0\1\u033e\15\0\1\u033e\6\0\12\u033e\1\u033f\43\0"+ - "\4\u0340\2\0\1\u0340\15\0\1\u0340\6\0\1\u0341\2\u0342"+ - "\1\u0341\4\u0342\1\u0343\1\u0342\14\0\1\u0273\27\0\4\u0344"+ - "\2\0\1\u0344\15\0\1\u0344\6\0\12\u0344\1\u0302\13\0"+ - "\1\u0273\27\0\4\u0340\2\0\1\u0340\15\0\1\u0340\6\0"+ - "\1\u0341\2\u0342\1\u0341\4\u0342\1\u0343\1\u0342\43\0\1\u02bf"+ - "\4\u0344\2\0\1\u0344\15\0\1\u0344\6\0\12\u0345\1\u0302"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u0344\2\0\1\u0344\15\0"+ - "\1\u0344\6\0\12\u0344\1\u0302\13\0\1\u0273\26\0\1\u02bf"+ - "\4\u0344\2\0\1\u0344\15\0\1\u0344\6\0\2\u0345\1\u0344"+ - "\2\u0345\2\u0344\2\u0345\1\u0344\1\u0302\13\0\1\u0273\27\0"+ - "\4\u0346\2\0\1\u0346\15\0\1\u0346\6\0\12\u0346\1\u02be"+ - "\13\0\1\u0273\26\0\1\u0347\33\0\12\u0308\43\0\1\u0347"+ - "\33\0\12\u0348\43\0\1\u0347\33\0\1\u0308\1\u0349\1\u0348"+ - "\2\u0308\2\u0348\2\u0308\1\u0348\43\0\1\u02bf\4\u0346\2\0"+ - "\1\u0346\15\0\1\u0346\6\0\12\u0346\1\u02be\13\0\1\u0273"+ - "\26\0\46\u0156\1\0\2\u0156\1\u0190\3\u0156\1\u0158\1\0"+ - "\1\u018f\3\0\2\u0156\4\0\1\u0156\103\0\1\u034a\60\0"+ - "\12\u034b\11\0\1\u018f\77\0\1\u0279\43\0\4\u034c\2\0"+ - "\1\u034c\15\0\1\u034c\6\0\12\u034c\1\u0310\43\0\4\u034d"+ - "\2\0\1\u034d\15\0\1\u034d\6\0\12\u034d\1\u034e\43\0"+ - "\4\u034f\2\0\1\u034f\15\0\1\u034f\6\0\12\u034f\1\u0350"+ - "\13\0\1\u0230\26\0\1\u0280\4\u034f\2\0\1\u034f\15\0"+ - "\1\u034f\6\0\12\u0351\1\u0350\13\0\1\u0230\26\0\1\u0280"+ - "\4\u034f\2\0\1\u034f\15\0\1\u034f\6\0\12\u0352\1\u0350"+ - "\13\0\1\u0230\26\0\1\u0280\4\u034f\2\0\1\u034f\15\0"+ - "\1\u034f\6\0\1\u0351\1\u0353\1\u0352\2\u0351\2\u0352\2\u0351"+ - "\1\u0352\1\u0350\13\0\1\u0230\27\0\4\u0354\2\0\1\u0354"+ - "\15\0\1\u0354\6\0\12\u0354\1\u02ca\13\0\1\u0230\26\0"+ - "\1\u0280\4\u0354\2\0\1\u0354\15\0\1\u0354\6\0\12\u0354"+ - "\1\u02ca\13\0\1\u0230\74\0\1\u027f\13\0\1\u0230\62\0"+ - "\1\u0355\2\u0356\1\u0355\4\u0356\1\u0357\1\u0356\43\0\1\u0318"+ - "\110\0\1\u0318\33\0\2\u0319\1\0\2\u0319\2\0\2\u0319"+ - "\44\0\34\u0197\12\u0358\1\0\2\u0197\1\u01e3\3\u0197\1\u0199"+ - "\1\371\1\372\1\373\2\0\2\u0197\4\0\1\u0197\65\0"+ - "\1\u0287\43\0\4\u0359\2\0\1\u0359\15\0\1\u0359\6\0"+ - "\12\u0359\1\u031e\43\0\4\u035a\2\0\1\u035a\15\0\1\u035a"+ - "\6\0\1\u035b\2\u035c\1\u035b\4\u035c\1\u035d\1\u035c\1\u035e"+ - "\43\0\4\u035f\2\0\1\u035f\15\0\1\u035f\6\0\12\u035f"+ - "\1\u0360\13\0\1\264\26\0\1\365\4\u035f\2\0\1\u035f"+ - "\15\0\1\u035f\6\0\12\u0361\1\u0360\13\0\1\264\26\0"+ - "\1\365\4\u035f\2\0\1\u035f\15\0\1\u035f\6\0\12\u0362"+ - "\1\u0360\13\0\1\264\26\0\1\365\4\u035f\2\0\1\u035f"+ - "\15\0\1\u035f\6\0\1\u0361\1\u0363\1\u0362\2\u0361\2\u0362"+ - "\2\u0361\1\u0362\1\u0360\13\0\1\264\27\0\4\u0364\2\0"+ - "\1\u0364\15\0\1\u0364\6\0\12\u0364\1\u02d8\13\0\1\264"+ - "\26\0\1\365\4\u0364\2\0\1\u0364\15\0\1\u0364\6\0"+ - "\12\u0364\1\u02d8\13\0\1\264\26\0\1\172\2\63\1\374"+ - "\27\63\1\173\12\63\43\0\1\172\3\63\1\u0365\26\63"+ - "\1\173\12\63\43\0\1\172\32\63\1\173\11\63\1\u0366"+ - "\43\0\1\172\32\63\1\173\11\63\1\u0367\43\0\1\172"+ - "\32\63\1\173\7\63\1\u0368\2\63\43\0\1\172\32\63"+ - "\1\173\4\63\1\u0369\5\63\43\0\1\172\26\63\1\u036a"+ - "\3\63\1\173\12\63\43\0\1\172\30\63\1\u036b\1\63"+ - "\1\173\12\63\43\0\1\172\11\63\1\u0136\20\63\1\173"+ - "\12\63\43\0\1\172\12\63\1\u036c\17\63\1\173\12\63"+ - "\43\0\1\172\17\63\1\u0104\12\63\1\173\12\63\43\0"+ - "\1\172\32\63\1\173\4\63\1\u036d\5\63\43\0\1\172"+ - "\30\63\1\u036e\1\63\1\173\12\63\43\0\1\172\30\63"+ - "\1\u036f\1\63\1\173\12\63\43\0\1\221\32\117\1\36"+ - "\6\117\1\u0257\3\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\15\117"+ - "\1\142\14\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\16\0\1\221"+ - "\32\117\1\36\1\117\1\u0370\10\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\30\117\1\u0371\1\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\6\117\1\u0372\23\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\32\117\1\36\5\117\1\u0373\4\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\22\117\1\226\7\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\5\117"+ - "\1\u0374\4\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\32\117\1\36"+ - "\1\117\1\142\10\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\13\117"+ - "\1\u0375\16\117\1\36\12\117\1\0\3\33\1\0\2\33"+ - "\1\34\3\33\3\0\1\33\4\0\2\33\64\0\1\u02b8"+ - "\43\0\4\u0376\2\0\1\u0376\15\0\1\u0376\6\0\12\u0376"+ - "\1\u033f\43\0\4\u0377\2\0\1\u0377\15\0\1\u0377\6\0"+ - "\12\u0377\1\u0378\43\0\4\u0379\2\0\1\u0379\15\0\1\u0379"+ - "\6\0\12\u0379\1\u037a\13\0\1\u0273\26\0\1\u02bf\4\u0379"+ - "\2\0\1\u0379\15\0\1\u0379\6\0\12\u037b\1\u037a\13\0"+ - "\1\u0273\26\0\1\u02bf\4\u0379\2\0\1\u0379\15\0\1\u0379"+ - "\6\0\12\u037c\1\u037a\13\0\1\u0273\26\0\1\u02bf\4\u0379"+ - "\2\0\1\u0379\15\0\1\u0379\6\0\1\u037b\1\u037d\1\u037c"+ - "\2\u037b\2\u037c\2\u037b\1\u037c\1\u037a\13\0\1\u0273\27\0"+ - "\4\u037e\2\0\1\u037e\15\0\1\u037e\6\0\12\u037e\1\u0302"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u037e\2\0\1\u037e\15\0"+ - "\1\u037e\6\0\12\u037e\1\u0302\13\0\1\u0273\74\0\1\u02be"+ - "\13\0\1\u0273\62\0\1\u037f\2\u0380\1\u037f\4\u0380\1\u0381"+ - "\1\u0380\43\0\1\u0347\110\0\1\u0347\33\0\2\u0348\1\0"+ - "\2\u0348\2\0\2\u0348\45\0\1\u0382\1\0\1\u0382\5\0"+ - "\1\u0382\156\0\1\u018f\32\0\4\u0383\2\0\1\u0383\15\0"+ - "\1\u0383\6\0\12\u0383\1\u0310\43\0\4\u0384\2\0\1\u0384"+ - "\15\0\1\u0384\6\0\12\u0384\1\u0385\43\0\4\u0386\2\0"+ - "\1\u0386\15\0\1\u0386\6\0\1\u0387\2\u0388\1\u0387\4\u0388"+ - "\1\u0389\1\u0388\14\0\1\u0230\27\0\4\u038a\2\0\1\u038a"+ - "\15\0\1\u038a\6\0\12\u038a\1\u0350\13\0\1\u0230\27\0"+ - "\4\u0386\2\0\1\u0386\15\0\1\u0386\6\0\1\u0387\2\u0388"+ - "\1\u0387\4\u0388\1\u0389\1\u0388\43\0\1\u0280\4\u038a\2\0"+ - "\1\u038a\15\0\1\u038a\6\0\12\u038b\1\u0350\13\0\1\u0230"+ - "\26\0\1\u0280\4\u038a\2\0\1\u038a\15\0\1\u038a\6\0"+ - "\12\u038a\1\u0350\13\0\1\u0230\26\0\1\u0280\4\u038a\2\0"+ - "\1\u038a\15\0\1\u038a\6\0\2\u038b\1\u038a\2\u038b\2\u038a"+ - "\2\u038b\1\u038a\1\u0350\13\0\1\u0230\74\0\1\u02ca\13\0"+ - "\1\u0230\26\0\1\u038c\33\0\12\u0356\43\0\1\u038c\33\0"+ - "\12\u038d\43\0\1\u038c\33\0\1\u0356\1\u038e\1\u038d\2\u0356"+ - "\2\u038d\2\u0356\1\u038d\43\0\46\u0197\1\0\2\u0197\1\u01e3"+ - "\3\u0197\1\u0199\1\371\1\372\1\373\2\0\2\u0197\4\0"+ - "\1\u0197\20\0\4\u038f\2\0\1\u038f\15\0\1\u038f\6\0"+ - "\12\u038f\1\u031e\43\0\4\u0390\2\0\1\u0390\15\0\1\u0390"+ - "\6\0\12\u0390\1\u0391\42\0\1\365\4\u0390\2\0\1\u0390"+ - "\15\0\1\u0390\6\0\12\u0392\1\u0391\42\0\1\365\4\u0390"+ - "\2\0\1\u0390\15\0\1\u0390\6\0\12\u0393\1\u0391\42\0"+ - "\1\365\4\u0390\2\0\1\u0390\15\0\1\u0390\6\0\1\u0392"+ - "\1\u0394\1\u0393\2\u0392\2\u0393\2\u0392\1\u0393\1\u0391\43\0"+ - "\4\u0395\2\0\1\u0395\15\0\1\u0395\6\0\12\u0395\14\0"+ - "\1\264\27\0\4\u0396\2\0\1\u0396\15\0\1\u0396\6\0"+ - "\12\u0396\1\u0360\13\0\1\264\27\0\4\u0395\2\0\1\u0395"+ - "\15\0\1\u0395\6\0\12\u0395\43\0\1\365\4\u0396\2\0"+ - "\1\u0396\15\0\1\u0396\6\0\12\u0397\1\u0360\13\0\1\264"+ - "\26\0\1\365\4\u0396\2\0\1\u0396\15\0\1\u0396\6\0"+ - "\12\u0396\1\u0360\13\0\1\264\26\0\1\365\4\u0396\2\0"+ - "\1\u0396\15\0\1\u0396\6\0\2\u0397\1\u0396\2\u0397\2\u0396"+ - "\2\u0397\1\u0396\1\u0360\13\0\1\264\74\0\1\u02d8\13\0"+ - "\1\264\26\0\1\172\32\63\1\173\10\63\1\u02e5\1\63"+ - "\43\0\1\172\1\u0398\31\63\1\173\12\63\43\0\1\172"+ - "\7\63\1\u0399\22\63\1\173\12\63\43\0\1\172\1\u039a"+ - "\31\63\1\173\12\63\43\0\1\172\25\63\1\u039b\4\63"+ - "\1\173\12\63\43\0\1\172\32\63\1\173\11\63\1\u039c"+ - "\43\0\1\172\1\u039d\31\63\1\173\12\63\43\0\1\172"+ - "\12\63\1\u039e\17\63\1\173\12\63\43\0\1\172\1\u039f"+ - "\31\63\1\173\12\63\43\0\1\172\10\63\1\u03a0\21\63"+ - "\1\173\12\63\43\0\1\172\31\63\1\u03a1\1\173\12\63"+ - "\43\0\1\221\2\117\1\u03a2\27\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\3\117\1\u03a3\26\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\32\117\1\36\1\117\1\u03a4"+ - "\10\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\3\117\1\u03a5\26\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\1\u03a6\31\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\26\117\1\u03a7"+ - "\3\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\17\0\4\u03a8\2\0"+ - "\1\u03a8\15\0\1\u03a8\6\0\12\u03a8\1\u033f\43\0\4\u03a9"+ - "\2\0\1\u03a9\15\0\1\u03a9\6\0\12\u03a9\1\u03aa\43\0"+ - "\4\u03ab\2\0\1\u03ab\15\0\1\u03ab\6\0\1\u03ac\2\u03ad"+ - "\1\u03ac\4\u03ad\1\u03ae\1\u03ad\14\0\1\u0273\27\0\4\u03af"+ - "\2\0\1\u03af\15\0\1\u03af\6\0\12\u03af\1\u037a\13\0"+ - "\1\u0273\27\0\4\u03ab\2\0\1\u03ab\15\0\1\u03ab\6\0"+ - "\1\u03ac\2\u03ad\1\u03ac\4\u03ad\1\u03ae\1\u03ad\43\0\1\u02bf"+ - "\4\u03af\2\0\1\u03af\15\0\1\u03af\6\0\12\u03b0\1\u037a"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u03af\2\0\1\u03af\15\0"+ - "\1\u03af\6\0\12\u03af\1\u037a\13\0\1\u0273\26\0\1\u02bf"+ - "\4\u03af\2\0\1\u03af\15\0\1\u03af\6\0\2\u03b0\1\u03af"+ - "\2\u03b0\2\u03af\2\u03b0\1\u03af\1\u037a\13\0\1\u0273\74\0"+ - "\1\u0302\13\0\1\u0273\26\0\1\u03b1\33\0\12\u0380\43\0"+ - "\1\u03b1\33\0\12\u03b2\43\0\1\u03b1\33\0\1\u0380\1\u03b3"+ - "\1\u03b2\2\u0380\2\u03b2\2\u0380\1\u03b2\123\0\1\373\76\0"+ - "\1\u0310\43\0\4\u03b4\2\0\1\u03b4\15\0\1\u03b4\6\0"+ - "\12\u03b4\1\u0385\43\0\4\u03b5\2\0\1\u03b5\15\0\1\u03b5"+ - "\6\0\12\u03b5\1\u03b6\43\0\4\u03b7\2\0\1\u03b7\15\0"+ - "\1\u03b7\6\0\12\u03b7\1\u03b8\13\0\1\u0230\26\0\1\u0280"+ - "\4\u03b7\2\0\1\u03b7\15\0\1\u03b7\6\0\12\u03b9\1\u03b8"+ - "\13\0\1\u0230\26\0\1\u0280\4\u03b7\2\0\1\u03b7\15\0"+ - "\1\u03b7\6\0\12\u03ba\1\u03b8\13\0\1\u0230\26\0\1\u0280"+ - "\4\u03b7\2\0\1\u03b7\15\0\1\u03b7\6\0\1\u03b9\1\u03bb"+ - "\1\u03ba\2\u03b9\2\u03ba\2\u03b9\1\u03ba\1\u03b8\13\0\1\u0230"+ - "\27\0\4\u03bc\2\0\1\u03bc\15\0\1\u03bc\6\0\12\u03bc"+ - "\1\u0350\13\0\1\u0230\26\0\1\u0280\4\u03bc\2\0\1\u03bc"+ - "\15\0\1\u03bc\6\0\12\u03bc\1\u0350\13\0\1\u0230\62\0"+ - "\1\u03bd\2\u03be\1\u03bd\4\u03be\1\u03bf\1\u03be\43\0\1\u038c"+ - "\110\0\1\u038c\33\0\2\u038d\1\0\2\u038d\2\0\2\u038d"+ - "\112\0\1\u031e\43\0\4\u03c0\2\0\1\u03c0\15\0\1\u03c0"+ - "\6\0\12\u03c0\1\u0391\43\0\4\u0395\2\0\1\u0395\15\0"+ - "\1\u0395\6\0\12\u0395\1\u028e\42\0\1\365\4\u03c0\2\0"+ - "\1\u03c0\15\0\1\u03c0\6\0\12\u03c1\1\u0391\42\0\1\365"+ - "\4\u03c0\2\0\1\u03c0\15\0\1\u03c0\6\0\12\u03c0\1\u0391"+ - "\42\0\1\365\4\u03c0\2\0\1\u03c0\15\0\1\u03c0\6\0"+ - "\2\u03c1\1\u03c0\2\u03c1\2\u03c0\2\u03c1\1\u03c0\1\u0391\43\0"+ - "\4\u03c2\2\0\1\u03c2\15\0\1\u03c2\6\0\12\u03c2\14\0"+ - "\1\264\27\0\4\u03c3\2\0\1\u03c3\15\0\1\u03c3\6\0"+ - "\12\u03c3\1\u0360\13\0\1\264\26\0\1\365\4\u03c3\2\0"+ - "\1\u03c3\15\0\1\u03c3\6\0\12\u03c3\1\u0360\13\0\1\264"+ - "\26\0\1\172\32\63\1\173\6\63\1\u02de\3\63\43\0"+ - "\1\172\15\63\1\301\14\63\1\173\12\63\43\0\1\172"+ - "\32\63\1\173\1\63\1\u03c4\10\63\43\0\1\172\30\63"+ - "\1\u03c5\1\63\1\173\12\63\43\0\1\172\6\63\1\u03c6"+ - "\23\63\1\173\12\63\43\0\1\172\32\63\1\173\5\63"+ - "\1\u03c7\4\63\43\0\1\172\22\63\1\374\7\63\1\173"+ - "\12\63\43\0\1\172\32\63\1\173\5\63\1\u03c8\4\63"+ - "\43\0\1\172\32\63\1\173\1\63\1\301\10\63\43\0"+ - "\1\172\13\63\1\u03c9\16\63\1\173\12\63\43\0\1\221"+ - "\32\117\1\36\7\117\1\u03ca\2\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\32\117\1\36\10\117\1\142\1\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\32\117\1\36\4\117\1\u03cb\5\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\16\117\1\u03cc\13\117\1\36\12\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\26\117\1\u03cd\3\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\16\0\1\221\32\117\1\36\7\117"+ - "\1\u03ce\2\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\64\0\1\u033f\43\0\4\u03cf"+ - "\2\0\1\u03cf\15\0\1\u03cf\6\0\12\u03cf\1\u03aa\43\0"+ - "\4\u03d0\2\0\1\u03d0\15\0\1\u03d0\6\0\12\u03d0\1\u03d1"+ - "\43\0\4\u03d2\2\0\1\u03d2\15\0\1\u03d2\6\0\12\u03d2"+ - "\1\u03d3\13\0\1\u0273\26\0\1\u02bf\4\u03d2\2\0\1\u03d2"+ - "\15\0\1\u03d2\6\0\12\u03d4\1\u03d3\13\0\1\u0273\26\0"+ - "\1\u02bf\4\u03d2\2\0\1\u03d2\15\0\1\u03d2\6\0\12\u03d5"+ - "\1\u03d3\13\0\1\u0273\26\0\1\u02bf\4\u03d2\2\0\1\u03d2"+ - "\15\0\1\u03d2\6\0\1\u03d4\1\u03d6\1\u03d5\2\u03d4\2\u03d5"+ - "\2\u03d4\1\u03d5\1\u03d3\13\0\1\u0273\27\0\4\u03d7\2\0"+ - "\1\u03d7\15\0\1\u03d7\6\0\12\u03d7\1\u037a\13\0\1\u0273"+ - "\26\0\1\u02bf\4\u03d7\2\0\1\u03d7\15\0\1\u03d7\6\0"+ - "\12\u03d7\1\u037a\13\0\1\u0273\62\0\1\u03d8\2\u03d9\1\u03d8"+ - "\4\u03d9\1\u03da\1\u03d9\43\0\1\u03b1\110\0\1\u03b1\33\0"+ - "\2\u03b2\1\0\2\u03b2\2\0\2\u03b2\45\0\4\u03db\2\0"+ - "\1\u03db\15\0\1\u03db\6\0\12\u03db\1\u0385\43\0\4\u03dc"+ - "\2\0\1\u03dc\15\0\1\u03dc\6\0\12\u03dc\1\u03dd\43\0"+ - "\4\u03de\2\0\1\u03de\15\0\1\u03de\6\0\1\u03df\2\u03e0"+ - "\1\u03df\4\u03e0\1\u03e1\1\u03e0\14\0\1\u0230\27\0\4\u03e2"+ - "\2\0\1\u03e2\15\0\1\u03e2\6\0\12\u03e2\1\u03b8\13\0"+ - "\1\u0230\27\0\4\u03de\2\0\1\u03de\15\0\1\u03de\6\0"+ - "\1\u03df\2\u03e0\1\u03df\4\u03e0\1\u03e1\1\u03e0\43\0\1\u0280"+ - "\4\u03e2\2\0\1\u03e2\15\0\1\u03e2\6\0\12\u03e3\1\u03b8"+ - "\13\0\1\u0230\26\0\1\u0280\4\u03e2\2\0\1\u03e2\15\0"+ - "\1\u03e2\6\0\12\u03e2\1\u03b8\13\0\1\u0230\26\0\1\u0280"+ - "\4\u03e2\2\0\1\u03e2\15\0\1\u03e2\6\0\2\u03e3\1\u03e2"+ - "\2\u03e3\2\u03e2\2\u03e3\1\u03e2\1\u03b8\13\0\1\u0230\74\0"+ - "\1\u0350\13\0\1\u0230\62\0\12\u03be\14\0\1\u0230\62\0"+ - "\12\u03e4\14\0\1\u0230\62\0\1\u03be\1\u03e5\1\u03e4\2\u03be"+ - "\2\u03e4\2\u03be\1\u03e4\14\0\1\u0230\27\0\4\u03e6\2\0"+ - "\1\u03e6\15\0\1\u03e6\6\0\12\u03e6\1\u0391\42\0\1\365"+ - "\4\u03e6\2\0\1\u03e6\15\0\1\u03e6\6\0\12\u03e6\1\u0391"+ - "\43\0\4\u03e7\2\0\1\u03e7\15\0\1\u03e7\6\0\12\u03e7"+ - "\14\0\1\264\74\0\1\u0360\13\0\1\264\26\0\1\172"+ - "\2\63\1\u03e8\27\63\1\173\12\63\43\0\1\172\3\63"+ - "\1\u03e9\26\63\1\173\12\63\43\0\1\172\32\63\1\173"+ - "\1\63\1\u03ea\10\63\43\0\1\172\3\63\1\u03eb\26\63"+ - "\1\173\12\63\43\0\1\172\1\u03ec\31\63\1\173\12\63"+ - "\43\0\1\172\26\63\1\u03ed\3\63\1\173\12\63\43\0"+ - "\1\221\1\u03ee\31\117\1\36\12\117\1\0\3\33\1\0"+ - "\2\33\1\34\3\33\3\0\1\33\4\0\2\33\16\0"+ - "\1\221\24\117\1\u03ef\5\117\1\36\12\117\1\0\3\33"+ - "\1\0\2\33\1\34\3\33\3\0\1\33\4\0\2\33"+ - "\16\0\1\221\1\117\1\u03f0\30\117\1\36\12\117\1\0"+ - "\3\33\1\0\2\33\1\34\3\33\3\0\1\33\4\0"+ - "\2\33\16\0\1\221\32\117\1\36\2\117\1\235\7\117"+ - "\1\0\3\33\1\0\2\33\1\34\3\33\3\0\1\33"+ - "\4\0\2\33\16\0\1\221\6\117\1\226\23\117\1\36"+ - "\12\117\1\0\3\33\1\0\2\33\1\34\3\33\3\0"+ - "\1\33\4\0\2\33\17\0\4\u03f1\2\0\1\u03f1\15\0"+ - "\1\u03f1\6\0\12\u03f1\1\u03aa\43\0\4\u03f2\2\0\1\u03f2"+ - "\15\0\1\u03f2\6\0\12\u03f2\1\u03f3\43\0\4\u03f4\2\0"+ - "\1\u03f4\15\0\1\u03f4\6\0\1\u03f5\2\u03f6\1\u03f5\4\u03f6"+ - "\1\u03f7\1\u03f6\14\0\1\u0273\27\0\4\u03f8\2\0\1\u03f8"+ - "\15\0\1\u03f8\6\0\12\u03f8\1\u03d3\13\0\1\u0273\27\0"+ - "\4\u03f4\2\0\1\u03f4\15\0\1\u03f4\6\0\1\u03f5\2\u03f6"+ - "\1\u03f5\4\u03f6\1\u03f7\1\u03f6\43\0\1\u02bf\4\u03f8\2\0"+ - "\1\u03f8\15\0\1\u03f8\6\0\12\u03f9\1\u03d3\13\0\1\u0273"+ - "\26\0\1\u02bf\4\u03f8\2\0\1\u03f8\15\0\1\u03f8\6\0"+ - "\12\u03f8\1\u03d3\13\0\1\u0273\26\0\1\u02bf\4\u03f8\2\0"+ - "\1\u03f8\15\0\1\u03f8\6\0\2\u03f9\1\u03f8\2\u03f9\2\u03f8"+ - "\2\u03f9\1\u03f8\1\u03d3\13\0\1\u0273\74\0\1\u037a\13\0"+ - "\1\u0273\62\0\12\u03d9\14\0\1\u0273\62\0\12\u03fa\14\0"+ - "\1\u0273\62\0\1\u03d9\1\u03fb\1\u03fa\2\u03d9\2\u03fa\2\u03d9"+ - "\1\u03fa\14\0\1\u0273\74\0\1\u0385\43\0\4\u03fc\2\0"+ - "\1\u03fc\15\0\1\u03fc\6\0\12\u03fc\1\u03dd\43\0\4\u03fd"+ - "\2\0\1\u03fd\15\0\1\u03fd\6\0\12\u03fd\1\u03fe\43\0"+ - "\4\u03ff\2\0\1\u03ff\15\0\1\u03ff\6\0\12\u03ff\1\u0400"+ - "\13\0\1\u0230\26\0\1\u0280\4\u03ff\2\0\1\u03ff\15\0"+ - "\1\u03ff\6\0\12\u0401\1\u0400\13\0\1\u0230\26\0\1\u0280"+ - "\4\u03ff\2\0\1\u03ff\15\0\1\u03ff\6\0\12\u0402\1\u0400"+ - "\13\0\1\u0230\26\0\1\u0280\4\u03ff\2\0\1\u03ff\15\0"+ - "\1\u03ff\6\0\1\u0401\1\u0403\1\u0402\2\u0401\2\u0402\2\u0401"+ - "\1\u0402\1\u0400\13\0\1\u0230\27\0\4\u0404\2\0\1\u0404"+ - "\15\0\1\u0404\6\0\12\u0404\1\u03b8\13\0\1\u0230\26\0"+ - "\1\u0280\4\u0404\2\0\1\u0404\15\0\1\u0404\6\0\12\u0404"+ - "\1\u03b8\13\0\1\u0230\110\0\1\u0230\62\0\2\u03e4\1\0"+ - "\2\u03e4\2\0\2\u03e4\15\0\1\u0230\74\0\1\u0391\43\0"+ - "\4\u028e\2\0\1\u028e\15\0\1\u028e\6\0\12\u028e\14\0"+ - "\1\264\26\0\1\172\32\63\1\173\7\63\1\u0405\2\63"+ - "\43\0\1\172\32\63\1\173\10\63\1\301\1\63\43\0"+ - "\1\172\32\63\1\173\4\63\1\u0406\5\63\43\0\1\172"+ - "\16\63\1\u0407\13\63\1\173\12\63\43\0\1\172\26\63"+ - "\1\u0408\3\63\1\173\12\63\43\0\1\172\32\63\1\173"+ - "\7\63\1\u0409\2\63\43\0\1\221\4\117\1\226\25\117"+ - "\1\36\12\117\1\0\3\33\1\0\2\33\1\34\3\33"+ - "\3\0\1\33\4\0\2\33\16\0\1\221\24\117\1\142"+ - "\5\117\1\36\12\117\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\16\0\1\221\32\117"+ - "\1\36\11\117\1\142\1\0\3\33\1\0\2\33\1\34"+ - "\3\33\3\0\1\33\4\0\2\33\64\0\1\u03aa\43\0"+ - "\4\u040a\2\0\1\u040a\15\0\1\u040a\6\0\12\u040a\1\u03f3"+ - "\43\0\4\u040b\2\0\1\u040b\15\0\1\u040b\6\0\12\u040b"+ - "\1\u040c\43\0\4\u040d\2\0\1\u040d\15\0\1\u040d\6\0"+ - "\12\u040d\1\u040e\13\0\1\u0273\26\0\1\u02bf\4\u040d\2\0"+ - "\1\u040d\15\0\1\u040d\6\0\12\u040f\1\u040e\13\0\1\u0273"+ - "\26\0\1\u02bf\4\u040d\2\0\1\u040d\15\0\1\u040d\6\0"+ - "\12\u0410\1\u040e\13\0\1\u0273\26\0\1\u02bf\4\u040d\2\0"+ - "\1\u040d\15\0\1\u040d\6\0\1\u040f\1\u0411\1\u0410\2\u040f"+ - "\2\u0410\2\u040f\1\u0410\1\u040e\13\0\1\u0273\27\0\4\u0412"+ - "\2\0\1\u0412\15\0\1\u0412\6\0\12\u0412\1\u03d3\13\0"+ - "\1\u0273\26\0\1\u02bf\4\u0412\2\0\1\u0412\15\0\1\u0412"+ - "\6\0\12\u0412\1\u03d3\13\0\1\u0273\110\0\1\u0273\62\0"+ - "\2\u03fa\1\0\2\u03fa\2\0\2\u03fa\15\0\1\u0273\27\0"+ - "\4\u0413\2\0\1\u0413\15\0\1\u0413\6\0\12\u0413\1\u03dd"+ - "\43\0\4\u0414\2\0\1\u0414\15\0\1\u0414\6\0\12\u0414"+ - "\1\u0415\43\0\4\u0416\2\0\1\u0416\15\0\1\u0416\6\0"+ - "\1\u0417\2\u0418\1\u0417\4\u0418\1\u0419\1\u0418\14\0\1\u0230"+ - "\27\0\4\u041a\2\0\1\u041a\15\0\1\u041a\6\0\12\u041a"+ - "\1\u0400\13\0\1\u0230\27\0\4\u0416\2\0\1\u0416\15\0"+ - "\1\u0416\6\0\1\u0417\2\u0418\1\u0417\4\u0418\1\u0419\1\u0418"+ - "\43\0\1\u0280\4\u041a\2\0\1\u041a\15\0\1\u041a\6\0"+ - "\12\u041b\1\u0400\13\0\1\u0230\26\0\1\u0280\4\u041a\2\0"+ - "\1\u041a\15\0\1\u041a\6\0\12\u041a\1\u0400\13\0\1\u0230"+ - "\26\0\1\u0280\4\u041a\2\0\1\u041a\15\0\1\u041a\6\0"+ - "\2\u041b\1\u041a\2\u041b\2\u041a\2\u041b\1\u041a\1\u0400\13\0"+ - "\1\u0230\74\0\1\u03b8\13\0\1\u0230\26\0\1\172\1\u041c"+ - "\31\63\1\173\12\63\43\0\1\172\24\63\1\u041d\5\63"+ - "\1\173\12\63\43\0\1\172\1\63\1\u041e\30\63\1\173"+ - "\12\63\43\0\1\172\32\63\1\173\2\63\1\u0103\7\63"+ - "\43\0\1\172\6\63\1\374\23\63\1\173\12\63\44\0"+ - "\4\u041f\2\0\1\u041f\15\0\1\u041f\6\0\12\u041f\1\u03f3"+ - "\43\0\4\u0420\2\0\1\u0420\15\0\1\u0420\6\0\12\u0420"+ - "\1\u0421\43\0\4\u0422\2\0\1\u0422\15\0\1\u0422\6\0"+ - "\1\u0423\2\u0424\1\u0423\4\u0424\1\u0425\1\u0424\14\0\1\u0273"+ - "\27\0\4\u0426\2\0\1\u0426\15\0\1\u0426\6\0\12\u0426"+ - "\1\u040e\13\0\1\u0273\27\0\4\u0422\2\0\1\u0422\15\0"+ - "\1\u0422\6\0\1\u0423\2\u0424\1\u0423\4\u0424\1\u0425\1\u0424"+ - "\43\0\1\u02bf\4\u0426\2\0\1\u0426\15\0\1\u0426\6\0"+ - "\12\u0427\1\u040e\13\0\1\u0273\26\0\1\u02bf\4\u0426\2\0"+ - "\1\u0426\15\0\1\u0426\6\0\12\u0426\1\u040e\13\0\1\u0273"+ - "\26\0\1\u02bf\4\u0426\2\0\1\u0426\15\0\1\u0426\6\0"+ - "\2\u0427\1\u0426\2\u0427\2\u0426\2\u0427\1\u0426\1\u040e\13\0"+ - "\1\u0273\74\0\1\u03d3\13\0\1\u0273\74\0\1\u03dd\43\0"+ - "\4\u0428\2\0\1\u0428\15\0\1\u0428\6\0\12\u0428\1\u0415"+ - "\43\0\4\u0429\2\0\1\u0429\15\0\1\u0429\6\0\1\u042a"+ - "\2\u042b\1\u042a\4\u042b\1\u042c\1\u042b\1\u042d\43\0\4\u042e"+ - "\2\0\1\u042e\15\0\1\u042e\6\0\12\u042e\1\u042f\13\0"+ - "\1\u0230\26\0\1\u0280\4\u042e\2\0\1\u042e\15\0\1\u042e"+ - "\6\0\12\u0430\1\u042f\13\0\1\u0230\26\0\1\u0280\4\u042e"+ - "\2\0\1\u042e\15\0\1\u042e\6\0\12\u0431\1\u042f\13\0"+ - "\1\u0230\26\0\1\u0280\4\u042e\2\0\1\u042e\15\0\1\u042e"+ - "\6\0\1\u0430\1\u0432\1\u0431\2\u0430\2\u0431\2\u0430\1\u0431"+ - "\1\u042f\13\0\1\u0230\27\0\4\u0433\2\0\1\u0433\15\0"+ - "\1\u0433\6\0\12\u0433\1\u0400\13\0\1\u0230\26\0\1\u0280"+ - "\4\u0433\2\0\1\u0433\15\0\1\u0433\6\0\12\u0433\1\u0400"+ - "\13\0\1\u0230\26\0\1\172\4\63\1\374\25\63\1\173"+ - "\12\63\43\0\1\172\24\63\1\301\5\63\1\173\12\63"+ - "\43\0\1\172\32\63\1\173\11\63\1\301\111\0\1\u03f3"+ - "\43\0\4\u0434\2\0\1\u0434\15\0\1\u0434\6\0\12\u0434"+ - "\1\u0421\43\0\4\u0435\2\0\1\u0435\15\0\1\u0435\6\0"+ - "\1\u0436\2\u0437\1\u0436\4\u0437\1\u0438\1\u0437\1\u0439\43\0"+ - "\4\u043a\2\0\1\u043a\15\0\1\u043a\6\0\12\u043a\1\u043b"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u043a\2\0\1\u043a\15\0"+ - "\1\u043a\6\0\12\u043c\1\u043b\13\0\1\u0273\26\0\1\u02bf"+ - "\4\u043a\2\0\1\u043a\15\0\1\u043a\6\0\12\u043d\1\u043b"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u043a\2\0\1\u043a\15\0"+ - "\1\u043a\6\0\1\u043c\1\u043e\1\u043d\2\u043c\2\u043d\2\u043c"+ - "\1\u043d\1\u043b\13\0\1\u0273\27\0\4\u043f\2\0\1\u043f"+ - "\15\0\1\u043f\6\0\12\u043f\1\u040e\13\0\1\u0273\26\0"+ - "\1\u02bf\4\u043f\2\0\1\u043f\15\0\1\u043f\6\0\12\u043f"+ - "\1\u040e\13\0\1\u0273\27\0\4\u0440\2\0\1\u0440\15\0"+ - "\1\u0440\6\0\12\u0440\1\u0415\43\0\4\u0441\2\0\1\u0441"+ - "\15\0\1\u0441\6\0\12\u0441\1\u0442\42\0\1\u0280\4\u0441"+ - "\2\0\1\u0441\15\0\1\u0441\6\0\12\u0443\1\u0442\42\0"+ - "\1\u0280\4\u0441\2\0\1\u0441\15\0\1\u0441\6\0\12\u0444"+ - "\1\u0442\42\0\1\u0280\4\u0441\2\0\1\u0441\15\0\1\u0441"+ - "\6\0\1\u0443\1\u0445\1\u0444\2\u0443\2\u0444\2\u0443\1\u0444"+ - "\1\u0442\43\0\4\u0446\2\0\1\u0446\15\0\1\u0446\6\0"+ - "\12\u0446\14\0\1\u0230\27\0\4\u0447\2\0\1\u0447\15\0"+ - "\1\u0447\6\0\12\u0447\1\u042f\13\0\1\u0230\27\0\4\u0446"+ - "\2\0\1\u0446\15\0\1\u0446\6\0\12\u0446\43\0\1\u0280"+ - "\4\u0447\2\0\1\u0447\15\0\1\u0447\6\0\12\u0448\1\u042f"+ - "\13\0\1\u0230\26\0\1\u0280\4\u0447\2\0\1\u0447\15\0"+ - "\1\u0447\6\0\12\u0447\1\u042f\13\0\1\u0230\26\0\1\u0280"+ - "\4\u0447\2\0\1\u0447\15\0\1\u0447\6\0\2\u0448\1\u0447"+ - "\2\u0448\2\u0447\2\u0448\1\u0447\1\u042f\13\0\1\u0230\74\0"+ - "\1\u0400\13\0\1\u0230\27\0\4\u0449\2\0\1\u0449\15\0"+ - "\1\u0449\6\0\12\u0449\1\u0421\43\0\4\u044a\2\0\1\u044a"+ - "\15\0\1\u044a\6\0\12\u044a\1\u044b\42\0\1\u02bf\4\u044a"+ - "\2\0\1\u044a\15\0\1\u044a\6\0\12\u044c\1\u044b\42\0"+ - "\1\u02bf\4\u044a\2\0\1\u044a\15\0\1\u044a\6\0\12\u044d"+ - "\1\u044b\42\0\1\u02bf\4\u044a\2\0\1\u044a\15\0\1\u044a"+ - "\6\0\1\u044c\1\u044e\1\u044d\2\u044c\2\u044d\2\u044c\1\u044d"+ - "\1\u044b\43\0\4\u044f\2\0\1\u044f\15\0\1\u044f\6\0"+ - "\12\u044f\14\0\1\u0273\27\0\4\u0450\2\0\1\u0450\15\0"+ - "\1\u0450\6\0\12\u0450\1\u043b\13\0\1\u0273\27\0\4\u044f"+ - "\2\0\1\u044f\15\0\1\u044f\6\0\12\u044f\43\0\1\u02bf"+ - "\4\u0450\2\0\1\u0450\15\0\1\u0450\6\0\12\u0451\1\u043b"+ - "\13\0\1\u0273\26\0\1\u02bf\4\u0450\2\0\1\u0450\15\0"+ - "\1\u0450\6\0\12\u0450\1\u043b\13\0\1\u0273\26\0\1\u02bf"+ - "\4\u0450\2\0\1\u0450\15\0\1\u0450\6\0\2\u0451\1\u0450"+ - "\2\u0451\2\u0450\2\u0451\1\u0450\1\u043b\13\0\1\u0273\74\0"+ - "\1\u040e\13\0\1\u0273\74\0\1\u0415\43\0\4\u0452\2\0"+ - "\1\u0452\15\0\1\u0452\6\0\12\u0452\1\u0442\43\0\4\u0446"+ - "\2\0\1\u0446\15\0\1\u0446\6\0\12\u0446\1\u03e4\42\0"+ - "\1\u0280\4\u0452\2\0\1\u0452\15\0\1\u0452\6\0\12\u0453"+ - "\1\u0442\42\0\1\u0280\4\u0452\2\0\1\u0452\15\0\1\u0452"+ - "\6\0\12\u0452\1\u0442\42\0\1\u0280\4\u0452\2\0\1\u0452"+ - "\15\0\1\u0452\6\0\2\u0453\1\u0452\2\u0453\2\u0452\2\u0453"+ - "\1\u0452\1\u0442\43\0\4\u0454\2\0\1\u0454\15\0\1\u0454"+ - "\6\0\12\u0454\14\0\1\u0230\27\0\4\u0455\2\0\1\u0455"+ - "\15\0\1\u0455\6\0\12\u0455\1\u042f\13\0\1\u0230\26\0"+ - "\1\u0280\4\u0455\2\0\1\u0455\15\0\1\u0455\6\0\12\u0455"+ - "\1\u042f\13\0\1\u0230\74\0\1\u0421\43\0\4\u0456\2\0"+ - "\1\u0456\15\0\1\u0456\6\0\12\u0456\1\u044b\43\0\4\u044f"+ - "\2\0\1\u044f\15\0\1\u044f\6\0\12\u044f\1\u03fa\42\0"+ - "\1\u02bf\4\u0456\2\0\1\u0456\15\0\1\u0456\6\0\12\u0457"+ - "\1\u044b\42\0\1\u02bf\4\u0456\2\0\1\u0456\15\0\1\u0456"+ - "\6\0\12\u0456\1\u044b\42\0\1\u02bf\4\u0456\2\0\1\u0456"+ - "\15\0\1\u0456\6\0\2\u0457\1\u0456\2\u0457\2\u0456\2\u0457"+ - "\1\u0456\1\u044b\43\0\4\u0458\2\0\1\u0458\15\0\1\u0458"+ - "\6\0\12\u0458\14\0\1\u0273\27\0\4\u0459\2\0\1\u0459"+ - "\15\0\1\u0459\6\0\12\u0459\1\u043b\13\0\1\u0273\26\0"+ - "\1\u02bf\4\u0459\2\0\1\u0459\15\0\1\u0459\6\0\12\u0459"+ - "\1\u043b\13\0\1\u0273\27\0\4\u045a\2\0\1\u045a\15\0"+ - "\1\u045a\6\0\12\u045a\1\u0442\42\0\1\u0280\4\u045a\2\0"+ - "\1\u045a\15\0\1\u045a\6\0\12\u045a\1\u0442\43\0\4\u045b"+ - "\2\0\1\u045b\15\0\1\u045b\6\0\12\u045b\14\0\1\u0230"+ - "\74\0\1\u042f\13\0\1\u0230\27\0\4\u045c\2\0\1\u045c"+ - "\15\0\1\u045c\6\0\12\u045c\1\u044b\42\0\1\u02bf\4\u045c"+ - "\2\0\1\u045c\15\0\1\u045c\6\0\12\u045c\1\u044b\43\0"+ - "\4\u045d\2\0\1\u045d\15\0\1\u045d\6\0\12\u045d\14\0"+ - "\1\u0273\74\0\1\u043b\13\0\1\u0273\74\0\1\u0442\43\0"+ - "\4\u03e4\2\0\1\u03e4\15\0\1\u03e4\6\0\12\u03e4\14\0"+ - "\1\u0230\74\0\1\u044b\43\0\4\u03fa\2\0\1\u03fa\15\0"+ - "\1\u03fa\6\0\12\u03fa\14\0\1\u0273\15\0"; + "\1\2\1\3\1\2\1\4\1\2\1\5\1\2\1\6"+ + "\1\2\1\7\1\2\1\10\3\2\1\11\5\2\1\12"+ + "\3\2\1\13\11\2\1\14\2\2\1\15\43\2\1\16"+ + "\1\2\1\17\3\2\1\20\1\21\1\2\1\22\1\2"+ + "\1\23\2\2\1\24\1\2\1\25\1\2\1\26\1\27"+ + "\3\2\1\30\2\31\1\32\1\33\1\34\6\35\1\36"+ + "\16\35\1\37\4\35\1\34\1\40\2\41\1\40\4\41"+ + "\1\42\1\41\1\2\1\34\1\43\1\34\1\2\2\34"+ + "\1\2\3\34\1\44\2\2\1\34\1\45\3\2\2\34"+ + "\1\2\244\0\1\25\11\0\1\25\20\0\1\25\22\0"+ + "\1\25\10\0\3\25\17\0\1\25\10\0\1\25\117\0"+ + "\1\25\1\0\1\25\1\0\1\25\1\0\1\25\1\0"+ + "\1\25\1\0\3\25\1\0\5\25\1\0\3\25\1\0"+ + "\11\25\1\0\2\25\1\0\16\25\1\0\2\25\1\0"+ + "\21\25\1\0\1\25\1\0\3\25\2\0\1\25\1\0"+ + "\1\25\1\0\2\25\1\0\1\25\112\0\1\25\3\0"+ + "\1\25\5\0\2\25\3\0\1\25\13\0\1\25\1\0"+ + "\1\25\4\0\2\25\4\0\1\25\1\0\1\25\3\0"+ + "\2\25\1\0\1\25\5\0\3\25\1\0\1\25\15\0"+ + "\1\25\10\0\1\25\117\0\1\25\3\0\1\25\1\0"+ + "\1\25\1\0\1\25\1\0\3\25\2\0\4\25\1\0"+ + "\3\25\2\0\3\25\1\0\4\25\1\0\2\25\2\0"+ + "\3\25\1\0\11\25\1\0\2\25\1\0\16\25\1\0"+ + "\2\25\1\0\1\25\1\0\3\25\2\0\1\25\1\0"+ + "\1\25\1\0\2\25\1\0\1\25\112\0\1\25\3\0"+ + "\1\25\3\0\1\25\1\0\3\25\2\0\1\25\1\0"+ + "\2\25\1\0\3\25\3\0\2\25\1\0\1\25\1\0"+ + "\2\25\1\0\2\25\3\0\2\25\1\0\1\25\1\0"+ + "\1\25\1\0\2\25\1\0\2\25\1\0\2\25\1\0"+ + "\5\25\1\0\5\25\1\0\2\25\1\0\2\25\1\0"+ + "\1\25\1\0\3\25\4\0\1\25\4\0\1\25\124\0"+ + "\3\25\5\0\1\25\1\0\1\25\1\0\1\25\4\0"+ + "\1\25\14\0\1\25\5\0\1\25\11\0\2\25\12\0"+ + "\1\26\1\0\2\25\12\0\1\25\117\0\1\25\1\0"+ + "\1\26\7\0\2\25\2\0\5\25\2\0\2\25\4\0"+ + "\6\25\1\0\2\25\4\0\5\25\1\0\5\25\1\0"+ + "\2\25\1\0\3\25\1\0\4\25\1\0\5\25\1\26"+ + "\1\0\1\25\1\0\1\25\1\0\3\25\2\0\1\25"+ + "\1\0\1\25\1\0\1\25\2\0\1\25\112\0\1\25"+ + "\3\0\1\25\5\0\2\25\3\0\1\25\4\0\3\25"+ + "\4\0\1\25\1\0\1\25\2\0\1\25\1\0\2\25"+ + "\4\0\1\25\1\0\1\25\3\0\2\25\1\0\1\25"+ + "\5\0\3\25\1\0\1\25\10\0\1\25\1\0\2\26"+ + "\1\0\1\25\10\0\1\25\117\0\1\25\3\0\1\25"+ + "\6\0\2\25\5\0\1\25\1\0\1\25\1\0\1\25"+ + "\1\0\11\25\2\0\1\25\4\0\1\25\4\0\6\25"+ + "\2\0\1\25\1\0\1\25\1\0\3\25\3\0\2\25"+ + "\4\0\3\25\1\0\1\25\10\0\1\25\1\0\2\25"+ + "\114\0\1\25\11\0\2\25\17\0\1\25\6\0\2\25"+ + "\4\0\1\25\5\0\1\25\2\0\1\25\5\0\3\25"+ + "\1\0\1\25\15\0\1\25\10\0\1\25\117\0\1\25"+ + "\3\0\1\25\5\0\1\25\32\0\15\25\5\0\3\25"+ + "\1\0\1\25\5\0\1\25\7\0\1\25\2\0\1\25"+ + "\5\0\1\25\2\0\1\25\1\0\1\25\201\0\1\33"+ + "\21\0\1\27\130\0\1\32\3\0\1\32\3\0\1\32"+ + "\1\0\3\32\2\0\1\32\2\0\1\32\1\0\3\32"+ + "\3\0\2\32\1\0\1\32\1\0\2\32\1\0\2\32"+ + "\3\0\2\32\1\0\1\32\3\0\2\32\1\0\2\32"+ + "\1\0\2\32\1\0\5\32\1\0\5\32\2\0\1\32"+ + "\1\0\2\32\1\0\1\32\1\0\3\32\4\0\1\32"+ + "\4\0\1\32\112\0\1\32\1\0\1\32\1\0\1\32"+ + "\1\0\1\32\1\0\1\32\1\0\3\32\1\0\5\32"+ + "\1\0\3\32\1\0\11\32\1\0\2\32\1\0\16\32"+ + "\1\0\2\32\1\0\21\32\1\0\1\32\1\0\3\32"+ + "\2\0\1\32\1\0\1\32\1\0\2\32\1\0\1\32"+ + "\112\0\1\32\1\0\1\32\1\0\1\32\3\0\1\32"+ + "\1\0\3\32\1\0\2\32\1\0\2\32\1\0\3\32"+ + "\1\0\11\32\1\0\2\32\1\0\16\32\1\0\2\32"+ + "\1\0\21\32\1\0\1\32\1\0\3\32\2\0\1\32"+ + "\1\0\1\32\1\0\2\32\1\0\1\32\112\0\1\32"+ + "\11\0\1\32\20\0\1\32\33\0\1\32\21\0\1\32"+ + "\10\0\1\32\117\0\1\32\1\0\1\32\1\0\1\32"+ + "\1\0\1\32\1\0\1\32\1\0\3\32\1\0\5\32"+ + "\1\0\3\32\1\0\6\32\1\0\2\32\1\0\2\32"+ + "\1\0\10\32\1\0\5\32\1\0\2\32\1\0\21\32"+ + "\1\0\1\32\1\0\3\32\2\0\1\32\1\0\1\32"+ + "\1\0\2\32\1\0\1\32\241\0\1\33\111\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\64\32\25\1\0\12\63\1\64"+ + "\1\0\1\65\3\0\1\64\20\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\66"+ + "\3\0\1\67\5\0\1\70\3\0\1\71\11\0\1\57"+ + "\2\0\1\72\16\0\1\73\2\0\1\74\41\0\1\25"+ + "\2\26\2\0\2\75\1\76\1\0\1\26\2\0\1\75"+ + "\32\25\1\0\12\26\2\0\1\76\2\0\2\75\6\0"+ + "\1\75\23\0\1\77\15\0\1\100\14\0\1\101\16\0"+ + "\1\102\2\0\1\103\21\0\1\104\20\0\1\27\1\0"+ + "\1\27\3\0\1\65\1\0\1\27\52\0\1\65\24\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\105\3\0\1\67\5\0\1\70\3\0"+ + "\1\106\11\0\1\57\2\0\1\107\16\0\1\110\2\0"+ + "\1\111\21\0\1\104\17\0\1\25\1\112\1\26\1\27"+ + "\3\0\1\112\1\0\1\112\3\0\32\25\1\0\12\26"+ + "\2\0\1\112\165\0\2\31\244\0\1\113\45\114\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\53\3\0\1\54\5\0"+ + "\1\55\3\0\1\56\11\0\1\57\2\0\1\60\16\0"+ + "\1\61\2\0\1\62\41\0\2\25\1\63\1\0\1\64"+ + "\1\0\1\64\1\65\1\0\1\25\2\0\1\116\32\35"+ + "\1\117\12\120\1\64\1\114\1\121\1\114\1\0\1\114"+ + "\1\122\1\115\3\114\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\53\3\0\1\54\5\0\1\55\3\0"+ + "\1\56\11\0\1\57\2\0\1\60\16\0\1\61\2\0"+ + "\1\62\41\0\2\25\1\63\1\0\1\64\1\0\1\64"+ + "\1\65\1\0\1\25\2\0\1\116\10\35\1\123\6\35"+ + "\1\124\12\35\1\117\12\120\1\64\1\114\1\121\1\114"+ + "\1\0\1\114\1\122\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\53\3\0\1\54\5\0"+ + "\1\55\3\0\1\56\11\0\1\57\2\0\1\60\16\0"+ + "\1\61\2\0\1\62\41\0\2\25\1\63\1\0\1\64"+ + "\1\0\1\64\1\65\1\0\1\25\2\0\1\116\17\35"+ + "\1\125\12\35\1\117\12\120\1\64\1\114\1\121\1\114"+ + "\1\0\1\114\1\122\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\66\3\0\1\67\5\0"+ + "\1\70\3\0\1\71\11\0\1\57\2\0\1\72\16\0"+ + "\1\73\2\0\1\74\41\0\1\25\2\26\2\0\2\75"+ + "\1\76\1\0\1\26\2\0\1\126\32\35\1\117\12\41"+ + "\1\0\1\114\1\127\1\114\1\0\2\130\1\115\3\114"+ + "\2\0\1\75\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\66\3\0\1\67\5\0\1\70\3\0\1\71\11\0"+ + "\1\57\2\0\1\72\16\0\1\73\2\0\1\74\41\0"+ + "\1\25\2\26\2\0\2\75\1\76\1\0\1\26\2\0"+ + "\1\126\32\35\1\117\12\131\1\0\1\114\1\127\1\114"+ + "\1\0\2\130\1\115\3\114\2\0\1\75\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\66\3\0\1\67\5\0"+ + "\1\70\3\0\1\71\11\0\1\57\2\0\1\72\16\0"+ + "\1\73\2\0\1\74\41\0\1\25\2\26\2\0\2\75"+ + "\1\76\1\0\1\26\2\0\1\126\32\35\1\117\1\41"+ + "\1\132\1\131\2\41\2\131\2\41\1\131\1\0\1\114"+ + "\1\127\1\114\1\0\2\130\1\115\3\114\2\0\1\75"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\105\3\0"+ + "\1\67\5\0\1\70\3\0\1\106\11\0\1\57\2\0"+ + "\1\107\16\0\1\110\2\0\1\111\21\0\1\104\17\0"+ + "\1\25\1\112\1\26\1\27\3\0\1\112\1\0\1\112"+ + "\2\0\1\113\32\133\1\114\12\134\1\0\1\114\1\135"+ + "\1\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\150\0\4\136\2\0\1\136\15\0\1\136\6\0"+ + "\12\136\1\137\173\0\65\140\1\141\1\140\1\142\1\0"+ + "\2\140\3\0\1\25\11\0\3\25\5\0\1\25\1\0"+ + "\1\25\1\0\1\25\4\0\1\25\4\0\1\25\1\0"+ + "\2\25\4\0\1\25\5\0\1\25\3\0\1\25\4\0"+ + "\5\25\10\0\1\63\1\0\2\25\1\0\1\25\10\0"+ + "\1\25\117\0\1\25\1\0\1\63\7\0\2\25\2\0"+ + "\5\25\2\0\2\25\4\0\6\25\1\0\2\25\4\0"+ + "\5\25\1\0\5\25\1\0\2\25\1\0\3\25\1\0"+ + "\4\25\1\0\5\25\1\63\1\0\1\25\1\0\1\25"+ + "\1\0\3\25\2\0\1\25\1\0\1\25\1\0\1\25"+ + "\2\0\1\25\112\0\1\25\3\0\1\25\5\0\2\25"+ + "\3\0\1\25\4\0\3\25\4\0\1\25\1\0\1\25"+ + "\2\0\1\25\1\0\2\25\4\0\1\25\1\0\1\25"+ + "\3\0\2\25\1\0\1\25\5\0\3\25\1\0\1\25"+ + "\10\0\1\25\1\0\2\63\1\0\1\25\10\0\1\25"+ + "\117\0\1\25\3\0\1\25\6\0\2\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\1\0\11\25\2\0\1\25"+ + "\4\0\1\25\4\0\6\25\2\0\1\25\1\0\1\25"+ + "\1\0\3\25\1\0\1\25\1\0\2\25\4\0\3\25"+ + "\1\0\1\25\10\0\1\25\1\0\2\25\114\0\1\25"+ + "\3\0\1\25\5\0\1\25\32\0\15\25\5\0\3\25"+ + "\1\0\1\25\5\0\3\25\5\0\1\25\2\0\2\25"+ + "\4\0\1\25\2\0\1\25\1\0\1\25\176\0\2\25"+ + "\6\0\1\25\151\0\1\25\3\0\1\25\2\0\1\25"+ + "\3\0\1\25\5\0\1\25\7\0\1\25\4\0\2\25"+ + "\3\0\2\25\1\0\1\25\4\0\1\25\1\0\1\25"+ + "\2\0\2\25\1\0\3\25\1\0\1\25\2\0\4\25"+ + "\2\0\1\25\134\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\143\3\0\1\54"+ + "\5\0\1\55\3\0\1\144\11\0\1\57\2\0\1\145"+ + "\16\0\1\146\2\0\1\147\41\0\1\25\2\63\2\0"+ + "\2\150\1\65\1\0\1\63\2\0\1\150\32\25\1\0"+ + "\12\63\2\0\1\65\2\0\2\150\6\0\1\150\11\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\151\3\0\1\152\5\0\1\153\3\0"+ + "\1\154\11\0\1\57\2\0\1\155\16\0\1\156\2\0"+ + "\1\157\41\0\1\25\1\64\7\0\1\64\3\0\32\25"+ + "\42\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\160\3\0\1\54\5\0\1\55"+ + "\3\0\1\161\11\0\1\57\2\0\1\162\16\0\1\163"+ + "\2\0\1\164\21\0\1\104\17\0\1\25\1\65\1\63"+ + "\1\27\3\0\1\65\1\0\1\65\3\0\32\25\1\0"+ + "\12\63\2\0\1\65\25\0\1\26\11\0\3\25\5\0"+ + "\1\25\1\0\1\25\1\0\1\25\4\0\1\25\4\0"+ + "\1\26\1\0\2\26\4\0\1\25\5\0\1\25\3\0"+ + "\1\26\4\0\1\26\2\25\2\26\10\0\1\26\1\0"+ + "\2\25\1\0\1\26\10\0\1\25\117\0\1\25\3\0"+ + "\1\25\6\0\2\25\5\0\1\25\1\0\1\25\1\0"+ + "\1\25\1\0\11\25\2\0\1\25\4\0\1\25\4\0"+ + "\6\25\2\0\1\25\1\0\1\25\1\0\3\25\1\0"+ + "\1\26\1\0\2\25\4\0\3\25\1\0\1\25\10\0"+ + "\1\25\1\0\2\25\114\0\1\25\3\0\1\25\5\0"+ + "\1\25\32\0\15\25\5\0\3\25\1\0\1\25\5\0"+ + "\1\25\2\26\5\0\1\25\2\0\1\25\1\26\4\0"+ + "\1\25\2\0\1\25\1\0\1\25\176\0\2\26\6\0"+ + "\1\26\151\0\1\26\3\0\1\26\2\0\1\26\3\0"+ + "\1\26\5\0\1\26\7\0\1\26\4\0\2\26\3\0"+ + "\2\26\1\0\1\26\4\0\1\26\1\0\1\26\2\0"+ + "\2\26\1\0\3\26\1\0\1\26\2\0\4\26\2\0"+ + "\1\26\146\0\1\165\3\0\1\166\5\0\1\167\3\0"+ + "\1\170\14\0\1\171\16\0\1\172\2\0\1\173\42\0"+ + "\1\75\1\26\6\0\1\75\36\0\12\26\27\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\174\3\0\1\67\5\0\1\70\3\0\1\175"+ + "\11\0\1\57\2\0\1\176\16\0\1\177\2\0\1\200"+ + "\21\0\1\104\17\0\1\25\1\76\1\26\1\27\3\0"+ + "\1\76\1\0\1\76\3\0\32\25\1\0\12\26\2\0"+ + "\1\76\25\0\1\27\37\0\1\27\1\0\2\27\16\0"+ + "\1\27\4\0\1\27\2\0\2\27\15\0\1\27\225\0"+ + "\1\27\246\0\2\27\11\0\1\27\210\0\2\27\6\0"+ + "\1\27\151\0\1\27\3\0\1\27\2\0\1\27\3\0"+ + "\1\27\5\0\1\27\7\0\1\27\4\0\2\27\3\0"+ + "\2\27\1\0\1\27\4\0\1\27\1\0\1\27\2\0"+ + "\2\27\1\0\3\27\1\0\1\27\2\0\4\27\2\0"+ + "\1\27\246\0\1\27\130\0\1\112\11\0\3\25\5\0"+ + "\1\25\1\0\1\25\1\0\1\25\4\0\1\25\4\0"+ + "\1\112\1\0\2\112\4\0\1\25\5\0\1\25\3\0"+ + "\1\112\4\0\1\112\2\25\2\112\10\0\1\26\1\0"+ + "\2\25\1\0\1\112\10\0\1\25\117\0\1\25\3\0"+ + "\1\25\6\0\2\25\5\0\1\25\1\0\1\25\1\0"+ + "\1\25\1\0\11\25\2\0\1\25\4\0\1\25\4\0"+ + "\6\25\2\0\1\25\1\0\1\25\1\0\3\25\1\0"+ + "\1\112\1\0\2\25\4\0\3\25\1\0\1\25\10\0"+ + "\1\25\1\0\2\25\114\0\1\25\3\0\1\25\5\0"+ + "\1\25\32\0\15\25\5\0\3\25\1\0\1\25\5\0"+ + "\1\25\2\112\5\0\1\25\2\0\1\25\1\112\4\0"+ + "\1\25\2\0\1\25\1\0\1\25\176\0\2\112\6\0"+ + "\1\112\151\0\1\112\3\0\1\112\2\0\1\112\3\0"+ + "\1\112\5\0\1\112\7\0\1\112\4\0\2\112\3\0"+ + "\2\112\1\0\1\112\4\0\1\112\1\0\1\112\2\0"+ + "\2\112\1\0\3\112\1\0\1\112\2\0\4\112\2\0"+ + "\1\112\301\0\1\113\45\114\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\1\140\3\0\2\114\150\0"+ + "\32\201\1\0\12\201\13\0\1\202\13\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\151\3\0\1\152\5\0\1\153\3\0\1\154\11\0"+ + "\1\57\2\0\1\155\16\0\1\156\2\0\1\157\41\0"+ + "\1\25\1\64\7\0\1\64\2\0\1\113\1\203\1\204"+ + "\1\205\1\206\1\207\1\210\1\211\1\212\1\213\1\214"+ + "\1\215\1\216\1\217\1\220\1\221\1\222\1\223\1\224"+ + "\1\225\1\226\1\227\1\230\1\231\1\232\1\233\1\234"+ + "\1\114\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\1\140\3\0\2\114\147\0\1\113\32\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\143"+ + "\3\0\1\54\5\0\1\55\3\0\1\144\11\0\1\57"+ + "\2\0\1\145\16\0\1\146\2\0\1\147\41\0\1\25"+ + "\2\63\2\0\2\150\1\65\1\0\1\63\2\0\1\236"+ + "\32\35\1\117\12\120\1\0\1\114\1\121\1\114\1\0"+ + "\2\237\1\115\3\114\2\0\1\150\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\160\3\0\1\54\5\0\1\55"+ + "\3\0\1\161\11\0\1\57\2\0\1\162\16\0\1\163"+ + "\2\0\1\164\21\0\1\104\17\0\1\25\1\65\1\63"+ + "\1\27\3\0\1\65\1\0\1\65\2\0\1\113\32\133"+ + "\1\114\12\240\1\0\1\114\1\121\1\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\151\3\0\1\152\5\0\1\153\3\0\1\154"+ + "\11\0\1\57\2\0\1\155\16\0\1\156\2\0\1\157"+ + "\41\0\1\25\1\64\7\0\1\64\2\0\1\113\32\133"+ + "\13\114\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\11\35\1\241\20\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\15\35\1\242\14\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\17\35\1\243\12\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\14\0\1\165\3\0\1\166\5\0"+ + "\1\167\3\0\1\170\14\0\1\171\16\0\1\172\2\0"+ + "\1\173\42\0\1\75\1\26\6\0\1\75\2\0\1\113"+ + "\1\244\1\245\1\246\1\247\1\250\1\251\1\252\1\253"+ + "\1\254\1\255\1\256\1\257\1\260\1\261\1\262\1\263"+ + "\1\264\1\265\1\266\1\267\1\270\1\271\1\272\1\273"+ + "\1\274\1\275\1\114\1\276\2\277\1\276\4\277\1\300"+ + "\1\277\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\1\140\3\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\174"+ + "\3\0\1\67\5\0\1\70\3\0\1\175\11\0\1\57"+ + "\2\0\1\176\16\0\1\177\2\0\1\200\21\0\1\104"+ + "\17\0\1\25\1\76\1\26\1\27\3\0\1\76\1\0"+ + "\1\76\2\0\1\113\32\133\1\114\12\134\1\0\1\114"+ + "\1\127\1\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\14\0\1\165\3\0\1\166\5\0\1\167"+ + "\3\0\1\170\14\0\1\171\16\0\1\172\2\0\1\173"+ + "\42\0\1\75\1\26\6\0\1\75\2\0\1\113\33\114"+ + "\12\134\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\66\3\0"+ + "\1\67\5\0\1\70\3\0\1\71\11\0\1\57\2\0"+ + "\1\72\16\0\1\73\2\0\1\74\41\0\1\25\2\26"+ + "\2\0\2\75\1\76\1\0\1\26\2\0\1\126\32\35"+ + "\1\117\12\301\1\0\1\114\1\127\1\114\1\0\2\130"+ + "\1\115\3\114\2\0\1\75\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\66\3\0\1\67\5\0\1\70\3\0"+ + "\1\71\11\0\1\57\2\0\1\72\16\0\1\73\2\0"+ + "\1\74\41\0\1\25\2\26\2\0\2\75\1\76\1\0"+ + "\1\26\2\0\1\126\32\35\1\117\2\131\1\301\2\131"+ + "\2\301\2\131\1\301\1\0\1\114\1\127\1\114\1\0"+ + "\2\130\1\115\3\114\2\0\1\75\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\302\32\133\1\114"+ + "\12\240\1\64\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\66\3\0\1\67\5\0\1\70\3\0\1\71"+ + "\11\0\1\57\2\0\1\72\16\0\1\73\2\0\1\74"+ + "\41\0\1\25\2\26\2\0\2\75\1\76\1\0\1\26"+ + "\2\0\1\303\32\133\1\114\12\134\1\0\1\114\1\127"+ + "\1\114\1\0\2\130\1\115\3\114\2\0\1\75\1\114"+ + "\4\0\2\114\150\0\4\304\2\0\1\304\15\0\1\304"+ + "\6\0\12\304\1\305\241\0\1\306\173\0\1\307\54\0"+ + "\1\115\164\0\74\140\2\0\1\63\11\0\3\25\5\0"+ + "\1\25\1\0\1\25\1\0\1\25\4\0\1\25\4\0"+ + "\1\63\1\0\2\63\4\0\1\25\5\0\1\25\3\0"+ + "\1\63\4\0\1\63\2\25\2\63\10\0\1\63\1\0"+ + "\2\25\1\0\1\63\10\0\1\25\117\0\1\25\3\0"+ + "\1\25\6\0\2\25\5\0\1\25\1\0\1\25\1\0"+ + "\1\25\1\0\11\25\2\0\1\25\4\0\1\25\4\0"+ + "\6\25\2\0\1\25\1\0\1\25\1\0\3\25\1\0"+ + "\1\63\1\0\2\25\4\0\3\25\1\0\1\25\10\0"+ + "\1\25\1\0\2\25\114\0\1\25\3\0\1\25\5\0"+ + "\1\25\32\0\15\25\5\0\3\25\1\0\1\25\5\0"+ + "\1\25\2\63\5\0\1\25\2\0\1\25\1\63\4\0"+ + "\1\25\2\0\1\25\1\0\1\25\176\0\2\63\6\0"+ + "\1\63\151\0\1\63\3\0\1\63\2\0\1\63\3\0"+ + "\1\63\5\0\1\63\7\0\1\63\4\0\2\63\3\0"+ + "\2\63\1\0\1\63\4\0\1\63\1\0\1\63\2\0"+ + "\2\63\1\0\3\63\1\0\1\63\2\0\4\63\2\0"+ + "\1\63\146\0\1\310\3\0\1\311\5\0\1\312\3\0"+ + "\1\313\14\0\1\314\16\0\1\315\2\0\1\316\42\0"+ + "\1\150\1\63\6\0\1\150\36\0\12\63\30\0\1\64"+ + "\11\0\3\25\5\0\1\25\1\0\1\25\1\0\1\25"+ + "\4\0\1\25\4\0\1\64\1\0\2\64\4\0\1\25"+ + "\5\0\1\25\3\0\1\64\4\0\1\64\2\25\2\64"+ + "\12\0\2\25\1\0\1\64\10\0\1\25\117\0\1\25"+ + "\11\0\2\25\2\0\5\25\2\0\2\25\4\0\6\25"+ + "\1\0\2\25\4\0\5\25\1\0\5\25\1\0\2\25"+ + "\1\0\3\25\1\0\4\25\1\0\5\25\2\0\1\25"+ + "\1\0\1\25\1\0\3\25\2\0\1\25\1\0\1\25"+ + "\1\0\1\25\2\0\1\25\112\0\1\25\3\0\1\25"+ + "\5\0\2\25\3\0\1\25\4\0\3\25\4\0\1\25"+ + "\1\0\1\25\2\0\1\25\1\0\2\25\4\0\1\25"+ + "\1\0\1\25\3\0\2\25\1\0\1\25\5\0\3\25"+ + "\1\0\1\25\10\0\1\25\4\0\1\25\10\0\1\25"+ + "\117\0\1\25\3\0\1\25\6\0\2\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\1\0\11\25\2\0\1\25"+ + "\4\0\1\25\4\0\6\25\2\0\1\25\1\0\1\25"+ + "\1\0\3\25\1\0\1\64\1\0\2\25\4\0\3\25"+ + "\1\0\1\25\10\0\1\25\1\0\2\25\114\0\1\25"+ + "\3\0\1\25\5\0\1\25\32\0\15\25\5\0\3\25"+ + "\1\0\1\25\5\0\1\25\2\64\5\0\1\25\2\0"+ + "\1\25\1\64\4\0\1\25\2\0\1\25\1\0\1\25"+ + "\176\0\2\64\6\0\1\64\151\0\1\64\3\0\1\64"+ + "\2\0\1\64\3\0\1\64\5\0\1\64\7\0\1\64"+ + "\4\0\2\64\3\0\2\64\1\0\1\64\4\0\1\64"+ + "\1\0\1\64\2\0\2\64\1\0\3\64\1\0\1\64"+ + "\2\0\4\64\2\0\1\64\135\0\1\65\11\0\3\25"+ + "\5\0\1\25\1\0\1\25\1\0\1\25\4\0\1\25"+ + "\4\0\1\65\1\0\2\65\4\0\1\25\5\0\1\25"+ + "\3\0\1\65\4\0\1\65\2\25\2\65\10\0\1\63"+ + "\1\0\2\25\1\0\1\65\10\0\1\25\117\0\1\25"+ + "\3\0\1\25\6\0\2\25\5\0\1\25\1\0\1\25"+ + "\1\0\1\25\1\0\11\25\2\0\1\25\4\0\1\25"+ + "\4\0\6\25\2\0\1\25\1\0\1\25\1\0\3\25"+ + "\1\0\1\65\1\0\2\25\4\0\3\25\1\0\1\25"+ + "\10\0\1\25\1\0\2\25\114\0\1\25\3\0\1\25"+ + "\5\0\1\25\32\0\15\25\5\0\3\25\1\0\1\25"+ + "\5\0\1\25\2\65\5\0\1\25\2\0\1\25\1\65"+ + "\4\0\1\25\2\0\1\25\1\0\1\25\176\0\2\65"+ + "\6\0\1\65\151\0\1\65\3\0\1\65\2\0\1\65"+ + "\3\0\1\65\5\0\1\65\7\0\1\65\4\0\2\65"+ + "\3\0\2\65\1\0\1\65\4\0\1\65\1\0\1\65"+ + "\2\0\2\65\1\0\3\65\1\0\1\65\2\0\4\65"+ + "\2\0\1\65\135\0\1\75\37\0\1\75\1\0\2\75"+ + "\16\0\1\75\4\0\1\75\2\0\2\75\10\0\1\26"+ + "\4\0\1\75\132\0\1\26\102\0\1\26\242\0\2\26"+ + "\227\0\1\75\246\0\2\75\11\0\1\75\210\0\2\75"+ + "\6\0\1\75\151\0\1\75\3\0\1\75\2\0\1\75"+ + "\3\0\1\75\5\0\1\75\7\0\1\75\4\0\2\75"+ + "\3\0\2\75\1\0\1\75\4\0\1\75\1\0\1\75"+ + "\2\0\2\75\1\0\3\75\1\0\1\75\2\0\4\75"+ + "\2\0\1\75\135\0\1\76\11\0\3\25\5\0\1\25"+ + "\1\0\1\25\1\0\1\25\4\0\1\25\4\0\1\76"+ + "\1\0\2\76\4\0\1\25\5\0\1\25\3\0\1\76"+ + "\4\0\1\76\2\25\2\76\10\0\1\26\1\0\2\25"+ + "\1\0\1\76\10\0\1\25\117\0\1\25\3\0\1\25"+ + "\6\0\2\25\5\0\1\25\1\0\1\25\1\0\1\25"+ + "\1\0\11\25\2\0\1\25\4\0\1\25\4\0\6\25"+ + "\2\0\1\25\1\0\1\25\1\0\3\25\1\0\1\76"+ + "\1\0\2\25\4\0\3\25\1\0\1\25\10\0\1\25"+ + "\1\0\2\25\114\0\1\25\3\0\1\25\5\0\1\25"+ + "\32\0\15\25\5\0\3\25\1\0\1\25\5\0\1\25"+ + "\2\76\5\0\1\25\2\0\1\25\1\76\4\0\1\25"+ + "\2\0\1\25\1\0\1\25\176\0\2\76\6\0\1\76"+ + "\151\0\1\76\3\0\1\76\2\0\1\76\3\0\1\76"+ + "\5\0\1\76\7\0\1\76\4\0\2\76\3\0\2\76"+ + "\1\0\1\76\4\0\1\76\1\0\1\76\2\0\2\76"+ + "\1\0\3\76\1\0\1\76\2\0\4\76\2\0\1\76"+ + "\301\0\1\317\32\201\1\320\12\201\174\0\61\202\1\0"+ + "\1\321\4\202\1\322\1\0\3\202\1\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\116\1\35\2\323\1\324\1\325\10\323"+ + "\1\35\1\326\5\323\6\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\1\327\2\323\1\35\1\323\1\330\6\323\4\35"+ + "\1\323\1\35\2\323\1\35\1\323\1\35\3\323\1\117"+ + "\12\120\1\64\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\116\3\35\1\323\1\35\1\323"+ + "\4\35\1\323\10\35\1\323\2\35\1\323\2\35\1\323"+ + "\1\117\12\120\1\64\1\114\1\121\1\114\1\0\1\114"+ + "\1\122\1\115\3\114\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\53\3\0\1\54\5\0\1\55\3\0"+ + "\1\56\11\0\1\57\2\0\1\60\16\0\1\61\2\0"+ + "\1\62\41\0\2\25\1\63\1\0\1\64\1\0\1\64"+ + "\1\65\1\0\1\25\2\0\1\116\1\35\1\323\1\331"+ + "\2\323\2\35\1\323\6\35\3\323\11\35\1\117\12\120"+ + "\1\64\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\116\3\35\1\323\1\35\1\323\10\35"+ + "\1\323\1\35\2\323\10\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\4\35\1\332\5\35\1\323\17\35\1\117\12\120"+ + "\1\64\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\116\4\35\2\323\2\35\1\323\1\35"+ + "\1\323\13\35\1\323\2\35\1\323\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\1\323\1\35\3\323\1\333\14\323\2\35"+ + "\2\323\2\35\1\323\1\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\2\35\4\323\3\35\2\323\1\334\1\323\1\35"+ + "\2\323\12\35\1\117\12\120\1\64\1\114\1\121\1\114"+ + "\1\0\1\114\1\122\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\53\3\0\1\54\5\0"+ + "\1\55\3\0\1\56\11\0\1\57\2\0\1\60\16\0"+ + "\1\61\2\0\1\62\41\0\2\25\1\63\1\0\1\64"+ + "\1\0\1\64\1\65\1\0\1\25\2\0\1\116\2\323"+ + "\2\35\1\323\3\35\1\323\5\35\3\323\3\35\1\323"+ + "\2\35\3\323\1\117\12\120\1\64\1\114\1\121\1\114"+ + "\1\0\1\114\1\122\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\53\3\0\1\54\5\0"+ + "\1\55\3\0\1\56\11\0\1\57\2\0\1\60\16\0"+ + "\1\61\2\0\1\62\41\0\2\25\1\63\1\0\1\64"+ + "\1\0\1\64\1\65\1\0\1\25\2\0\1\116\5\323"+ + "\1\335\1\35\1\323\1\336\7\323\1\337\3\323\1\35"+ + "\1\323\1\35\3\323\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\1\340\1\323\1\35\1\327\6\323\3\35\1\323\2\35"+ + "\1\323\2\35\1\323\6\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\1\323\31\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\1\323\2\35\1\323\1\341\1\35\2\323\1\35\3\323"+ + "\2\35\2\323\1\35\1\323\3\35\1\323\2\35\2\323"+ + "\1\117\12\120\1\64\1\114\1\121\1\114\1\0\1\114"+ + "\1\122\1\115\3\114\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\53\3\0\1\54\5\0\1\55\3\0"+ + "\1\56\11\0\1\57\2\0\1\60\16\0\1\61\2\0"+ + "\1\62\41\0\2\25\1\63\1\0\1\64\1\0\1\64"+ + "\1\65\1\0\1\25\2\0\1\116\6\323\1\35\5\323"+ + "\3\35\2\323\2\35\7\323\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\1\35\2\323\1\336\1\342\3\323\1\35\3\323"+ + "\1\35\1\323\1\35\1\323\1\35\1\323\1\35\1\323"+ + "\1\35\3\323\1\35\1\323\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\1\323\6\35\1\323\6\35\1\323\4\35\1\323"+ + "\4\35\2\323\1\117\12\120\1\64\1\114\1\121\1\114"+ + "\1\0\1\114\1\122\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\53\3\0\1\54\5\0"+ + "\1\55\3\0\1\56\11\0\1\57\2\0\1\60\16\0"+ + "\1\61\2\0\1\62\41\0\2\25\1\63\1\0\1\64"+ + "\1\0\1\64\1\65\1\0\1\25\2\0\1\116\6\35"+ + "\1\323\7\35\1\323\13\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\13\35\1\343\16\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\1\323\11\35\1\323\6\35\1\323\10\35\1\117"+ + "\12\120\1\64\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\116\1\323\1\35\6\323\1\344"+ + "\1\35\2\323\2\35\2\323\1\35\1\323\1\35\6\323"+ + "\1\35\1\117\12\120\1\64\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\116\4\35\1\323"+ + "\5\35\2\323\3\35\2\323\10\35\1\323\1\117\12\120"+ + "\1\64\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\116\3\35\1\323\1\35\1\345\4\35"+ + "\1\323\2\35\1\323\14\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\2\323\1\35\1\323\3\35\2\323\2\35\1\323"+ + "\4\35\1\323\11\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\3\35\1\323\13\35\1\323\12\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\3\35\2\323\2\35\2\323\1\35\2\323"+ + "\1\35\1\323\3\35\1\323\1\35\1\323\1\35\1\323"+ + "\2\35\1\323\1\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\32\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\14\0\1\310\3\0\1\311\5\0\1\312\3\0"+ + "\1\313\14\0\1\314\16\0\1\315\2\0\1\316\42\0"+ + "\1\150\1\63\6\0\1\150\2\0\1\113\1\244\1\245"+ + "\1\246\1\247\1\250\1\251\1\252\1\253\1\254\1\255"+ + "\1\256\1\257\1\260\1\261\1\262\1\263\1\264\1\265"+ + "\1\266\1\267\1\270\1\271\1\272\1\273\1\274\1\275"+ + "\1\114\12\120\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\1\140\3\0\2\114\14\0\1\310\3\0"+ + "\1\311\5\0\1\312\3\0\1\313\14\0\1\314\16\0"+ + "\1\315\2\0\1\316\42\0\1\150\1\63\6\0\1\150"+ + "\2\0\1\113\33\114\12\240\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\143\3\0\1\54\5\0\1\55\3\0\1\144"+ + "\11\0\1\57\2\0\1\145\16\0\1\146\2\0\1\147"+ + "\41\0\1\25\2\63\2\0\2\150\1\65\1\0\1\63"+ + "\2\0\1\347\32\133\1\114\12\240\1\0\1\114\1\121"+ + "\1\114\1\0\2\237\1\115\3\114\2\0\1\150\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\3\35\1\350\26\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\32\35\1\117\12\120\1\351\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\116\15\35\1\352"+ + "\14\35\1\117\12\120\1\64\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\1\235\2\353\1\354\1\355\10\353\1\235"+ + "\1\356\5\353\6\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\1\357\2\353\1\235\1\353\1\360\6\353\4\235"+ + "\1\353\1\235\2\353\1\235\1\353\1\235\3\353\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\3\235\1\353\1\235"+ + "\1\353\4\235\1\353\10\235\1\353\2\235\1\353\2\235"+ + "\1\353\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\235"+ + "\1\353\1\361\2\353\2\235\1\353\6\235\3\353\11\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\3\235\1\353"+ + "\1\235\1\353\10\235\1\353\1\235\2\353\10\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\4\235\1\362\5\235"+ + "\1\353\17\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\4\235\2\353\2\235\1\353\1\235\1\353\13\235\1\353"+ + "\2\235\1\353\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\353\1\235\3\353\1\363\14\353\2\235\2\353\2\235"+ + "\1\353\1\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\2\235\4\353\3\235\2\353\1\364\1\353\1\235\2\353"+ + "\12\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\2\353"+ + "\2\235\1\353\3\235\1\353\5\235\3\353\3\235\1\353"+ + "\2\235\3\353\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\5\353\1\365\1\235\1\353\1\366\7\353\1\367\3\353"+ + "\1\235\1\353\1\235\3\353\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\1\370\1\353\1\235\1\357\6\353\3\235"+ + "\1\353\2\235\1\353\2\235\1\353\6\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\1\353\31\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\1\353\2\235\1\353\1\371"+ + "\1\235\2\353\1\235\3\353\2\235\2\353\1\235\1\353"+ + "\3\235\1\353\2\235\2\353\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\6\353\1\235\5\353\3\235\2\353\2\235"+ + "\7\353\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\235"+ + "\2\353\1\366\1\372\3\353\1\235\3\353\1\235\1\353"+ + "\1\235\1\353\1\235\1\353\1\235\1\353\1\235\3\353"+ + "\1\235\1\353\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\353\6\235\1\353\6\235\1\353\4\235\1\353\4\235"+ + "\2\353\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\6\235"+ + "\1\353\7\235\1\353\13\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\13\235\1\373\16\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\353\11\235\1\353\6\235\1\353"+ + "\10\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\353"+ + "\1\235\6\353\1\374\1\235\2\353\2\235\2\353\1\235"+ + "\1\353\1\235\6\353\1\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\4\235\1\353\5\235\2\353\3\235\2\353"+ + "\10\235\1\353\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\3\235\1\353\1\235\1\375\4\235\1\353\2\235\1\353"+ + "\14\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\2\353"+ + "\1\235\1\353\3\235\2\353\2\235\1\353\4\235\1\353"+ + "\11\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\3\235"+ + "\1\353\13\235\1\353\12\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\3\235\2\353\2\235\2\353\1\235\2\353"+ + "\1\235\1\353\3\235\1\353\1\235\1\353\1\235\1\353"+ + "\2\235\1\353\1\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\66\3\0\1\67\5\0\1\70\3\0"+ + "\1\71\11\0\1\57\2\0\1\72\16\0\1\73\2\0"+ + "\1\74\41\0\1\25\2\26\2\0\2\75\1\76\1\0"+ + "\1\26\2\0\1\376\32\35\1\117\12\277\1\0\1\114"+ + "\1\127\1\114\1\0\2\130\1\115\3\114\2\0\1\75"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\66\3\0"+ + "\1\67\5\0\1\70\3\0\1\71\11\0\1\57\2\0"+ + "\1\72\16\0\1\73\2\0\1\74\41\0\1\25\2\26"+ + "\2\0\2\75\1\76\1\0\1\26\2\0\1\376\32\35"+ + "\1\117\12\377\1\0\1\114\1\127\1\114\1\0\2\130"+ + "\1\115\3\114\2\0\1\75\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\66\3\0\1\67\5\0\1\70\3\0"+ + "\1\71\11\0\1\57\2\0\1\72\16\0\1\73\2\0"+ + "\1\74\41\0\1\25\2\26\2\0\2\75\1\76\1\0"+ + "\1\26\2\0\1\376\32\35\1\117\1\277\1\u0100\1\377"+ + "\2\277\2\377\2\277\1\377\1\0\1\114\1\127\1\114"+ + "\1\0\2\130\1\115\3\114\2\0\1\75\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\66\3\0\1\67\5\0"+ + "\1\70\3\0\1\71\11\0\1\57\2\0\1\72\16\0"+ + "\1\73\2\0\1\74\41\0\1\25\2\26\2\0\2\75"+ + "\1\76\1\0\1\26\2\0\1\u0101\32\35\1\117\12\301"+ + "\1\0\1\114\1\127\1\114\1\0\2\130\1\115\3\114"+ + "\2\0\1\75\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\151\3\0\1\152\5\0\1\153\3\0\1\154\11\0"+ + "\1\57\2\0\1\155\16\0\1\156\2\0\1\157\41\0"+ + "\1\25\1\64\7\0\1\64\2\0\1\113\32\133\13\114"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\1\140\3\0\2\114\14\0\1\165\3\0\1\166\5\0"+ + "\1\167\3\0\1\170\14\0\1\171\16\0\1\172\2\0"+ + "\1\173\42\0\1\75\1\26\6\0\1\75\2\0\1\113"+ + "\33\114\12\134\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\1\140\3\0\2\114\150\0\4\u0102\2\0"+ + "\1\u0102\15\0\1\u0102\6\0\12\u0102\1\305\174\0\4\u0103"+ + "\2\0\1\u0103\15\0\1\u0103\6\0\12\u0103\1\u0104\174\0"+ + "\4\u0105\2\0\1\u0105\15\0\1\u0105\6\0\1\u0106\2\u0107"+ + "\1\u0106\4\u0107\1\u0108\1\u0107\14\0\1\u0109\157\0\46\114"+ + "\1\0\3\114\1\0\2\114\1\0\3\114\3\0\1\114"+ + "\1\140\3\0\2\114\3\0\1\150\37\0\1\150\1\0"+ + "\2\150\16\0\1\150\4\0\1\150\2\0\2\150\10\0"+ + "\1\63\4\0\1\150\132\0\1\63\102\0\1\63\242\0"+ + "\2\63\227\0\1\150\246\0\2\150\11\0\1\150\210\0"+ + "\2\150\6\0\1\150\151\0\1\150\3\0\1\150\2\0"+ + "\1\150\3\0\1\150\5\0\1\150\7\0\1\150\4\0"+ + "\2\150\3\0\2\150\1\0\1\150\4\0\1\150\1\0"+ + "\1\150\2\0\2\150\1\0\3\150\1\0\1\150\2\0"+ + "\4\150\2\0\1\150\302\0\1\u010a\1\u010b\1\u010c\1\u010d"+ + "\1\u010e\1\u010f\1\u0110\1\u0111\1\u0112\1\u0113\1\u0114\1\u0115"+ + "\1\u0116\1\u0117\1\u0118\1\u0119\1\u011a\1\u011b\1\u011c\1\u011d"+ + "\1\u011e\1\u011f\1\u0120\1\u0121\1\u0122\1\u0123\1\0\12\201"+ + "\175\0\32\201\1\320\12\201\174\0\74\202\1\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\u0124\32\35\1\117\12\120\1\u0125"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\u0124\4\35\1\u0129\25\35\1\117"+ + "\12\120\1\u0125\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\u0124\15\35\1\217"+ + "\14\35\1\117\12\120\1\u0125\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\u0124"+ + "\10\35\1\217\21\35\1\117\12\120\1\u0125\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\1\u0126\1\u0127\1\u0128"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\u0124\17\35\1\323\12\35\1\117\12\120\1\u0125"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\u0124\5\35\1\u012a\4\35\1\323"+ + "\17\35\1\117\12\120\1\u0125\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\20\35\1\323\11\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\7\35\1\323\22\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\116"+ + "\27\35\1\323\2\35\1\117\12\120\1\64\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\u0124"+ + "\6\35\1\u0129\10\35\1\323\12\35\1\117\12\120\1\u0125"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\u0124\24\35\1\u012b\5\35\1\117"+ + "\12\120\1\u0125\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\116\11\35\1\323"+ + "\20\35\1\117\12\120\1\64\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\u0124\16\35\1\u012c"+ + "\13\35\1\117\12\120\1\u0125\1\114\1\121\1\114\1\0"+ + "\1\114\1\122\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\53\3\0\1\54"+ + "\5\0\1\55\3\0\1\56\11\0\1\57\2\0\1\60"+ + "\16\0\1\61\2\0\1\62\41\0\2\25\1\63\1\0"+ + "\1\64\1\0\1\64\1\65\1\0\1\25\2\0\1\u0124"+ + "\12\35\1\u012d\17\35\1\117\12\120\1\u0125\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\1\u0126\1\u0127\1\u0128"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\u0124\5\35\1\323\24\35\1\117\12\120\1\u0125"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\u0124\1\u012e\31\35\1\117\12\120"+ + "\1\u0125\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\53\3\0\1\54\5\0\1\55\3\0"+ + "\1\56\11\0\1\57\2\0\1\60\16\0\1\61\2\0"+ + "\1\62\41\0\2\25\1\63\1\0\1\64\1\0\1\64"+ + "\1\65\1\0\1\25\2\0\1\116\32\35\1\u012f\12\120"+ + "\1\64\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\u0124\23\35\1\323\6\35\1\117\12\120"+ + "\1\u0125\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114\2\0"+ + "\1\46\1\0\1\47\1\0\1\50\1\0\1\51\1\0"+ + "\1\52\1\0\1\53\3\0\1\54\5\0\1\55\3\0"+ + "\1\56\11\0\1\57\2\0\1\60\16\0\1\61\2\0"+ + "\1\62\41\0\2\25\1\63\1\0\1\64\1\0\1\64"+ + "\1\65\1\0\1\25\2\0\1\u0124\24\35\1\u0130\5\35"+ + "\1\117\12\120\1\u0125\1\114\1\121\1\114\1\0\1\114"+ + "\1\122\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0"+ + "\2\114\147\0\1\113\1\244\1\245\1\246\1\247\1\250"+ + "\1\251\1\252\1\253\1\254\1\255\1\256\1\257\1\260"+ + "\1\261\1\262\1\263\1\264\1\265\1\266\1\267\1\270"+ + "\1\271\1\272\1\273\1\274\1\275\1\114\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\1\140"+ + "\3\0\2\114\14\0\1\310\3\0\1\311\5\0\1\312"+ + "\3\0\1\313\14\0\1\314\16\0\1\315\2\0\1\316"+ + "\42\0\1\150\1\63\6\0\1\150\2\0\1\113\33\114"+ + "\12\240\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\1\140\3\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\32\35\1\117\12\120\1\u0131\1\114\1\121"+ + "\1\114\1\0\1\114\1\122\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\151\3\0\1\152"+ + "\5\0\1\153\3\0\1\154\11\0\1\57\2\0\1\155"+ + "\16\0\1\156\2\0\1\157\41\0\1\25\1\64\7\0"+ + "\1\64\3\0\32\25\24\0\1\u0132\15\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\53\3\0\1\54\5\0\1\55\3\0\1\56\11\0"+ + "\1\57\2\0\1\60\16\0\1\61\2\0\1\62\41\0"+ + "\2\25\1\63\1\0\1\64\1\0\1\64\1\65\1\0"+ + "\1\25\2\0\1\116\16\35\1\u0133\13\35\1\117\12\120"+ + "\1\u0134\1\114\1\121\1\114\1\0\1\114\1\122\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\u0135\32\235"+ + "\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0\1\u0135"+ + "\4\235\1\u0137\25\235\1\117\12\235\1\u0136\3\114\1\0"+ + "\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0"+ + "\2\114\147\0\1\u0135\15\235\1\260\14\235\1\117\12\235"+ + "\1\u0136\3\114\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128"+ + "\3\0\1\114\4\0\2\114\147\0\1\u0135\10\235\1\260"+ + "\21\235\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115"+ + "\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0"+ + "\1\u0135\17\235\1\353\12\235\1\117\12\235\1\u0136\3\114"+ + "\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114"+ + "\4\0\2\114\147\0\1\u0135\5\235\1\u0138\4\235\1\353"+ + "\17\235\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115"+ + "\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\20\235\1\353\11\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\7\235\1\353\22\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\27\235\1\353\2\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\u0135\6\235\1\u0137\10\235\1\353"+ + "\12\235\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115"+ + "\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0"+ + "\1\u0135\24\235\1\u0139\5\235\1\117\12\235\1\u0136\3\114"+ + "\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\11\235\1\353\20\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\u0135\16\235\1\u013a\13\235"+ + "\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0\1\u0135"+ + "\12\235\1\u013b\17\235\1\117\12\235\1\u0136\3\114\1\0"+ + "\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0"+ + "\2\114\147\0\1\u0135\5\235\1\353\24\235\1\117\12\235"+ + "\1\u0136\3\114\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128"+ + "\3\0\1\114\4\0\2\114\147\0\1\u0135\1\u013c\31\235"+ + "\1\117\12\235\1\u0136\3\114\1\0\2\114\1\115\1\u0126"+ + "\1\u0127\1\u0128\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\u012f\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\u0135\23\235"+ + "\1\353\6\235\1\117\12\235\1\u0136\3\114\1\0\2\114"+ + "\1\115\1\u0126\1\u0127\1\u0128\3\0\1\114\4\0\2\114"+ + "\147\0\1\u0135\24\235\1\u013d\5\235\1\117\12\235\1\u0136"+ + "\3\114\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0"+ + "\1\114\4\0\2\114\14\0\1\165\3\0\1\166\5\0"+ + "\1\167\3\0\1\170\14\0\1\171\16\0\1\172\2\0"+ + "\1\173\42\0\1\75\1\26\6\0\1\75\2\0\1\113"+ + "\1\244\1\245\1\246\1\247\1\250\1\251\1\252\1\253"+ + "\1\254\1\255\1\256\1\257\1\260\1\261\1\262\1\263"+ + "\1\264\1\265\1\266\1\267\1\270\1\271\1\272\1\273"+ + "\1\274\1\275\1\114\1\u013e\2\u013f\1\u013e\4\u013f\1\u0140"+ + "\1\u013f\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\1\140\3\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\66"+ + "\3\0\1\67\5\0\1\70\3\0\1\71\11\0\1\57"+ + "\2\0\1\72\16\0\1\73\2\0\1\74\41\0\1\25"+ + "\2\26\2\0\2\75\1\76\1\0\1\26\2\0\1\376"+ + "\32\35\1\117\12\301\1\0\1\114\1\127\1\114\1\0"+ + "\2\130\1\115\3\114\2\0\1\75\1\114\4\0\2\114"+ + "\2\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\66\3\0\1\67\5\0\1\70"+ + "\3\0\1\71\11\0\1\57\2\0\1\72\16\0\1\73"+ + "\2\0\1\74\41\0\1\25\2\26\2\0\2\75\1\76"+ + "\1\0\1\26\2\0\1\376\32\35\1\117\2\377\1\301"+ + "\2\377\2\301\2\377\1\301\1\0\1\114\1\127\1\114"+ + "\1\0\2\130\1\115\3\114\2\0\1\75\1\114\4\0"+ + "\2\114\14\0\1\165\3\0\1\166\5\0\1\167\3\0"+ + "\1\170\14\0\1\171\16\0\1\172\2\0\1\173\42\0"+ + "\1\75\1\26\6\0\1\75\2\0\1\113\1\244\1\245"+ + "\1\246\1\247\1\250\1\251\1\252\1\253\1\254\1\255"+ + "\1\256\1\257\1\260\1\261\1\262\1\263\1\264\1\265"+ + "\1\266\1\267\1\270\1\271\1\272\1\273\1\274\1\275"+ + "\1\114\12\301\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\1\140\3\0\2\114\150\0\4\u0141\2\0"+ + "\1\u0141\15\0\1\u0141\6\0\12\u0141\1\305\174\0\4\u0142"+ + "\2\0\1\u0142\15\0\1\u0142\6\0\12\u0142\1\u0143\174\0"+ + "\4\u0144\2\0\1\u0144\15\0\1\u0144\6\0\1\u0145\2\u0146"+ + "\1\u0145\4\u0146\1\u0147\1\u0146\14\0\1\u0109\160\0\4\u0148"+ + "\2\0\1\u0148\15\0\1\u0148\6\0\12\u0148\1\u0149\13\0"+ + "\1\u0109\157\0\1\u014a\4\u0148\2\0\1\u0148\15\0\1\u0148"+ + "\6\0\12\u014b\1\u0149\13\0\1\u0109\157\0\1\u014a\4\u0148"+ + "\2\0\1\u0148\15\0\1\u0148\6\0\12\u014c\1\u0149\13\0"+ + "\1\u0109\157\0\1\u014a\4\u0148\2\0\1\u0148\15\0\1\u0148"+ + "\6\0\1\u014b\1\u014d\1\u014c\2\u014b\2\u014c\2\u014b\1\u014c"+ + "\1\u0149\13\0\1\u0109\225\0\1\u0136\7\0\1\u014e\1\u014f"+ + "\1\u0150\161\0\1\317\1\201\2\u0151\1\u0152\1\u0153\10\u0151"+ + "\1\201\1\u0154\5\u0151\6\201\1\320\12\201\174\0\1\317"+ + "\1\u0155\2\u0151\1\201\1\u0151\1\u0156\6\u0151\4\201\1\u0151"+ + "\1\201\2\u0151\1\201\1\u0151\1\201\3\u0151\1\320\12\201"+ + "\174\0\1\317\3\201\1\u0151\1\201\1\u0151\4\201\1\u0151"+ + "\10\201\1\u0151\2\201\1\u0151\2\201\1\u0151\1\320\12\201"+ + "\174\0\1\317\1\201\1\u0151\1\u0157\2\u0151\2\201\1\u0151"+ + "\6\201\3\u0151\11\201\1\320\12\201\174\0\1\317\3\201"+ + "\1\u0151\1\201\1\u0151\10\201\1\u0151\1\201\2\u0151\10\201"+ + "\1\320\12\201\174\0\1\317\4\201\1\u0158\5\201\1\u0151"+ + "\17\201\1\320\12\201\174\0\1\317\4\201\2\u0151\2\201"+ + "\1\u0151\1\201\1\u0151\13\201\1\u0151\2\201\1\u0151\1\320"+ + "\12\201\174\0\1\317\1\u0151\1\201\3\u0151\1\u0159\14\u0151"+ + "\2\201\2\u0151\2\201\1\u0151\1\201\1\320\12\201\174\0"+ + "\1\317\2\201\4\u0151\3\201\2\u0151\1\u015a\1\u0151\1\201"+ + "\2\u0151\12\201\1\320\12\201\174\0\1\317\2\u0151\2\201"+ + "\1\u0151\3\201\1\u0151\5\201\3\u0151\3\201\1\u0151\2\201"+ + "\3\u0151\1\320\12\201\174\0\1\317\5\u0151\1\u015b\1\201"+ + "\1\u0151\1\u015c\7\u0151\1\u015d\3\u0151\1\201\1\u0151\1\201"+ + "\3\u0151\1\320\12\201\174\0\1\317\1\u015e\1\u0151\1\201"+ + "\1\u0155\6\u0151\3\201\1\u0151\2\201\1\u0151\2\201\1\u0151"+ + "\6\201\1\320\12\201\174\0\1\317\1\u0151\31\201\1\320"+ + "\12\201\174\0\1\317\1\u0151\2\201\1\u0151\1\u015f\1\201"+ + "\2\u0151\1\201\3\u0151\2\201\2\u0151\1\201\1\u0151\3\201"+ + "\1\u0151\2\201\2\u0151\1\320\12\201\174\0\1\317\6\u0151"+ + "\1\201\5\u0151\3\201\2\u0151\2\201\7\u0151\1\320\12\201"+ + "\174\0\1\317\1\201\2\u0151\1\u015c\1\u0160\3\u0151\1\201"+ + "\3\u0151\1\201\1\u0151\1\201\1\u0151\1\201\1\u0151\1\201"+ + "\1\u0151\1\201\3\u0151\1\201\1\u0151\1\320\12\201\174\0"+ + "\1\317\1\u0151\6\201\1\u0151\6\201\1\u0151\4\201\1\u0151"+ + "\4\201\2\u0151\1\320\12\201\174\0\1\317\6\201\1\u0151"+ + "\7\201\1\u0151\13\201\1\320\12\201\174\0\1\317\13\201"+ + "\1\u0161\16\201\1\320\12\201\174\0\1\317\1\u0151\11\201"+ + "\1\u0151\6\201\1\u0151\10\201\1\320\12\201\174\0\1\317"+ + "\1\u0151\1\201\6\u0151\1\u0162\1\201\2\u0151\2\201\2\u0151"+ + "\1\201\1\u0151\1\201\6\u0151\1\201\1\320\12\201\174\0"+ + "\1\317\4\201\1\u0151\5\201\2\u0151\3\201\2\u0151\10\201"+ + "\1\u0151\1\320\12\201\174\0\1\317\3\201\1\u0151\1\201"+ + "\1\u0163\4\201\1\u0151\2\201\1\u0151\14\201\1\320\12\201"+ + "\174\0\1\317\2\u0151\1\201\1\u0151\3\201\2\u0151\2\201"+ + "\1\u0151\4\201\1\u0151\11\201\1\320\12\201\174\0\1\317"+ + "\3\201\1\u0151\13\201\1\u0151\12\201\1\320\12\201\174\0"+ + "\1\317\3\201\2\u0151\2\201\2\u0151\1\201\2\u0151\1\201"+ + "\1\u0151\3\201\1\u0151\1\201\1\u0151\1\201\1\u0151\2\201"+ + "\1\u0151\1\201\1\320\12\201\27\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\151"+ + "\3\0\1\152\5\0\1\153\3\0\1\154\11\0\1\57"+ + "\2\0\1\155\16\0\1\156\2\0\1\157\41\0\1\25"+ + "\1\64\7\0\1\64\2\0\1\113\1\203\1\204\1\205"+ + "\1\206\1\207\1\210\1\211\1\212\1\213\1\214\1\215"+ + "\1\216\1\217\1\220\1\221\1\222\1\223\1\224\1\225"+ + "\1\226\1\227\1\230\1\231\1\232\1\233\1\234\1\114"+ + "\12\235\1\u0136\3\114\1\0\2\114\1\115\1\u0126\1\u0127"+ + "\1\u0128\3\0\1\114\1\140\3\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\151\3\0\1\152\5\0\1\153\3\0\1\154"+ + "\11\0\1\57\2\0\1\155\16\0\1\156\2\0\1\157"+ + "\41\0\1\25\1\64\7\0\1\64\3\0\32\25\1\0"+ + "\12\u0164\174\0\1\u0165\45\u0126\1\u014e\2\u0126\1\u0166\1\u014e"+ + "\2\u0126\1\u0167\2\u0126\1\u0128\2\0\1\u014e\1\u0126\4\0"+ + "\1\u0126\1\114\147\0\1\u0168\45\u0127\1\u014f\2\u0127\1\u0169"+ + "\1\0\2\114\1\u016a\1\u0126\1\u0127\1\u0128\2\0\1\u014f"+ + "\1\u0127\4\0\2\114\147\0\1\u016b\45\u0128\1\u0150\2\u0128"+ + "\1\u016c\1\u0150\2\u0128\1\u016d\2\u0128\1\114\2\0\1\u0150"+ + "\1\u0128\4\0\1\u0128\1\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\5\35\1\323\24\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\15\35\1\323\14\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\10\35\1\323\21\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\3\35\1\u016e\26\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\3\35\1\323\26\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\53"+ + "\3\0\1\54\5\0\1\55\3\0\1\56\11\0\1\57"+ + "\2\0\1\60\16\0\1\61\2\0\1\62\41\0\2\25"+ + "\1\63\1\0\1\64\1\0\1\64\1\65\1\0\1\25"+ + "\2\0\1\116\27\35\1\u016f\2\35\1\117\12\120\1\64"+ + "\1\114\1\121\1\114\1\0\1\114\1\122\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\113\32\235\1\u0170"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\16\35\1\323\13\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\151\3\0"+ + "\1\152\5\0\1\153\3\0\1\154\11\0\1\57\2\0"+ + "\1\155\16\0\1\156\2\0\1\157\41\0\1\25\1\64"+ + "\7\0\1\64\3\0\32\25\24\0\1\u0171\241\0\1\u0172"+ + "\15\0\1\46\1\0\1\47\1\0\1\50\1\0\1\51"+ + "\1\0\1\52\1\0\1\53\3\0\1\54\5\0\1\55"+ + "\3\0\1\56\11\0\1\57\2\0\1\60\16\0\1\61"+ + "\2\0\1\62\41\0\2\25\1\63\1\0\1\64\1\0"+ + "\1\64\1\65\1\0\1\25\2\0\1\116\32\35\1\117"+ + "\12\120\1\u0134\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\151\3\0\1\152\5\0\1\153\3\0\1\154"+ + "\11\0\1\57\2\0\1\155\16\0\1\156\2\0\1\157"+ + "\41\0\1\25\1\64\7\0\1\64\3\0\32\25\24\0"+ + "\1\u0173\162\0\1\113\1\244\1\245\1\246\1\247\1\250"+ + "\1\251\1\252\1\253\1\254\1\255\1\256\1\257\1\260"+ + "\1\261\1\262\1\263\1\264\1\265\1\266\1\267\1\270"+ + "\1\271\1\272\1\273\1\274\1\275\1\114\12\235\1\u0136"+ + "\3\114\1\0\2\114\1\115\1\u0126\1\u0127\1\u0128\3\0"+ + "\1\114\1\140\3\0\2\114\203\0\12\u0164\174\0\1\346"+ + "\5\235\1\353\24\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\15\235\1\353\14\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\10\235\1\353\21\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\3\235\1\u0174\26\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\3\235\1\353\26\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\27\235\1\u0175\2\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\16\235\1\353"+ + "\13\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\66\3\0\1\67\5\0\1\70\3\0\1\71\11\0"+ + "\1\57\2\0\1\72\16\0\1\73\2\0\1\74\41\0"+ + "\1\25\2\26\2\0\2\75\1\76\1\0\1\26\2\0"+ + "\1\u0176\32\35\1\117\12\u013f\1\0\1\114\1\127\1\114"+ + "\1\0\2\130\1\115\3\114\2\0\1\75\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\66\3\0\1\67\5\0"+ + "\1\70\3\0\1\71\11\0\1\57\2\0\1\72\16\0"+ + "\1\73\2\0\1\74\41\0\1\25\2\26\2\0\2\75"+ + "\1\76\1\0\1\26\2\0\1\u0176\32\35\1\117\12\u0177"+ + "\1\0\1\114\1\127\1\114\1\0\2\130\1\115\3\114"+ + "\2\0\1\75\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\66\3\0\1\67\5\0\1\70\3\0\1\71\11\0"+ + "\1\57\2\0\1\72\16\0\1\73\2\0\1\74\41\0"+ + "\1\25\2\26\2\0\2\75\1\76\1\0\1\26\2\0"+ + "\1\u0176\32\35\1\117\1\u013f\1\u0178\1\u0177\2\u013f\2\u0177"+ + "\2\u013f\1\u0177\1\0\1\114\1\127\1\114\1\0\2\130"+ + "\1\115\3\114\2\0\1\75\1\114\4\0\2\114\215\0"+ + "\1\305\174\0\4\u0179\2\0\1\u0179\15\0\1\u0179\6\0"+ + "\12\u0179\1\u0143\174\0\4\u017a\2\0\1\u017a\15\0\1\u017a"+ + "\6\0\12\u017a\1\u017b\174\0\4\u017c\2\0\1\u017c\15\0"+ + "\1\u017c\6\0\12\u017c\1\u017d\13\0\1\u0109\157\0\1\u014a"+ + "\4\u017c\2\0\1\u017c\15\0\1\u017c\6\0\12\u017e\1\u017d"+ + "\13\0\1\u0109\157\0\1\u014a\4\u017c\2\0\1\u017c\15\0"+ + "\1\u017c\6\0\12\u017f\1\u017d\13\0\1\u0109\157\0\1\u014a"+ + "\4\u017c\2\0\1\u017c\15\0\1\u017c\6\0\1\u017e\1\u0180"+ + "\1\u017f\2\u017e\2\u017f\2\u017e\1\u017f\1\u017d\13\0\1\u0109"+ + "\160\0\4\u0181\2\0\1\u0181\15\0\1\u0181\6\0\12\u0181"+ + "\1\u0149\13\0\1\u0109\160\0\4\u0144\2\0\1\u0144\15\0"+ + "\1\u0144\6\0\1\u0145\2\u0146\1\u0145\4\u0146\1\u0147\1\u0146"+ + "\230\0\1\u0182\2\u0183\1\u0182\4\u0183\1\u0184\1\u0183\174\0"+ + "\1\u014a\4\u0181\2\0\1\u0181\15\0\1\u0181\6\0\12\u0185"+ + "\1\u0149\13\0\1\u0109\157\0\1\u014a\4\u0181\2\0\1\u0181"+ + "\15\0\1\u0181\6\0\12\u0181\1\u0149\13\0\1\u0109\157\0"+ + "\1\u014a\4\u0181\2\0\1\u0181\15\0\1\u0181\6\0\2\u0185"+ + "\1\u0181\2\u0185\2\u0181\2\u0185\1\u0181\1\u0149\13\0\1\u0109"+ + "\157\0\51\u014e\1\u0186\6\u014e\1\u0150\2\0\2\u014e\4\0"+ + "\1\u014e\150\0\51\u014f\1\u0187\3\0\1\u014f\1\u014e\1\u014f"+ + "\1\u0150\2\0\2\u014f\155\0\51\u0150\1\u0188\6\u0150\3\0"+ + "\2\u0150\4\0\1\u0150\150\0\1\u0189\32\201\1\320\12\201"+ + "\174\0\1\u0189\4\201\1\u018a\25\201\1\320\12\201\174\0"+ + "\1\u0189\15\201\1\u0116\14\201\1\320\12\201\174\0\1\u0189"+ + "\10\201\1\u0116\21\201\1\320\12\201\174\0\1\u0189\17\201"+ + "\1\u0151\12\201\1\320\12\201\174\0\1\u0189\5\201\1\u018b"+ + "\4\201\1\u0151\17\201\1\320\12\201\174\0\1\317\20\201"+ + "\1\u0151\11\201\1\320\12\201\174\0\1\317\7\201\1\u0151"+ + "\22\201\1\320\12\201\174\0\1\317\27\201\1\u0151\2\201"+ + "\1\320\12\201\174\0\1\u0189\6\201\1\u018a\10\201\1\u0151"+ + "\12\201\1\320\12\201\174\0\1\u0189\24\201\1\u018c\5\201"+ + "\1\320\12\201\174\0\1\317\11\201\1\u0151\20\201\1\320"+ + "\12\201\174\0\1\u0189\16\201\1\u018d\13\201\1\320\12\201"+ + "\174\0\1\u0189\12\201\1\u018e\17\201\1\320\12\201\174\0"+ + "\1\u0189\5\201\1\u0151\24\201\1\320\12\201\174\0\1\u0189"+ + "\1\u018f\31\201\1\320\12\201\174\0\1\317\32\201\1\u0190"+ + "\12\201\174\0\1\u0189\23\201\1\u0151\6\201\1\320\12\201"+ + "\174\0\1\u0189\24\201\1\u0191\5\201\1\320\12\201\230\0"+ + "\12\u0192\10\0\1\u014e\1\u014f\1\u0150\161\0\1\u0165\45\u0126"+ + "\1\u014e\2\u0126\1\u0166\1\u014e\2\u0126\1\u0167\2\u0126\1\u0128"+ + "\2\0\1\u014e\1\u0126\1\140\3\0\1\u0126\1\114\147\0"+ + "\1\113\4\u0193\2\114\1\u0193\15\114\1\u0193\6\114\12\u0193"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\51\u014e\1\u0186\6\u014e\1\u0150\1\202"+ + "\1\0\2\u014e\4\0\1\u014e\150\0\1\u0168\45\u0127\1\u014f"+ + "\2\u0127\1\u0169\1\0\2\114\1\u016a\1\u0126\1\u0127\1\u0128"+ + "\2\0\1\u014f\1\u0127\1\140\3\0\2\114\147\0\1\113"+ + "\4\u0194\2\114\1\u0194\15\114\1\u0194\6\114\12\u0194\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\51\u014f\1\u0187\3\0\1\u014f\1\u014e\1\u014f"+ + "\1\u0150\1\202\1\0\2\u014f\155\0\1\u016b\45\u0128\1\u0150"+ + "\2\u0128\1\u016c\1\u0150\2\u0128\1\u016d\2\u0128\1\114\2\0"+ + "\1\u0150\1\u0128\1\140\3\0\1\u0128\1\114\147\0\1\113"+ + "\4\u0195\2\114\1\u0195\15\114\1\u0195\6\114\12\u0195\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\51\u0150\1\u0188\6\u0150\1\0\1\202\1\0"+ + "\2\u0150\4\0\1\u0150\3\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\20\35\1\u0196\11\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\53\3\0"+ + "\1\54\5\0\1\55\3\0\1\56\11\0\1\57\2\0"+ + "\1\60\16\0\1\61\2\0\1\62\41\0\2\25\1\63"+ + "\1\0\1\64\1\0\1\64\1\65\1\0\1\25\2\0"+ + "\1\116\3\35\1\336\26\35\1\117\12\120\1\64\1\114"+ + "\1\121\1\114\1\0\1\114\1\122\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\113\2\235\1\u0197\2\235"+ + "\1\u0198\1\u0199\1\u019a\2\235\1\u019b\2\235\1\u019c\3\235"+ + "\1\u019d\1\u019e\1\u019f\1\235\1\u01a0\1\u01a1\1\235\1\u01a2"+ + "\1\u01a3\1\117\1\u01a4\2\235\1\u01a5\1\235\1\u01a6\1\u01a7"+ + "\3\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\226\0\1\u01a8\162\0\1\u01a9\32\u01aa"+ + "\1\u01a9\12\u01aa\1\u01ab\2\u01a9\1\u01ac\3\u01a9\1\u01ad\3\0"+ + "\1\u01ae\1\0\2\u01a9\4\0\1\u01a9\227\0\1\u01af\162\0"+ + "\1\346\20\235\1\u01b0\11\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\3\235\1\366\26\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\14\0\1\165\3\0\1\166\5\0\1\167\3\0"+ + "\1\170\14\0\1\171\16\0\1\172\2\0\1\173\42\0"+ + "\1\75\1\26\6\0\1\75\2\0\1\113\1\244\1\245"+ + "\1\246\1\247\1\250\1\251\1\252\1\253\1\254\1\255"+ + "\1\256\1\257\1\260\1\261\1\262\1\263\1\264\1\265"+ + "\1\266\1\267\1\270\1\271\1\272\1\273\1\274\1\275"+ + "\1\114\1\u01b1\2\u01b2\1\u01b1\4\u01b2\1\u01b3\1\u01b2\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\1\140"+ + "\3\0\2\114\2\0\1\46\1\0\1\47\1\0\1\50"+ + "\1\0\1\51\1\0\1\52\1\0\1\66\3\0\1\67"+ + "\5\0\1\70\3\0\1\71\11\0\1\57\2\0\1\72"+ + "\16\0\1\73\2\0\1\74\41\0\1\25\2\26\2\0"+ + "\2\75\1\76\1\0\1\26\2\0\1\u0176\32\35\1\117"+ + "\12\301\1\0\1\114\1\127\1\114\1\0\2\130\1\115"+ + "\3\114\2\0\1\75\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\66\3\0\1\67\5\0\1\70\3\0\1\71"+ + "\11\0\1\57\2\0\1\72\16\0\1\73\2\0\1\74"+ + "\41\0\1\25\2\26\2\0\2\75\1\76\1\0\1\26"+ + "\2\0\1\u0176\32\35\1\117\2\u0177\1\301\2\u0177\2\301"+ + "\2\u0177\1\301\1\0\1\114\1\127\1\114\1\0\2\130"+ + "\1\115\3\114\2\0\1\75\1\114\4\0\2\114\150\0"+ + "\4\u01b4\2\0\1\u01b4\15\0\1\u01b4\6\0\12\u01b4\1\u0143"+ + "\174\0\4\u01b5\2\0\1\u01b5\15\0\1\u01b5\6\0\12\u01b5"+ + "\1\u01b6\174\0\4\u01b7\2\0\1\u01b7\15\0\1\u01b7\6\0"+ + "\1\u01b8\2\u01b9\1\u01b8\4\u01b9\1\u01ba\1\u01b9\14\0\1\u0109"+ + "\160\0\4\u01bb\2\0\1\u01bb\15\0\1\u01bb\6\0\12\u01bb"+ + "\1\u017d\13\0\1\u0109\160\0\4\u01b7\2\0\1\u01b7\15\0"+ + "\1\u01b7\6\0\1\u01b8\2\u01b9\1\u01b8\4\u01b9\1\u01ba\1\u01b9"+ + "\174\0\1\u014a\4\u01bb\2\0\1\u01bb\15\0\1\u01bb\6\0"+ + "\12\u01bc\1\u017d\13\0\1\u0109\157\0\1\u014a\4\u01bb\2\0"+ + "\1\u01bb\15\0\1\u01bb\6\0\12\u01bb\1\u017d\13\0\1\u0109"+ + "\157\0\1\u014a\4\u01bb\2\0\1\u01bb\15\0\1\u01bb\6\0"+ + "\2\u01bc\1\u01bb\2\u01bc\2\u01bb\2\u01bc\1\u01bb\1\u017d\13\0"+ + "\1\u0109\160\0\4\u01bd\2\0\1\u01bd\15\0\1\u01bd\6\0"+ + "\12\u01bd\1\u0149\13\0\1\u0109\157\0\1\u01be\33\0\12\u0183"+ + "\174\0\1\u01be\33\0\12\u01bf\174\0\1\u01be\33\0\1\u0183"+ + "\1\u01c0\1\u01bf\2\u0183\2\u01bf\2\u0183\1\u01bf\174\0\1\u014a"+ + "\4\u01bd\2\0\1\u01bd\15\0\1\u01bd\6\0\12\u01bd\1\u0149"+ + "\13\0\1\u0109\160\0\4\u01c1\2\0\1\u01c1\15\0\1\u01c1"+ + "\6\0\12\u01c1\175\0\4\u01c2\2\0\1\u01c2\15\0\1\u01c2"+ + "\6\0\12\u01c2\175\0\4\u01c3\2\0\1\u01c3\15\0\1\u01c3"+ + "\6\0\12\u01c3\174\0\1\317\5\201\1\u0151\24\201\1\320"+ + "\12\201\174\0\1\317\15\201\1\u0151\14\201\1\320\12\201"+ + "\174\0\1\317\10\201\1\u0151\21\201\1\320\12\201\174\0"+ + "\1\317\3\201\1\u01c4\26\201\1\320\12\201\174\0\1\317"+ + "\3\201\1\u0151\26\201\1\320\12\201\174\0\1\317\27\201"+ + "\1\u01c5\2\201\1\320\12\201\175\0\32\201\1\u01c6\12\201"+ + "\174\0\1\317\16\201\1\u0151\13\201\1\320\12\201\230\0"+ + "\12\u01c7\10\0\1\u014e\1\u014f\1\u0150\161\0\1\113\4\u0126"+ + "\2\114\1\u0126\15\114\1\u0126\6\114\12\u0126\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\113\4\u0127\2\114\1\u0127\15\114\1\u0127\6\114"+ + "\12\u0127\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\113\4\u0128\2\114\1\u0128"+ + "\15\114\1\u0128\6\114\12\u0128\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\2\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\53\3\0\1\54\5\0\1\55\3\0\1\56"+ + "\11\0\1\57\2\0\1\60\16\0\1\61\2\0\1\62"+ + "\41\0\2\25\1\63\1\0\1\64\1\0\1\64\1\65"+ + "\1\0\1\25\2\0\1\116\12\35\1\323\17\35\1\117"+ + "\12\120\1\64\1\114\1\121\1\114\1\0\1\114\1\122"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\3\235\1\u01c8\26\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\4\235\1\u01c9\5\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\10\235\1\u01ca\12\235\1\u01cb\6\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\2\235"+ + "\1\u01cc\7\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\7\235\1\u01cd"+ + "\22\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\7\235"+ + "\1\u01ce\22\235\1\117\3\235\1\u01cf\6\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\7\235\1\u01d0\22\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\31\235\1\u01d1\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\235\1\u01d2\30\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\7\235\1\u01d3\1\235\1\u01d4"+ + "\20\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\22\235"+ + "\1\u01d5\7\235\1\117\2\235\1\u01d6\7\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\7\235\1\u01d7\22\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\7\235\1\u01d8\5\235\1\u01d9\14\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\23\235\1\u01da"+ + "\6\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\32\235"+ + "\1\117\3\235\1\u01db\6\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\17\235\1\u01dc\12\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\1\u01dd\11\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\150\0"+ + "\32\u01de\1\0\12\u01de\11\0\1\u01df\1\0\1\u01e0\160\0"+ + "\46\u01a9\1\u01ab\2\u01a9\1\u01ac\3\u01a9\1\u01ad\5\0\2\u01a9"+ + "\4\0\1\u01a9\150\0\1\u01e1\32\u01aa\1\u01e2\12\u01aa\1\u01e3"+ + "\2\u01a9\1\u01ac\3\u01a9\1\u01ad\1\0\1\u01e4\3\0\2\u01a9"+ + "\4\0\1\u01a9\150\0\46\u01ab\1\0\2\u01ab\1\u01e5\3\u01ab"+ + "\1\u01ad\5\0\2\u01ab\4\0\1\u01ab\151\0\4\u01e6\2\0"+ + "\1\u01e6\15\0\1\u01e6\6\0\12\u01e6\175\0\32\u01e7\1\0"+ + "\12\u01e7\13\0\1\u01ae\161\0\4\u01e8\2\0\1\u01e8\15\0"+ + "\1\u01e8\6\0\12\u01e8\1\u01e9\173\0\1\u01ea\32\u01eb\1\u01ea"+ + "\12\u01eb\1\u01ec\2\u01ea\1\u01ed\3\u01ea\1\u01ee\3\0\1\u01ef"+ + "\1\0\2\u01ea\4\0\1\u01ea\150\0\1\346\12\235\1\353"+ + "\17\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\2\0\1\46\1\0"+ + "\1\47\1\0\1\50\1\0\1\51\1\0\1\52\1\0"+ + "\1\66\3\0\1\67\5\0\1\70\3\0\1\71\11\0"+ + "\1\57\2\0\1\72\16\0\1\73\2\0\1\74\41\0"+ + "\1\25\2\26\2\0\2\75\1\76\1\0\1\26\2\0"+ + "\1\u0101\32\35\1\117\12\u01b2\1\u0136\1\114\1\127\1\114"+ + "\1\0\2\130\1\115\1\u0126\1\u0127\1\u0128\2\0\1\75"+ + "\1\114\4\0\2\114\2\0\1\46\1\0\1\47\1\0"+ + "\1\50\1\0\1\51\1\0\1\52\1\0\1\66\3\0"+ + "\1\67\5\0\1\70\3\0\1\71\11\0\1\57\2\0"+ + "\1\72\16\0\1\73\2\0\1\74\41\0\1\25\2\26"+ + "\2\0\2\75\1\76\1\0\1\26\2\0\1\u0101\32\35"+ + "\1\117\12\u01f0\1\u0136\1\114\1\127\1\114\1\0\2\130"+ + "\1\115\1\u0126\1\u0127\1\u0128\2\0\1\75\1\114\4\0"+ + "\2\114\2\0\1\46\1\0\1\47\1\0\1\50\1\0"+ + "\1\51\1\0\1\52\1\0\1\66\3\0\1\67\5\0"+ + "\1\70\3\0\1\71\11\0\1\57\2\0\1\72\16\0"+ + "\1\73\2\0\1\74\41\0\1\25\2\26\2\0\2\75"+ + "\1\76\1\0\1\26\2\0\1\u0101\32\35\1\117\1\u01b2"+ + "\1\u01f1\1\u01f0\2\u01b2\2\u01f0\2\u01b2\1\u01f0\1\u0136\1\114"+ + "\1\127\1\114\1\0\2\130\1\115\1\u0126\1\u0127\1\u0128"+ + "\2\0\1\75\1\114\4\0\2\114\215\0\1\u0143\174\0"+ + "\4\u01f2\2\0\1\u01f2\15\0\1\u01f2\6\0\12\u01f2\1\u01b6"+ + "\174\0\4\u01f3\2\0\1\u01f3\15\0\1\u01f3\6\0\12\u01f3"+ + "\1\u01f4\174\0\4\u01f5\2\0\1\u01f5\15\0\1\u01f5\6\0"+ + "\12\u01f5\1\u01f6\13\0\1\u0109\157\0\1\u014a\4\u01f5\2\0"+ + "\1\u01f5\15\0\1\u01f5\6\0\12\u01f7\1\u01f6\13\0\1\u0109"+ + "\157\0\1\u014a\4\u01f5\2\0\1\u01f5\15\0\1\u01f5\6\0"+ + "\12\u01f8\1\u01f6\13\0\1\u0109\157\0\1\u014a\4\u01f5\2\0"+ + "\1\u01f5\15\0\1\u01f5\6\0\1\u01f7\1\u01f9\1\u01f8\2\u01f7"+ + "\2\u01f8\2\u01f7\1\u01f8\1\u01f6\13\0\1\u0109\160\0\4\u01fa"+ + "\2\0\1\u01fa\15\0\1\u01fa\6\0\12\u01fa\1\u017d\13\0"+ + "\1\u0109\157\0\1\u014a\4\u01fa\2\0\1\u01fa\15\0\1\u01fa"+ + "\6\0\12\u01fa\1\u017d\13\0\1\u0109\225\0\1\u0149\13\0"+ + "\1\u0109\213\0\1\u01fb\2\u01fc\1\u01fb\4\u01fc\1\u01fd\1\u01fc"+ + "\174\0\1\u01be\241\0\1\u01be\33\0\2\u01bf\1\0\2\u01bf"+ + "\2\0\2\u01bf\176\0\4\u014e\2\0\1\u014e\15\0\1\u014e"+ + "\6\0\12\u014e\175\0\4\u014f\2\0\1\u014f\15\0\1\u014f"+ + "\6\0\12\u014f\175\0\4\u0150\2\0\1\u0150\15\0\1\u0150"+ + "\6\0\12\u0150\174\0\1\317\20\201\1\u01fe\11\201\1\320"+ + "\12\201\174\0\1\317\3\201\1\u015c\26\201\1\320\12\201"+ + "\175\0\2\201\1\u01ff\2\201\1\u0200\1\u0201\1\u0202\2\201"+ + "\1\u0203\2\201\1\u0204\3\201\1\u0205\1\u0206\1\u0207\1\201"+ + "\1\u0208\1\u0209\1\201\1\u020a\1\u020b\1\320\1\u020c\2\201"+ + "\1\u020d\1\201\1\u020e\1\u020f\3\201\230\0\12\u0210\10\0"+ + "\1\u014e\1\u014f\1\u0150\161\0\1\346\24\235\1\u0211\5\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\1\235\1\u0212"+ + "\30\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\14\235"+ + "\1\u0213\15\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\235\1\u0214\30\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\21\235\1\u0215\10\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\24\235\1\u0216\5\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\24\235\1\u0217\5\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\1\u0139\31\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\24\235\1\u0218\5\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\1\235\1\u0219\30\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\31\235\1\u021a"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\24\235\1\u021b"+ + "\5\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\235"+ + "\1\u021c\30\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\u021d\31\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\21\235\1\u021e\10\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\24\235\1\u021f\5\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\24\235\1\u0220\5\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\4\235\1\u0221\25\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\21\235\1\u0222\10\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\24\235\1\u0223\5\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\7\235\1\u0224\2\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\u0225"+ + "\31\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\u0226\32\u01de"+ + "\1\u0227\12\u01de\11\0\1\u01df\162\0\51\u01df\1\u0228\3\0"+ + "\3\u01df\1\u0150\3\0\1\u01df\156\0\4\u0229\2\0\1\u0229"+ + "\15\0\1\u0229\6\0\12\u0229\1\u022a\173\0\1\u01a9\32\u01aa"+ + "\1\u01a9\12\u01aa\1\u01ab\2\u01a9\1\u01ac\3\u01a9\1\u01ad\5\0"+ + "\2\u01a9\4\0\1\u01a9\150\0\1\u01a9\32\u01aa\1\u01e2\12\u01aa"+ + "\1\u01ab\2\u01a9\1\u01ac\3\u01a9\1\u01ad\5\0\2\u01a9\4\0"+ + "\1\u01a9\150\0\34\u01ab\12\u022b\1\0\2\u01ab\1\u01e5\3\u01ab"+ + "\1\u01ad\5\0\2\u01ab\4\0\1\u01ab\150\0\51\u01e4\1\u022c"+ + "\3\0\3\u01e4\1\u0150\2\0\1\u022d\1\u01e4\156\0\4\u022e"+ + "\2\0\1\u022e\15\0\1\u022e\6\0\12\u022e\175\0\4\u01a9"+ + "\2\0\1\u01a9\15\0\1\u01a9\6\0\12\u01a9\174\0\1\u022f"+ + "\32\u01e7\1\u0230\12\u01e7\1\u0231\10\0\1\u01e4\163\0\4\u0232"+ + "\2\0\1\u0232\15\0\1\u0232\6\0\12\u0232\1\u0233\241\0"+ + "\1\u0234\173\0\46\u01ea\1\u01ec\2\u01ea\1\u01ed\3\u01ea\1\u01ee"+ + "\5\0\2\u01ea\4\0\1\u01ea\150\0\1\u0235\32\u01eb\1\u0236"+ + "\12\u01eb\1\u0237\2\u01ea\1\u01ed\3\u01ea\1\u01ee\1\u014e\1\u014f"+ + "\1\u0150\2\0\2\u01ea\4\0\1\u01ea\150\0\46\u01ec\1\0"+ + "\2\u01ec\1\u0238\3\u01ec\1\u01ee\5\0\2\u01ec\4\0\1\u01ec"+ + "\151\0\4\u0239\2\0\1\u0239\15\0\1\u0239\6\0\12\u0239"+ + "\175\0\32\u023a\1\0\12\u023a\13\0\1\u01ef\13\0\1\46"+ + "\1\0\1\47\1\0\1\50\1\0\1\51\1\0\1\52"+ + "\1\0\1\66\3\0\1\67\5\0\1\70\3\0\1\71"+ + "\11\0\1\57\2\0\1\72\16\0\1\73\2\0\1\74"+ + "\41\0\1\25\2\26\2\0\2\75\1\76\1\0\1\26"+ + "\2\0\1\u0101\32\35\1\117\12\301\1\u0136\1\114\1\127"+ + "\1\114\1\0\2\130\1\115\1\u0126\1\u0127\1\u0128\2\0"+ + "\1\75\1\114\4\0\2\114\2\0\1\46\1\0\1\47"+ + "\1\0\1\50\1\0\1\51\1\0\1\52\1\0\1\66"+ + "\3\0\1\67\5\0\1\70\3\0\1\71\11\0\1\57"+ + "\2\0\1\72\16\0\1\73\2\0\1\74\41\0\1\25"+ + "\2\26\2\0\2\75\1\76\1\0\1\26\2\0\1\u0101"+ + "\32\35\1\117\2\u01f0\1\301\2\u01f0\2\301\2\u01f0\1\301"+ + "\1\u0136\1\114\1\127\1\114\1\0\2\130\1\115\1\u0126"+ + "\1\u0127\1\u0128\2\0\1\75\1\114\4\0\2\114\150\0"+ + "\4\u023b\2\0\1\u023b\15\0\1\u023b\6\0\12\u023b\1\u01b6"+ + "\174\0\4\u023c\2\0\1\u023c\15\0\1\u023c\6\0\12\u023c"+ + "\1\u023d\174\0\4\u023e\2\0\1\u023e\15\0\1\u023e\6\0"+ + "\1\u023f\2\u0240\1\u023f\4\u0240\1\u0241\1\u0240\14\0\1\u0109"+ + "\160\0\4\u0242\2\0\1\u0242\15\0\1\u0242\6\0\12\u0242"+ + "\1\u01f6\13\0\1\u0109\160\0\4\u023e\2\0\1\u023e\15\0"+ + "\1\u023e\6\0\1\u023f\2\u0240\1\u023f\4\u0240\1\u0241\1\u0240"+ + "\174\0\1\u014a\4\u0242\2\0\1\u0242\15\0\1\u0242\6\0"+ + "\12\u0243\1\u01f6\13\0\1\u0109\157\0\1\u014a\4\u0242\2\0"+ + "\1\u0242\15\0\1\u0242\6\0\12\u0242\1\u01f6\13\0\1\u0109"+ + "\157\0\1\u014a\4\u0242\2\0\1\u0242\15\0\1\u0242\6\0"+ + "\2\u0243\1\u0242\2\u0243\2\u0242\2\u0243\1\u0242\1\u01f6\13\0"+ + "\1\u0109\225\0\1\u017d\13\0\1\u0109\157\0\1\u0244\33\0"+ + "\12\u01fc\174\0\1\u0244\33\0\12\u0245\174\0\1\u0244\33\0"+ + "\1\u01fc\1\u0246\1\u0245\2\u01fc\2\u0245\2\u01fc\1\u0245\174\0"+ + "\1\317\12\201\1\u0151\17\201\1\320\12\201\174\0\1\317"+ + "\3\201\1\u0247\26\201\1\320\12\201\174\0\1\317\32\201"+ + "\1\320\4\201\1\u0248\5\201\174\0\1\317\10\201\1\u0249"+ + "\12\201\1\u024a\6\201\1\320\12\201\174\0\1\317\32\201"+ + "\1\320\2\201\1\u024b\7\201\174\0\1\317\7\201\1\u024c"+ + "\22\201\1\320\12\201\174\0\1\317\7\201\1\u024d\22\201"+ + "\1\320\3\201\1\u024e\6\201\174\0\1\317\7\201\1\u024f"+ + "\22\201\1\320\12\201\174\0\1\317\31\201\1\u0250\1\320"+ + "\12\201\174\0\1\317\1\201\1\u0251\30\201\1\320\12\201"+ + "\174\0\1\317\7\201\1\u0252\1\201\1\u0253\20\201\1\320"+ + "\12\201\174\0\1\317\22\201\1\u0254\7\201\1\320\2\201"+ + "\1\u0255\7\201\174\0\1\317\7\201\1\u0256\22\201\1\320"+ + "\12\201\174\0\1\317\7\201\1\u0257\5\201\1\u0258\14\201"+ + "\1\320\12\201\174\0\1\317\23\201\1\u0259\6\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\3\201\1\u025a\6\201"+ + "\174\0\1\317\17\201\1\u025b\12\201\1\320\12\201\174\0"+ + "\1\317\32\201\1\320\1\u025c\11\201\230\0\12\u025d\10\0"+ + "\1\u014e\1\u014f\1\u0150\161\0\1\346\1\u025e\31\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\21\235\1\u025f\10\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\16\235\1\u0260"+ + "\4\235\1\u0261\6\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\10\235\1\u0262\1\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\10\235\1\u0263\1\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\u0264\2\235\1\u0265\26\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\16\235\1\u0266\13\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\11\235\1\u0267"+ + "\13\235\1\u0268\4\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\10\235\1\u0269\1\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\23\235\1\u026a\6\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\31\235\1\u026b\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\26\235\1\u026c\3\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\11\235\1\u026d\20\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\3\235"+ + "\1\u026e\6\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\10\235\1\u026f"+ + "\21\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\3\235"+ + "\1\u0270\26\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\21\235\1\u0271\6\235\1\u0272\1\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\12\235\1\u0273\17\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\32\235\1\117\1\235\1\u0274"+ + "\10\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\24\235\1\u0275\5\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\31\235\1\u0276"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\150\0\32\u01de\1\0\12\u01de"+ + "\175\0\32\u01de\1\u0227\12\u01de\175\0\4\u0277\2\0\1\u0277"+ + "\15\0\1\u0277\6\0\12\u0277\175\0\4\u0278\2\0\1\u0278"+ + "\15\0\1\u0278\6\0\12\u0278\1\u0279\241\0\1\u027a\173\0"+ + "\34\u01ab\12\u027b\1\0\2\u01ab\1\u01e5\3\u01ab\1\u01ad\1\0"+ + "\1\u01e4\3\0\2\u01ab\4\0\1\u01ab\151\0\4\u027c\2\0"+ + "\1\u027c\15\0\1\u027c\6\0\12\u027c\214\0\1\u027d\222\0"+ + "\4\u01ab\2\0\1\u01ab\15\0\1\u01ab\6\0\12\u01ab\175\0"+ + "\32\u01e7\1\0\12\u01e7\175\0\32\u01e7\1\u0230\12\u01e7\230\0"+ + "\12\u027e\175\0\4\u027f\2\0\1\u027f\15\0\1\u027f\6\0"+ + "\12\u027f\1\u0233\174\0\4\u0280\2\0\1\u0280\15\0\1\u0280"+ + "\6\0\12\u0280\1\u0281\174\0\4\u0282\2\0\1\u0282\15\0"+ + "\1\u0282\6\0\1\u0283\2\u0284\1\u0283\4\u0284\1\u0285\1\u0284"+ + "\14\0\1\u0286\157\0\1\u01ea\32\u01eb\1\u01ea\12\u01eb\1\u01ec"+ + "\2\u01ea\1\u01ed\3\u01ea\1\u01ee\5\0\2\u01ea\4\0\1\u01ea"+ + "\150\0\1\u01ea\32\u01eb\1\u0236\12\u01eb\1\u01ec\2\u01ea\1\u01ed"+ + "\3\u01ea\1\u01ee\5\0\2\u01ea\4\0\1\u01ea\150\0\34\u01ec"+ + "\12\u0287\1\0\2\u01ec\1\u0238\3\u01ec\1\u01ee\5\0\2\u01ec"+ + "\4\0\1\u01ec\151\0\4\u0288\2\0\1\u0288\15\0\1\u0288"+ + "\6\0\12\u0288\175\0\4\u01ea\2\0\1\u01ea\15\0\1\u01ea"+ + "\6\0\12\u01ea\174\0\1\u0289\32\u023a\1\u028a\12\u023a\1\u0136"+ + "\7\0\1\u014e\1\u014f\1\u0150\227\0\1\u01b6\174\0\4\u028b"+ + "\2\0\1\u028b\15\0\1\u028b\6\0\12\u028b\1\u023d\174\0"+ + "\4\u028c\2\0\1\u028c\15\0\1\u028c\6\0\12\u028c\1\u028d"+ + "\174\0\4\u028e\2\0\1\u028e\15\0\1\u028e\6\0\12\u028e"+ + "\1\u028f\13\0\1\u0109\157\0\1\u014a\4\u028e\2\0\1\u028e"+ + "\15\0\1\u028e\6\0\12\u0290\1\u028f\13\0\1\u0109\157\0"+ + "\1\u014a\4\u028e\2\0\1\u028e\15\0\1\u028e\6\0\12\u0291"+ + "\1\u028f\13\0\1\u0109\157\0\1\u014a\4\u028e\2\0\1\u028e"+ + "\15\0\1\u028e\6\0\1\u0290\1\u0292\1\u0291\2\u0290\2\u0291"+ + "\2\u0290\1\u0291\1\u028f\13\0\1\u0109\160\0\4\u0293\2\0"+ + "\1\u0293\15\0\1\u0293\6\0\12\u0293\1\u01f6\13\0\1\u0109"+ + "\157\0\1\u014a\4\u0293\2\0\1\u0293\15\0\1\u0293\6\0"+ + "\12\u0293\1\u01f6\13\0\1\u0109\213\0\1\u0294\2\u0295\1\u0294"+ + "\4\u0295\1\u0296\1\u0295\174\0\1\u0244\241\0\1\u0244\33\0"+ + "\2\u0245\1\0\2\u0245\2\0\2\u0245\175\0\1\317\24\201"+ + "\1\u0297\5\201\1\320\12\201\174\0\1\317\1\201\1\u0298"+ + "\30\201\1\320\12\201\174\0\1\317\14\201\1\u0299\15\201"+ + "\1\320\12\201\174\0\1\317\1\201\1\u029a\30\201\1\320"+ + "\12\201\174\0\1\317\21\201\1\u029b\10\201\1\320\12\201"+ + "\174\0\1\317\24\201\1\u029c\5\201\1\320\12\201\174\0"+ + "\1\317\24\201\1\u029d\5\201\1\320\12\201\174\0\1\317"+ + "\1\u018c\31\201\1\320\12\201\174\0\1\317\24\201\1\u029e"+ + "\5\201\1\320\12\201\174\0\1\317\1\201\1\u029f\30\201"+ + "\1\320\12\201\174\0\1\317\31\201\1\u02a0\1\320\12\201"+ + "\174\0\1\317\24\201\1\u02a1\5\201\1\320\12\201\174\0"+ + "\1\317\1\201\1\u02a2\30\201\1\320\12\201\174\0\1\317"+ + "\1\u02a3\31\201\1\320\12\201\174\0\1\317\21\201\1\u02a4"+ + "\10\201\1\320\12\201\174\0\1\317\24\201\1\u02a5\5\201"+ + "\1\320\12\201\174\0\1\317\24\201\1\u02a6\5\201\1\320"+ + "\12\201\174\0\1\317\4\201\1\u02a7\25\201\1\320\12\201"+ + "\174\0\1\317\21\201\1\u02a8\10\201\1\320\12\201\174\0"+ + "\1\317\24\201\1\u02a9\5\201\1\320\12\201\174\0\1\317"+ + "\32\201\1\320\7\201\1\u02aa\2\201\174\0\1\317\1\u02ab"+ + "\31\201\1\320\12\201\252\0\1\u014e\1\u014f\1\u0150\161\0"+ + "\1\346\32\235\1\117\1\u02ac\11\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\7\235\1\u02ad\2\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\6\235\1\u013d\3\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\32\235\1\117\5\235\1\u013d\4\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\1\235\1\u02ae\30\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\1\235"+ + "\1\u02af\10\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\1\u02b0\27\235"+ + "\1\u02b1\1\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\4\235\1\u02b2\25\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\1\u02b3\11\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\2\235\1\260\7\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\3\235\1\u02b4\6\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\u02b5\31\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\u02ad\31\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\32\235\1\117\2\235\1\u02b6\7\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\32\235\1\117\2\235\1\u02b7"+ + "\7\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\15\235\1\u02b8\14\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\5\235\1\u02b9\4\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\32\235"+ + "\1\117\10\235\1\u02ba\1\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\235\1\u02bb\30\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\3\235\1\u02bc\6\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\1\235\1\u02bd\10\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\32\235\1\117\1\235\1\u02be\10\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\24\235\1\u02bf\5\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\3\235"+ + "\1\u02c0\6\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\25\235\1\u02c1"+ + "\4\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\150\0\4\u01df\2\0"+ + "\1\u01df\15\0\1\u01df\6\0\12\u01df\175\0\4\u02c2\2\0"+ + "\1\u02c2\15\0\1\u02c2\6\0\12\u02c2\1\u0279\174\0\4\u02c3"+ + "\2\0\1\u02c3\15\0\1\u02c3\6\0\12\u02c3\1\u02c4\174\0"+ + "\4\u02c5\2\0\1\u02c5\15\0\1\u02c5\6\0\1\u02c6\2\u02c7"+ + "\1\u02c6\4\u02c7\1\u02c8\1\u02c7\14\0\1\u02c9\157\0\34\u01ab"+ + "\12\u02ca\1\0\2\u01ab\1\u01e5\3\u01ab\1\u01ad\1\0\1\u01e4"+ + "\3\0\2\u01ab\4\0\1\u01ab\151\0\4\u01e4\2\0\1\u01e4"+ + "\15\0\1\u01e4\6\0\12\u01e4\225\0\1\u02cb\244\0\12\u02cc"+ + "\11\0\1\u01e4\163\0\4\u02cd\2\0\1\u02cd\15\0\1\u02cd"+ + "\6\0\12\u02cd\1\u0233\174\0\4\u02ce\2\0\1\u02ce\15\0"+ + "\1\u02ce\6\0\12\u02ce\1\u02cf\174\0\4\u02d0\2\0\1\u02d0"+ + "\15\0\1\u02d0\6\0\1\u02d1\2\u02d2\1\u02d1\4\u02d2\1\u02d3"+ + "\1\u02d2\14\0\1\u0286\160\0\4\u02d4\2\0\1\u02d4\15\0"+ + "\1\u02d4\6\0\12\u02d4\1\u02d5\13\0\1\u0286\157\0\1\u02d6"+ + "\4\u02d4\2\0\1\u02d4\15\0\1\u02d4\6\0\12\u02d7\1\u02d5"+ + "\13\0\1\u0286\157\0\1\u02d6\4\u02d4\2\0\1\u02d4\15\0"+ + "\1\u02d4\6\0\12\u02d8\1\u02d5\13\0\1\u0286\157\0\1\u02d6"+ + "\4\u02d4\2\0\1\u02d4\15\0\1\u02d4\6\0\1\u02d7\1\u02d9"+ + "\1\u02d8\2\u02d7\2\u02d8\2\u02d7\1\u02d8\1\u02d5\13\0\1\u0286"+ + "\225\0\1\u0231\10\0\1\u01e4\162\0\34\u01ec\12\u02da\1\0"+ + "\2\u01ec\1\u0238\3\u01ec\1\u01ee\1\u014e\1\u014f\1\u0150\2\0"+ + "\2\u01ec\4\0\1\u01ec\151\0\4\u01ec\2\0\1\u01ec\15\0"+ + "\1\u01ec\6\0\12\u01ec\175\0\32\u023a\1\0\12\u023a\175\0"+ + "\32\u023a\1\u028a\12\u023a\175\0\4\u02db\2\0\1\u02db\15\0"+ + "\1\u02db\6\0\12\u02db\1\u023d\174\0\4\u02dc\2\0\1\u02dc"+ + "\15\0\1\u02dc\6\0\12\u02dc\1\u02dd\174\0\4\u02de\2\0"+ + "\1\u02de\15\0\1\u02de\6\0\1\u02df\2\u02e0\1\u02df\4\u02e0"+ + "\1\u02e1\1\u02e0\14\0\1\u0109\160\0\4\u02e2\2\0\1\u02e2"+ + "\15\0\1\u02e2\6\0\12\u02e2\1\u028f\13\0\1\u0109\160\0"+ + "\4\u02de\2\0\1\u02de\15\0\1\u02de\6\0\1\u02df\2\u02e0"+ + "\1\u02df\4\u02e0\1\u02e1\1\u02e0\174\0\1\u014a\4\u02e2\2\0"+ + "\1\u02e2\15\0\1\u02e2\6\0\12\u02e3\1\u028f\13\0\1\u0109"+ + "\157\0\1\u014a\4\u02e2\2\0\1\u02e2\15\0\1\u02e2\6\0"+ + "\12\u02e2\1\u028f\13\0\1\u0109\157\0\1\u014a\4\u02e2\2\0"+ + "\1\u02e2\15\0\1\u02e2\6\0\2\u02e3\1\u02e2\2\u02e3\2\u02e2"+ + "\2\u02e3\1\u02e2\1\u028f\13\0\1\u0109\225\0\1\u01f6\13\0"+ + "\1\u0109\213\0\12\u0295\14\0\1\u0109\213\0\12\u02e4\14\0"+ + "\1\u0109\213\0\1\u0295\1\u02e5\1\u02e4\2\u0295\2\u02e4\2\u0295"+ + "\1\u02e4\14\0\1\u0109\157\0\1\317\1\u02e6\31\201\1\320"+ + "\12\201\174\0\1\317\21\201\1\u02e7\10\201\1\320\12\201"+ + "\174\0\1\317\16\201\1\u02e8\4\201\1\u02e9\6\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\10\201\1\u02ea\1\201"+ + "\174\0\1\317\32\201\1\320\10\201\1\u02eb\1\201\174\0"+ + "\1\317\1\u02ec\2\201\1\u02ed\26\201\1\320\12\201\174\0"+ + "\1\317\16\201\1\u02ee\13\201\1\320\12\201\174\0\1\317"+ + "\11\201\1\u02ef\13\201\1\u02f0\4\201\1\320\12\201\174\0"+ + "\1\317\32\201\1\320\10\201\1\u02f1\1\201\174\0\1\317"+ + "\23\201\1\u02f2\6\201\1\320\12\201\174\0\1\317\31\201"+ + "\1\u02f3\1\320\12\201\174\0\1\317\26\201\1\u02f4\3\201"+ + "\1\320\12\201\174\0\1\317\11\201\1\u02f5\20\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\3\201\1\u02f6\6\201"+ + "\174\0\1\317\10\201\1\u02f7\21\201\1\320\12\201\174\0"+ + "\1\317\3\201\1\u02f8\26\201\1\320\12\201\174\0\1\317"+ + "\21\201\1\u02f9\6\201\1\u02fa\1\201\1\320\12\201\174\0"+ + "\1\317\12\201\1\u02fb\17\201\1\320\12\201\174\0\1\317"+ + "\32\201\1\320\1\201\1\u02fc\10\201\174\0\1\317\24\201"+ + "\1\u02fd\5\201\1\320\12\201\174\0\1\317\31\201\1\u02fe"+ + "\1\320\12\201\174\0\1\346\1\u02ff\31\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\25\235\1\353\4\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\5\235"+ + "\1\u0300\4\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\3\235\1\u02ff\6\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\12\235"+ + "\1\u0301\17\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\25\235\1\u0302\4\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\15\235\1\u0303\14\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\2\235\1\u02ad\27\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\1\235\1\353\30\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\11\235\1\u0304\20\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\1\u0305\31\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\1\u0306\31\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\2\235\1\u0307\27\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\4\235\1\362\5\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\u0308"+ + "\31\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\25\235"+ + "\1\u0309\4\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\117\4\235\1\u02ff\5\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\11\235\1\u02ff\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\2\235\1\u02ff\7\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\16\235\1\u030a\13\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\32\235\1\117\3\235\1\u030b\6\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\24\235\1\u030c\5\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\150\0\4\u030d\2\0\1\u030d\15\0"+ + "\1\u030d\6\0\12\u030d\1\u0279\174\0\4\u030e\2\0\1\u030e"+ + "\15\0\1\u030e\6\0\12\u030e\1\u030f\174\0\4\u0310\2\0"+ + "\1\u0310\15\0\1\u0310\6\0\1\u0311\2\u0312\1\u0311\4\u0312"+ + "\1\u0313\1\u0312\14\0\1\u02c9\160\0\4\u0314\2\0\1\u0314"+ + "\15\0\1\u0314\6\0\12\u0314\1\u0315\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u0314\2\0\1\u0314\15\0\1\u0314\6\0\12\u0317"+ + "\1\u0315\13\0\1\u02c9\157\0\1\u0316\4\u0314\2\0\1\u0314"+ + "\15\0\1\u0314\6\0\12\u0318\1\u0315\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u0314\2\0\1\u0314\15\0\1\u0314\6\0\1\u0317"+ + "\1\u0319\1\u0318\2\u0317\2\u0318\2\u0317\1\u0318\1\u0315\13\0"+ + "\1\u02c9\236\0\1\u01df\162\0\34\u01ab\12\u031a\1\0\2\u01ab"+ + "\1\u01e5\3\u01ab\1\u01ad\1\0\1\u01e4\3\0\2\u01ab\4\0"+ + "\1\u01ab\166\0\1\u031b\257\0\12\u031c\11\0\1\u01e4\230\0"+ + "\1\u0233\174\0\4\u031d\2\0\1\u031d\15\0\1\u031d\6\0"+ + "\12\u031d\1\u02cf\174\0\4\u031e\2\0\1\u031e\15\0\1\u031e"+ + "\6\0\12\u031e\1\u031f\174\0\4\u0320\2\0\1\u0320\15\0"+ + "\1\u0320\6\0\12\u0320\1\u0321\13\0\1\u0286\157\0\1\u02d6"+ + "\4\u0320\2\0\1\u0320\15\0\1\u0320\6\0\12\u0322\1\u0321"+ + "\13\0\1\u0286\157\0\1\u02d6\4\u0320\2\0\1\u0320\15\0"+ + "\1\u0320\6\0\12\u0323\1\u0321\13\0\1\u0286\157\0\1\u02d6"+ + "\4\u0320\2\0\1\u0320\15\0\1\u0320\6\0\1\u0322\1\u0324"+ + "\1\u0323\2\u0322\2\u0323\2\u0322\1\u0323\1\u0321\13\0\1\u0286"+ + "\160\0\4\u0325\2\0\1\u0325\15\0\1\u0325\6\0\12\u0325"+ + "\1\u02d5\13\0\1\u0286\160\0\4\u02d0\2\0\1\u02d0\15\0"+ + "\1\u02d0\6\0\1\u02d1\2\u02d2\1\u02d1\4\u02d2\1\u02d3\1\u02d2"+ + "\230\0\1\u0326\2\u0327\1\u0326\4\u0327\1\u0328\1\u0327\174\0"+ + "\1\u02d6\4\u0325\2\0\1\u0325\15\0\1\u0325\6\0\12\u0329"+ + "\1\u02d5\13\0\1\u0286\157\0\1\u02d6\4\u0325\2\0\1\u0325"+ + "\15\0\1\u0325\6\0\12\u0325\1\u02d5\13\0\1\u0286\157\0"+ + "\1\u02d6\4\u0325\2\0\1\u0325\15\0\1\u0325\6\0\2\u0329"+ + "\1\u0325\2\u0329\2\u0325\2\u0329\1\u0325\1\u02d5\13\0\1\u0286"+ + "\157\0\34\u01ec\12\u032a\1\0\2\u01ec\1\u0238\3\u01ec\1\u01ee"+ + "\1\u014e\1\u014f\1\u0150\2\0\2\u01ec\4\0\1\u01ec\216\0"+ + "\1\u023d\174\0\4\u032b\2\0\1\u032b\15\0\1\u032b\6\0"+ + "\12\u032b\1\u02dd\174\0\4\u032c\2\0\1\u032c\15\0\1\u032c"+ + "\6\0\12\u032c\1\u032d\174\0\4\u032e\2\0\1\u032e\15\0"+ + "\1\u032e\6\0\12\u032e\1\u032f\13\0\1\u0109\157\0\1\u014a"+ + "\4\u032e\2\0\1\u032e\15\0\1\u032e\6\0\12\u0330\1\u032f"+ + "\13\0\1\u0109\157\0\1\u014a\4\u032e\2\0\1\u032e\15\0"+ + "\1\u032e\6\0\12\u0331\1\u032f\13\0\1\u0109\157\0\1\u014a"+ + "\4\u032e\2\0\1\u032e\15\0\1\u032e\6\0\1\u0330\1\u0332"+ + "\1\u0331\2\u0330\2\u0331\2\u0330\1\u0331\1\u032f\13\0\1\u0109"+ + "\160\0\4\u0333\2\0\1\u0333\15\0\1\u0333\6\0\12\u0333"+ + "\1\u028f\13\0\1\u0109\157\0\1\u014a\4\u0333\2\0\1\u0333"+ + "\15\0\1\u0333\6\0\12\u0333\1\u028f\13\0\1\u0109\241\0"+ + "\1\u0109\213\0\2\u02e4\1\0\2\u02e4\2\0\2\u02e4\15\0"+ + "\1\u0109\157\0\1\317\32\201\1\320\1\u0334\11\201\174\0"+ + "\1\317\32\201\1\320\7\201\1\u0335\2\201\174\0\1\317"+ + "\32\201\1\320\6\201\1\u0191\3\201\174\0\1\317\32\201"+ + "\1\320\5\201\1\u0191\4\201\174\0\1\317\1\201\1\u0336"+ + "\30\201\1\320\12\201\174\0\1\317\32\201\1\320\1\201"+ + "\1\u0337\10\201\174\0\1\317\1\u0338\27\201\1\u0339\1\201"+ + "\1\320\12\201\174\0\1\317\4\201\1\u033a\25\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\1\u033b\11\201\174\0"+ + "\1\317\32\201\1\320\2\201\1\u0116\7\201\174\0\1\317"+ + "\32\201\1\320\3\201\1\u033c\6\201\174\0\1\317\1\u033d"+ + "\31\201\1\320\12\201\174\0\1\317\1\u0335\31\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\2\201\1\u033e\7\201"+ + "\174\0\1\317\32\201\1\320\2\201\1\u033f\7\201\174\0"+ + "\1\317\15\201\1\u0340\14\201\1\320\12\201\174\0\1\317"+ + "\32\201\1\320\5\201\1\u0341\4\201\174\0\1\317\32\201"+ + "\1\320\10\201\1\u0342\1\201\174\0\1\317\1\201\1\u0343"+ + "\30\201\1\320\12\201\174\0\1\317\32\201\1\320\3\201"+ + "\1\u0344\6\201\174\0\1\317\32\201\1\320\1\201\1\u0345"+ + "\10\201\174\0\1\317\32\201\1\320\1\201\1\u0346\10\201"+ + "\174\0\1\317\24\201\1\u0347\5\201\1\320\12\201\174\0"+ + "\1\317\32\201\1\320\3\201\1\u0348\6\201\174\0\1\317"+ + "\25\201\1\u0349\4\201\1\320\12\201\174\0\1\346\2\235"+ + "\1\353\27\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\3\235\1\u034a\26\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\11\235\1\u034b\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\11\235\1\u034c\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\7\235\1\u034d\2\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\4\235\1\u034e\5\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\26\235\1\u034f\3\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\30\235\1\u0350\1\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\11\235\1\u0138\20\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\12\235\1\u0351"+ + "\17\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\17\235"+ + "\1\363\12\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\117\4\235\1\u0352\5\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\30\235\1\u0353\1\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\30\235\1\u0354\1\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\215\0\1\u0279\174\0\4\u0355\2\0\1\u0355\15\0"+ + "\1\u0355\6\0\12\u0355\1\u030f\174\0\4\u0356\2\0\1\u0356"+ + "\15\0\1\u0356\6\0\12\u0356\1\u0357\174\0\4\u0358\2\0"+ + "\1\u0358\15\0\1\u0358\6\0\12\u0358\1\u0359\13\0\1\u02c9"+ + "\157\0\1\u0316\4\u0358\2\0\1\u0358\15\0\1\u0358\6\0"+ + "\12\u035a\1\u0359\13\0\1\u02c9\157\0\1\u0316\4\u0358\2\0"+ + "\1\u0358\15\0\1\u0358\6\0\12\u035b\1\u0359\13\0\1\u02c9"+ + "\157\0\1\u0316\4\u0358\2\0\1\u0358\15\0\1\u0358\6\0"+ + "\1\u035a\1\u035c\1\u035b\2\u035a\2\u035b\2\u035a\1\u035b\1\u0359"+ + "\13\0\1\u02c9\160\0\4\u035d\2\0\1\u035d\15\0\1\u035d"+ + "\6\0\12\u035d\1\u0315\13\0\1\u02c9\160\0\4\u0310\2\0"+ + "\1\u0310\15\0\1\u0310\6\0\1\u0311\2\u0312\1\u0311\4\u0312"+ + "\1\u0313\1\u0312\230\0\1\u035e\2\u035f\1\u035e\4\u035f\1\u0360"+ + "\1\u035f\174\0\1\u0316\4\u035d\2\0\1\u035d\15\0\1\u035d"+ + "\6\0\12\u0361\1\u0315\13\0\1\u02c9\157\0\1\u0316\4\u035d"+ + "\2\0\1\u035d\15\0\1\u035d\6\0\12\u035d\1\u0315\13\0"+ + "\1\u02c9\157\0\1\u0316\4\u035d\2\0\1\u035d\15\0\1\u035d"+ + "\6\0\2\u0361\1\u035d\2\u0361\2\u035d\2\u0361\1\u035d\1\u0315"+ + "\13\0\1\u02c9\157\0\34\u01ab\12\u0362\1\0\2\u01ab\1\u01e5"+ + "\3\u01ab\1\u01ad\1\0\1\u01e4\3\0\2\u01ab\4\0\1\u01ab"+ + "\154\0\1\u0363\271\0\12\u0364\11\0\1\u01e4\163\0\4\u0365"+ + "\2\0\1\u0365\15\0\1\u0365\6\0\12\u0365\1\u02cf\174\0"+ + "\4\u0366\2\0\1\u0366\15\0\1\u0366\6\0\12\u0366\1\u0367"+ + "\174\0\4\u0368\2\0\1\u0368\15\0\1\u0368\6\0\1\u0369"+ + "\2\u036a\1\u0369\4\u036a\1\u036b\1\u036a\14\0\1\u0286\160\0"+ + "\4\u036c\2\0\1\u036c\15\0\1\u036c\6\0\12\u036c\1\u0321"+ + "\13\0\1\u0286\160\0\4\u0368\2\0\1\u0368\15\0\1\u0368"+ + "\6\0\1\u0369\2\u036a\1\u0369\4\u036a\1\u036b\1\u036a\174\0"+ + "\1\u02d6\4\u036c\2\0\1\u036c\15\0\1\u036c\6\0\12\u036d"+ + "\1\u0321\13\0\1\u0286\157\0\1\u02d6\4\u036c\2\0\1\u036c"+ + "\15\0\1\u036c\6\0\12\u036c\1\u0321\13\0\1\u0286\157\0"+ + "\1\u02d6\4\u036c\2\0\1\u036c\15\0\1\u036c\6\0\2\u036d"+ + "\1\u036c\2\u036d\2\u036c\2\u036d\1\u036c\1\u0321\13\0\1\u0286"+ + "\160\0\4\u036e\2\0\1\u036e\15\0\1\u036e\6\0\12\u036e"+ + "\1\u02d5\13\0\1\u0286\157\0\1\u036f\33\0\12\u0327\174\0"+ + "\1\u036f\33\0\12\u0370\174\0\1\u036f\33\0\1\u0327\1\u0371"+ + "\1\u0370\2\u0327\2\u0370\2\u0327\1\u0370\174\0\1\u02d6\4\u036e"+ + "\2\0\1\u036e\15\0\1\u036e\6\0\12\u036e\1\u02d5\13\0"+ + "\1\u0286\157\0\34\u01ec\12\u0372\1\0\2\u01ec\1\u0238\3\u01ec"+ + "\1\u01ee\1\u014e\1\u014f\1\u0150\2\0\2\u01ec\4\0\1\u01ec"+ + "\151\0\4\u0373\2\0\1\u0373\15\0\1\u0373\6\0\12\u0373"+ + "\1\u02dd\174\0\4\u0374\2\0\1\u0374\15\0\1\u0374\6\0"+ + "\12\u0374\1\u0375\174\0\4\u0376\2\0\1\u0376\15\0\1\u0376"+ + "\6\0\1\u0377\2\u0378\1\u0377\4\u0378\1\u0379\1\u0378\14\0"+ + "\1\u0109\160\0\4\u037a\2\0\1\u037a\15\0\1\u037a\6\0"+ + "\12\u037a\1\u032f\13\0\1\u0109\160\0\4\u0376\2\0\1\u0376"+ + "\15\0\1\u0376\6\0\1\u0377\2\u0378\1\u0377\4\u0378\1\u0379"+ + "\1\u0378\174\0\1\u014a\4\u037a\2\0\1\u037a\15\0\1\u037a"+ + "\6\0\12\u037b\1\u032f\13\0\1\u0109\157\0\1\u014a\4\u037a"+ + "\2\0\1\u037a\15\0\1\u037a\6\0\12\u037a\1\u032f\13\0"+ + "\1\u0109\157\0\1\u014a\4\u037a\2\0\1\u037a\15\0\1\u037a"+ + "\6\0\2\u037b\1\u037a\2\u037b\2\u037a\2\u037b\1\u037a\1\u032f"+ + "\13\0\1\u0109\225\0\1\u028f\13\0\1\u0109\157\0\1\317"+ + "\1\u037c\31\201\1\320\12\201\174\0\1\317\25\201\1\u0151"+ + "\4\201\1\320\12\201\174\0\1\317\32\201\1\320\5\201"+ + "\1\u037d\4\201\174\0\1\317\32\201\1\320\3\201\1\u037c"+ + "\6\201\174\0\1\317\12\201\1\u037e\17\201\1\320\12\201"+ + "\174\0\1\317\25\201\1\u037f\4\201\1\320\12\201\174\0"+ + "\1\317\15\201\1\u0380\14\201\1\320\12\201\174\0\1\317"+ + "\2\201\1\u0335\27\201\1\320\12\201\174\0\1\317\1\201"+ + "\1\u0151\30\201\1\320\12\201\174\0\1\317\11\201\1\u0381"+ + "\20\201\1\320\12\201\174\0\1\317\1\u0382\31\201\1\320"+ + "\12\201\174\0\1\317\1\u0383\31\201\1\320\12\201\174\0"+ + "\1\317\2\201\1\u0384\27\201\1\320\12\201\174\0\1\317"+ + "\32\201\1\320\4\201\1\u0158\5\201\174\0\1\317\1\u0385"+ + "\31\201\1\320\12\201\174\0\1\317\25\201\1\u0386\4\201"+ + "\1\320\12\201\174\0\1\317\32\201\1\320\4\201\1\u037c"+ + "\5\201\174\0\1\317\32\201\1\320\11\201\1\u037c\174\0"+ + "\1\317\32\201\1\320\2\201\1\u037c\7\201\174\0\1\317"+ + "\16\201\1\u0387\13\201\1\320\12\201\174\0\1\317\32\201"+ + "\1\320\3\201\1\u0388\6\201\174\0\1\317\24\201\1\u0389"+ + "\5\201\1\320\12\201\174\0\1\346\32\235\1\117\10\235"+ + "\1\u02b4\1\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\1\u038a\31\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\7\235\1\u038b"+ + "\22\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\1\u038c"+ + "\31\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\25\235"+ + "\1\u038d\4\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\117\11\235\1\u038e\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\1\u038f\31\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\12\235\1\u0390\17\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\1\u0391\31\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\10\235\1\u0392\21\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\31\235\1\u0393\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\150\0\4\u0394\2\0\1\u0394\15\0\1\u0394\6\0\12\u0394"+ + "\1\u030f\174\0\4\u0395\2\0\1\u0395\15\0\1\u0395\6\0"+ + "\12\u0395\1\u0396\174\0\4\u0397\2\0\1\u0397\15\0\1\u0397"+ + "\6\0\1\u0398\2\u0399\1\u0398\4\u0399\1\u039a\1\u0399\14\0"+ + "\1\u02c9\160\0\4\u039b\2\0\1\u039b\15\0\1\u039b\6\0"+ + "\12\u039b\1\u0359\13\0\1\u02c9\160\0\4\u0397\2\0\1\u0397"+ + "\15\0\1\u0397\6\0\1\u0398\2\u0399\1\u0398\4\u0399\1\u039a"+ + "\1\u0399\174\0\1\u0316\4\u039b\2\0\1\u039b\15\0\1\u039b"+ + "\6\0\12\u039c\1\u0359\13\0\1\u02c9\157\0\1\u0316\4\u039b"+ + "\2\0\1\u039b\15\0\1\u039b\6\0\12\u039b\1\u0359\13\0"+ + "\1\u02c9\157\0\1\u0316\4\u039b\2\0\1\u039b\15\0\1\u039b"+ + "\6\0\2\u039c\1\u039b\2\u039c\2\u039b\2\u039c\1\u039b\1\u0359"+ + "\13\0\1\u02c9\160\0\4\u039d\2\0\1\u039d\15\0\1\u039d"+ + "\6\0\12\u039d\1\u0315\13\0\1\u02c9\157\0\1\u039e\33\0"+ + "\12\u035f\174\0\1\u039e\33\0\12\u039f\174\0\1\u039e\33\0"+ + "\1\u035f\1\u03a0\1\u039f\2\u035f\2\u039f\2\u035f\1\u039f\174\0"+ + "\1\u0316\4\u039d\2\0\1\u039d\15\0\1\u039d\6\0\12\u039d"+ + "\1\u0315\13\0\1\u02c9\157\0\46\u01ab\1\0\2\u01ab\1\u01e5"+ + "\3\u01ab\1\u01ad\1\0\1\u01e4\3\0\2\u01ab\4\0\1\u01ab"+ + "\234\0\1\u03a1\211\0\12\u03a2\11\0\1\u01e4\230\0\1\u02cf"+ + "\174\0\4\u03a3\2\0\1\u03a3\15\0\1\u03a3\6\0\12\u03a3"+ + "\1\u0367\174\0\4\u03a4\2\0\1\u03a4\15\0\1\u03a4\6\0"+ + "\12\u03a4\1\u03a5\174\0\4\u03a6\2\0\1\u03a6\15\0\1\u03a6"+ + "\6\0\12\u03a6\1\u03a7\13\0\1\u0286\157\0\1\u02d6\4\u03a6"+ + "\2\0\1\u03a6\15\0\1\u03a6\6\0\12\u03a8\1\u03a7\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u03a6\2\0\1\u03a6\15\0\1\u03a6"+ + "\6\0\12\u03a9\1\u03a7\13\0\1\u0286\157\0\1\u02d6\4\u03a6"+ + "\2\0\1\u03a6\15\0\1\u03a6\6\0\1\u03a8\1\u03aa\1\u03a9"+ + "\2\u03a8\2\u03a9\2\u03a8\1\u03a9\1\u03a7\13\0\1\u0286\160\0"+ + "\4\u03ab\2\0\1\u03ab\15\0\1\u03ab\6\0\12\u03ab\1\u0321"+ + "\13\0\1\u0286\157\0\1\u02d6\4\u03ab\2\0\1\u03ab\15\0"+ + "\1\u03ab\6\0\12\u03ab\1\u0321\13\0\1\u0286\225\0\1\u02d5"+ + "\13\0\1\u0286\213\0\1\u03ac\2\u03ad\1\u03ac\4\u03ad\1\u03ae"+ + "\1\u03ad\174\0\1\u036f\241\0\1\u036f\33\0\2\u0370\1\0"+ + "\2\u0370\2\0\2\u0370\175\0\34\u01ec\12\u03af\1\0\2\u01ec"+ + "\1\u0238\3\u01ec\1\u01ee\1\u014e\1\u014f\1\u0150\2\0\2\u01ec"+ + "\4\0\1\u01ec\216\0\1\u02dd\174\0\4\u03b0\2\0\1\u03b0"+ + "\15\0\1\u03b0\6\0\12\u03b0\1\u0375\174\0\4\u03b1\2\0"+ + "\1\u03b1\15\0\1\u03b1\6\0\1\u03b2\2\u03b3\1\u03b2\4\u03b3"+ + "\1\u03b4\1\u03b3\1\u03b5\174\0\4\u03b6\2\0\1\u03b6\15\0"+ + "\1\u03b6\6\0\12\u03b6\1\u03b7\13\0\1\u0109\157\0\1\u014a"+ + "\4\u03b6\2\0\1\u03b6\15\0\1\u03b6\6\0\12\u03b8\1\u03b7"+ + "\13\0\1\u0109\157\0\1\u014a\4\u03b6\2\0\1\u03b6\15\0"+ + "\1\u03b6\6\0\12\u03b9\1\u03b7\13\0\1\u0109\157\0\1\u014a"+ + "\4\u03b6\2\0\1\u03b6\15\0\1\u03b6\6\0\1\u03b8\1\u03ba"+ + "\1\u03b9\2\u03b8\2\u03b9\2\u03b8\1\u03b9\1\u03b7\13\0\1\u0109"+ + "\160\0\4\u03bb\2\0\1\u03bb\15\0\1\u03bb\6\0\12\u03bb"+ + "\1\u032f\13\0\1\u0109\157\0\1\u014a\4\u03bb\2\0\1\u03bb"+ + "\15\0\1\u03bb\6\0\12\u03bb\1\u032f\13\0\1\u0109\157\0"+ + "\1\317\2\201\1\u0151\27\201\1\320\12\201\174\0\1\317"+ + "\3\201\1\u03bc\26\201\1\320\12\201\174\0\1\317\32\201"+ + "\1\320\11\201\1\u03bd\174\0\1\317\32\201\1\320\11\201"+ + "\1\u03be\174\0\1\317\32\201\1\320\7\201\1\u03bf\2\201"+ + "\174\0\1\317\32\201\1\320\4\201\1\u03c0\5\201\174\0"+ + "\1\317\26\201\1\u03c1\3\201\1\320\12\201\174\0\1\317"+ + "\30\201\1\u03c2\1\201\1\320\12\201\174\0\1\317\11\201"+ + "\1\u018b\20\201\1\320\12\201\174\0\1\317\12\201\1\u03c3"+ + "\17\201\1\320\12\201\174\0\1\317\17\201\1\u0159\12\201"+ + "\1\320\12\201\174\0\1\317\32\201\1\320\4\201\1\u03c4"+ + "\5\201\174\0\1\317\30\201\1\u03c5\1\201\1\320\12\201"+ + "\174\0\1\317\30\201\1\u03c6\1\201\1\320\12\201\174\0"+ + "\1\346\32\235\1\117\6\235\1\u02ad\3\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\15\235\1\260\14\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\147\0\1\346\32\235\1\117\1\235\1\u03c7\10\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\30\235\1\u03c8\1\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\6\235\1\u03c9\23\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\5\235\1\u03ca\4\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\22\235"+ + "\1\353\7\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\117\5\235\1\u03cb\4\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\32\235\1\117\1\235\1\260\10\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\13\235\1\u03cc\16\235\1\117\12\235\1\0"+ + "\3\114\1\0\2\114\1\115\3\114\3\0\1\114\4\0"+ + "\2\114\215\0\1\u030f\174\0\4\u03cd\2\0\1\u03cd\15\0"+ + "\1\u03cd\6\0\12\u03cd\1\u0396\174\0\4\u03ce\2\0\1\u03ce"+ + "\15\0\1\u03ce\6\0\12\u03ce\1\u03cf\174\0\4\u03d0\2\0"+ + "\1\u03d0\15\0\1\u03d0\6\0\12\u03d0\1\u03d1\13\0\1\u02c9"+ + "\157\0\1\u0316\4\u03d0\2\0\1\u03d0\15\0\1\u03d0\6\0"+ + "\12\u03d2\1\u03d1\13\0\1\u02c9\157\0\1\u0316\4\u03d0\2\0"+ + "\1\u03d0\15\0\1\u03d0\6\0\12\u03d3\1\u03d1\13\0\1\u02c9"+ + "\157\0\1\u0316\4\u03d0\2\0\1\u03d0\15\0\1\u03d0\6\0"+ + "\1\u03d2\1\u03d4\1\u03d3\2\u03d2\2\u03d3\2\u03d2\1\u03d3\1\u03d1"+ + "\13\0\1\u02c9\160\0\4\u03d5\2\0\1\u03d5\15\0\1\u03d5"+ + "\6\0\12\u03d5\1\u0359\13\0\1\u02c9\157\0\1\u0316\4\u03d5"+ + "\2\0\1\u03d5\15\0\1\u03d5\6\0\12\u03d5\1\u0359\13\0"+ + "\1\u02c9\225\0\1\u0315\13\0\1\u02c9\213\0\1\u03d6\2\u03d7"+ + "\1\u03d6\4\u03d7\1\u03d8\1\u03d7\174\0\1\u039e\241\0\1\u039e"+ + "\33\0\2\u039f\1\0\2\u039f\2\0\2\u039f\176\0\1\u03d9"+ + "\1\0\1\u03d9\5\0\1\u03d9\307\0\1\u01e4\163\0\4\u03da"+ + "\2\0\1\u03da\15\0\1\u03da\6\0\12\u03da\1\u0367\174\0"+ + "\4\u03db\2\0\1\u03db\15\0\1\u03db\6\0\12\u03db\1\u03dc"+ + "\174\0\4\u03dd\2\0\1\u03dd\15\0\1\u03dd\6\0\1\u03de"+ + "\2\u03df\1\u03de\4\u03df\1\u03e0\1\u03df\14\0\1\u0286\160\0"+ + "\4\u03e1\2\0\1\u03e1\15\0\1\u03e1\6\0\12\u03e1\1\u03a7"+ + "\13\0\1\u0286\160\0\4\u03dd\2\0\1\u03dd\15\0\1\u03dd"+ + "\6\0\1\u03de\2\u03df\1\u03de\4\u03df\1\u03e0\1\u03df\174\0"+ + "\1\u02d6\4\u03e1\2\0\1\u03e1\15\0\1\u03e1\6\0\12\u03e2"+ + "\1\u03a7\13\0\1\u0286\157\0\1\u02d6\4\u03e1\2\0\1\u03e1"+ + "\15\0\1\u03e1\6\0\12\u03e1\1\u03a7\13\0\1\u0286\157\0"+ + "\1\u02d6\4\u03e1\2\0\1\u03e1\15\0\1\u03e1\6\0\2\u03e2"+ + "\1\u03e1\2\u03e2\2\u03e1\2\u03e2\1\u03e1\1\u03a7\13\0\1\u0286"+ + "\225\0\1\u0321\13\0\1\u0286\157\0\1\u03e3\33\0\12\u03ad"+ + "\174\0\1\u03e3\33\0\12\u03e4\174\0\1\u03e3\33\0\1\u03ad"+ + "\1\u03e5\1\u03e4\2\u03ad\2\u03e4\2\u03ad\1\u03e4\174\0\46\u01ec"+ + "\1\0\2\u01ec\1\u0238\3\u01ec\1\u01ee\1\u014e\1\u014f\1\u0150"+ + "\2\0\2\u01ec\4\0\1\u01ec\151\0\4\u03e6\2\0\1\u03e6"+ + "\15\0\1\u03e6\6\0\12\u03e6\1\u0375\174\0\4\u03e7\2\0"+ + "\1\u03e7\15\0\1\u03e7\6\0\12\u03e7\1\u03e8\173\0\1\u014a"+ + "\4\u03e7\2\0\1\u03e7\15\0\1\u03e7\6\0\12\u03e9\1\u03e8"+ + "\173\0\1\u014a\4\u03e7\2\0\1\u03e7\15\0\1\u03e7\6\0"+ + "\12\u03ea\1\u03e8\173\0\1\u014a\4\u03e7\2\0\1\u03e7\15\0"+ + "\1\u03e7\6\0\1\u03e9\1\u03eb\1\u03ea\2\u03e9\2\u03ea\2\u03e9"+ + "\1\u03ea\1\u03e8\174\0\4\u03ec\2\0\1\u03ec\15\0\1\u03ec"+ + "\6\0\12\u03ec\14\0\1\u0109\160\0\4\u03ed\2\0\1\u03ed"+ + "\15\0\1\u03ed\6\0\12\u03ed\1\u03b7\13\0\1\u0109\160\0"+ + "\4\u03ec\2\0\1\u03ec\15\0\1\u03ec\6\0\12\u03ec\174\0"+ + "\1\u014a\4\u03ed\2\0\1\u03ed\15\0\1\u03ed\6\0\12\u03ee"+ + "\1\u03b7\13\0\1\u0109\157\0\1\u014a\4\u03ed\2\0\1\u03ed"+ + "\15\0\1\u03ed\6\0\12\u03ed\1\u03b7\13\0\1\u0109\157\0"+ + "\1\u014a\4\u03ed\2\0\1\u03ed\15\0\1\u03ed\6\0\2\u03ee"+ + "\1\u03ed\2\u03ee\2\u03ed\2\u03ee\1\u03ed\1\u03b7\13\0\1\u0109"+ + "\225\0\1\u032f\13\0\1\u0109\157\0\1\317\32\201\1\320"+ + "\10\201\1\u033c\1\201\174\0\1\317\1\u03ef\31\201\1\320"+ + "\12\201\174\0\1\317\7\201\1\u03f0\22\201\1\320\12\201"+ + "\174\0\1\317\1\u03f1\31\201\1\320\12\201\174\0\1\317"+ + "\25\201\1\u03f2\4\201\1\320\12\201\174\0\1\317\32\201"+ + "\1\320\11\201\1\u03f3\174\0\1\317\1\u03f4\31\201\1\320"+ + "\12\201\174\0\1\317\12\201\1\u03f5\17\201\1\320\12\201"+ + "\174\0\1\317\1\u03f6\31\201\1\320\12\201\174\0\1\317"+ + "\10\201\1\u03f7\21\201\1\320\12\201\174\0\1\317\31\201"+ + "\1\u03f8\1\320\12\201\174\0\1\346\2\235\1\u03f9\27\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\3\235\1\u03fa"+ + "\26\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\32\235"+ + "\1\117\1\235\1\u03fb\10\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\3\235\1\u03fc\26\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\1\u03fd\31\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\26\235\1\u03fe\3\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\150\0\4\u03ff\2\0\1\u03ff\15\0\1\u03ff\6\0\12\u03ff"+ + "\1\u0396\174\0\4\u0400\2\0\1\u0400\15\0\1\u0400\6\0"+ + "\12\u0400\1\u0401\174\0\4\u0402\2\0\1\u0402\15\0\1\u0402"+ + "\6\0\1\u0403\2\u0404\1\u0403\4\u0404\1\u0405\1\u0404\14\0"+ + "\1\u02c9\160\0\4\u0406\2\0\1\u0406\15\0\1\u0406\6\0"+ + "\12\u0406\1\u03d1\13\0\1\u02c9\160\0\4\u0402\2\0\1\u0402"+ + "\15\0\1\u0402\6\0\1\u0403\2\u0404\1\u0403\4\u0404\1\u0405"+ + "\1\u0404\174\0\1\u0316\4\u0406\2\0\1\u0406\15\0\1\u0406"+ + "\6\0\12\u0407\1\u03d1\13\0\1\u02c9\157\0\1\u0316\4\u0406"+ + "\2\0\1\u0406\15\0\1\u0406\6\0\12\u0406\1\u03d1\13\0"+ + "\1\u02c9\157\0\1\u0316\4\u0406\2\0\1\u0406\15\0\1\u0406"+ + "\6\0\2\u0407\1\u0406\2\u0407\2\u0406\2\u0407\1\u0406\1\u03d1"+ + "\13\0\1\u02c9\225\0\1\u0359\13\0\1\u02c9\157\0\1\u0408"+ + "\33\0\12\u03d7\174\0\1\u0408\33\0\12\u0409\174\0\1\u0408"+ + "\33\0\1\u03d7\1\u040a\1\u0409\2\u03d7\2\u0409\2\u03d7\1\u0409"+ + "\254\0\1\u0150\227\0\1\u0367\174\0\4\u040b\2\0\1\u040b"+ + "\15\0\1\u040b\6\0\12\u040b\1\u03dc\174\0\4\u040c\2\0"+ + "\1\u040c\15\0\1\u040c\6\0\12\u040c\1\u040d\174\0\4\u040e"+ + "\2\0\1\u040e\15\0\1\u040e\6\0\12\u040e\1\u040f\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u040e\2\0\1\u040e\15\0\1\u040e"+ + "\6\0\12\u0410\1\u040f\13\0\1\u0286\157\0\1\u02d6\4\u040e"+ + "\2\0\1\u040e\15\0\1\u040e\6\0\12\u0411\1\u040f\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u040e\2\0\1\u040e\15\0\1\u040e"+ + "\6\0\1\u0410\1\u0412\1\u0411\2\u0410\2\u0411\2\u0410\1\u0411"+ + "\1\u040f\13\0\1\u0286\160\0\4\u0413\2\0\1\u0413\15\0"+ + "\1\u0413\6\0\12\u0413\1\u03a7\13\0\1\u0286\157\0\1\u02d6"+ + "\4\u0413\2\0\1\u0413\15\0\1\u0413\6\0\12\u0413\1\u03a7"+ + "\13\0\1\u0286\213\0\1\u0414\2\u0415\1\u0414\4\u0415\1\u0416"+ + "\1\u0415\174\0\1\u03e3\241\0\1\u03e3\33\0\2\u03e4\1\0"+ + "\2\u03e4\2\0\2\u03e4\243\0\1\u0375\174\0\4\u0417\2\0"+ + "\1\u0417\15\0\1\u0417\6\0\12\u0417\1\u03e8\174\0\4\u03ec"+ + "\2\0\1\u03ec\15\0\1\u03ec\6\0\12\u03ec\1\u02e4\173\0"+ + "\1\u014a\4\u0417\2\0\1\u0417\15\0\1\u0417\6\0\12\u0418"+ + "\1\u03e8\173\0\1\u014a\4\u0417\2\0\1\u0417\15\0\1\u0417"+ + "\6\0\12\u0417\1\u03e8\173\0\1\u014a\4\u0417\2\0\1\u0417"+ + "\15\0\1\u0417\6\0\2\u0418\1\u0417\2\u0418\2\u0417\2\u0418"+ + "\1\u0417\1\u03e8\174\0\4\u0419\2\0\1\u0419\15\0\1\u0419"+ + "\6\0\12\u0419\14\0\1\u0109\160\0\4\u041a\2\0\1\u041a"+ + "\15\0\1\u041a\6\0\12\u041a\1\u03b7\13\0\1\u0109\157\0"+ + "\1\u014a\4\u041a\2\0\1\u041a\15\0\1\u041a\6\0\12\u041a"+ + "\1\u03b7\13\0\1\u0109\157\0\1\317\32\201\1\320\6\201"+ + "\1\u0335\3\201\174\0\1\317\15\201\1\u0116\14\201\1\320"+ + "\12\201\174\0\1\317\32\201\1\320\1\201\1\u041b\10\201"+ + "\174\0\1\317\30\201\1\u041c\1\201\1\320\12\201\174\0"+ + "\1\317\6\201\1\u041d\23\201\1\320\12\201\174\0\1\317"+ + "\32\201\1\320\5\201\1\u041e\4\201\174\0\1\317\22\201"+ + "\1\u0151\7\201\1\320\12\201\174\0\1\317\32\201\1\320"+ + "\5\201\1\u041f\4\201\174\0\1\317\32\201\1\320\1\201"+ + "\1\u0116\10\201\174\0\1\317\13\201\1\u0420\16\201\1\320"+ + "\12\201\174\0\1\346\32\235\1\117\7\235\1\u0421\2\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\32\235\1\117\10\235\1\260"+ + "\1\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\32\235\1\117\4\235"+ + "\1\u0422\5\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\16\235\1\u0423"+ + "\13\235\1\117\12\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\26\235"+ + "\1\u0424\3\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\147\0\1\346"+ + "\32\235\1\117\7\235\1\u0425\2\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\215\0"+ + "\1\u0396\174\0\4\u0426\2\0\1\u0426\15\0\1\u0426\6\0"+ + "\12\u0426\1\u0401\174\0\4\u0427\2\0\1\u0427\15\0\1\u0427"+ + "\6\0\12\u0427\1\u0428\174\0\4\u0429\2\0\1\u0429\15\0"+ + "\1\u0429\6\0\12\u0429\1\u042a\13\0\1\u02c9\157\0\1\u0316"+ + "\4\u0429\2\0\1\u0429\15\0\1\u0429\6\0\12\u042b\1\u042a"+ + "\13\0\1\u02c9\157\0\1\u0316\4\u0429\2\0\1\u0429\15\0"+ + "\1\u0429\6\0\12\u042c\1\u042a\13\0\1\u02c9\157\0\1\u0316"+ + "\4\u0429\2\0\1\u0429\15\0\1\u0429\6\0\1\u042b\1\u042d"+ + "\1\u042c\2\u042b\2\u042c\2\u042b\1\u042c\1\u042a\13\0\1\u02c9"+ + "\160\0\4\u042e\2\0\1\u042e\15\0\1\u042e\6\0\12\u042e"+ + "\1\u03d1\13\0\1\u02c9\157\0\1\u0316\4\u042e\2\0\1\u042e"+ + "\15\0\1\u042e\6\0\12\u042e\1\u03d1\13\0\1\u02c9\213\0"+ + "\1\u042f\2\u0430\1\u042f\4\u0430\1\u0431\1\u0430\174\0\1\u0408"+ + "\241\0\1\u0408\33\0\2\u0409\1\0\2\u0409\2\0\2\u0409"+ + "\176\0\4\u0432\2\0\1\u0432\15\0\1\u0432\6\0\12\u0432"+ + "\1\u03dc\174\0\4\u0433\2\0\1\u0433\15\0\1\u0433\6\0"+ + "\12\u0433\1\u0434\174\0\4\u0435\2\0\1\u0435\15\0\1\u0435"+ + "\6\0\1\u0436\2\u0437\1\u0436\4\u0437\1\u0438\1\u0437\14\0"+ + "\1\u0286\160\0\4\u0439\2\0\1\u0439\15\0\1\u0439\6\0"+ + "\12\u0439\1\u040f\13\0\1\u0286\160\0\4\u0435\2\0\1\u0435"+ + "\15\0\1\u0435\6\0\1\u0436\2\u0437\1\u0436\4\u0437\1\u0438"+ + "\1\u0437\174\0\1\u02d6\4\u0439\2\0\1\u0439\15\0\1\u0439"+ + "\6\0\12\u043a\1\u040f\13\0\1\u0286\157\0\1\u02d6\4\u0439"+ + "\2\0\1\u0439\15\0\1\u0439\6\0\12\u0439\1\u040f\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u0439\2\0\1\u0439\15\0\1\u0439"+ + "\6\0\2\u043a\1\u0439\2\u043a\2\u0439\2\u043a\1\u0439\1\u040f"+ + "\13\0\1\u0286\225\0\1\u03a7\13\0\1\u0286\213\0\12\u0415"+ + "\14\0\1\u0286\213\0\12\u043b\14\0\1\u0286\213\0\1\u0415"+ + "\1\u043c\1\u043b\2\u0415\2\u043b\2\u0415\1\u043b\14\0\1\u0286"+ + "\160\0\4\u043d\2\0\1\u043d\15\0\1\u043d\6\0\12\u043d"+ + "\1\u03e8\173\0\1\u014a\4\u043d\2\0\1\u043d\15\0\1\u043d"+ + "\6\0\12\u043d\1\u03e8\174\0\4\u043e\2\0\1\u043e\15\0"+ + "\1\u043e\6\0\12\u043e\14\0\1\u0109\225\0\1\u03b7\13\0"+ + "\1\u0109\157\0\1\317\2\201\1\u043f\27\201\1\320\12\201"+ + "\174\0\1\317\3\201\1\u0440\26\201\1\320\12\201\174\0"+ + "\1\317\32\201\1\320\1\201\1\u0441\10\201\174\0\1\317"+ + "\3\201\1\u0442\26\201\1\320\12\201\174\0\1\317\1\u0443"+ + "\31\201\1\320\12\201\174\0\1\317\26\201\1\u0444\3\201"+ + "\1\320\12\201\174\0\1\346\1\u0445\31\235\1\117\12\235"+ + "\1\0\3\114\1\0\2\114\1\115\3\114\3\0\1\114"+ + "\4\0\2\114\147\0\1\346\24\235\1\u0446\5\235\1\117"+ + "\12\235\1\0\3\114\1\0\2\114\1\115\3\114\3\0"+ + "\1\114\4\0\2\114\147\0\1\346\1\235\1\u0447\30\235"+ + "\1\117\12\235\1\0\3\114\1\0\2\114\1\115\3\114"+ + "\3\0\1\114\4\0\2\114\147\0\1\346\32\235\1\117"+ + "\2\235\1\362\7\235\1\0\3\114\1\0\2\114\1\115"+ + "\3\114\3\0\1\114\4\0\2\114\147\0\1\346\6\235"+ + "\1\353\23\235\1\117\12\235\1\0\3\114\1\0\2\114"+ + "\1\115\3\114\3\0\1\114\4\0\2\114\150\0\4\u0448"+ + "\2\0\1\u0448\15\0\1\u0448\6\0\12\u0448\1\u0401\174\0"+ + "\4\u0449\2\0\1\u0449\15\0\1\u0449\6\0\12\u0449\1\u044a"+ + "\174\0\4\u044b\2\0\1\u044b\15\0\1\u044b\6\0\1\u044c"+ + "\2\u044d\1\u044c\4\u044d\1\u044e\1\u044d\14\0\1\u02c9\160\0"+ + "\4\u044f\2\0\1\u044f\15\0\1\u044f\6\0\12\u044f\1\u042a"+ + "\13\0\1\u02c9\160\0\4\u044b\2\0\1\u044b\15\0\1\u044b"+ + "\6\0\1\u044c\2\u044d\1\u044c\4\u044d\1\u044e\1\u044d\174\0"+ + "\1\u0316\4\u044f\2\0\1\u044f\15\0\1\u044f\6\0\12\u0450"+ + "\1\u042a\13\0\1\u02c9\157\0\1\u0316\4\u044f\2\0\1\u044f"+ + "\15\0\1\u044f\6\0\12\u044f\1\u042a\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u044f\2\0\1\u044f\15\0\1\u044f\6\0\2\u0450"+ + "\1\u044f\2\u0450\2\u044f\2\u0450\1\u044f\1\u042a\13\0\1\u02c9"+ + "\225\0\1\u03d1\13\0\1\u02c9\213\0\12\u0430\14\0\1\u02c9"+ + "\213\0\12\u0451\14\0\1\u02c9\213\0\1\u0430\1\u0452\1\u0451"+ + "\2\u0430\2\u0451\2\u0430\1\u0451\14\0\1\u02c9\225\0\1\u03dc"+ + "\174\0\4\u0453\2\0\1\u0453\15\0\1\u0453\6\0\12\u0453"+ + "\1\u0434\174\0\4\u0454\2\0\1\u0454\15\0\1\u0454\6\0"+ + "\12\u0454\1\u0455\174\0\4\u0456\2\0\1\u0456\15\0\1\u0456"+ + "\6\0\12\u0456\1\u0457\13\0\1\u0286\157\0\1\u02d6\4\u0456"+ + "\2\0\1\u0456\15\0\1\u0456\6\0\12\u0458\1\u0457\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u0456\2\0\1\u0456\15\0\1\u0456"+ + "\6\0\12\u0459\1\u0457\13\0\1\u0286\157\0\1\u02d6\4\u0456"+ + "\2\0\1\u0456\15\0\1\u0456\6\0\1\u0458\1\u045a\1\u0459"+ + "\2\u0458\2\u0459\2\u0458\1\u0459\1\u0457\13\0\1\u0286\160\0"+ + "\4\u045b\2\0\1\u045b\15\0\1\u045b\6\0\12\u045b\1\u040f"+ + "\13\0\1\u0286\157\0\1\u02d6\4\u045b\2\0\1\u045b\15\0"+ + "\1\u045b\6\0\12\u045b\1\u040f\13\0\1\u0286\241\0\1\u0286"+ + "\213\0\2\u043b\1\0\2\u043b\2\0\2\u043b\15\0\1\u0286"+ + "\225\0\1\u03e8\174\0\4\u02e4\2\0\1\u02e4\15\0\1\u02e4"+ + "\6\0\12\u02e4\14\0\1\u0109\157\0\1\317\32\201\1\320"+ + "\7\201\1\u045c\2\201\174\0\1\317\32\201\1\320\10\201"+ + "\1\u0116\1\201\174\0\1\317\32\201\1\320\4\201\1\u045d"+ + "\5\201\174\0\1\317\16\201\1\u045e\13\201\1\320\12\201"+ + "\174\0\1\317\26\201\1\u045f\3\201\1\320\12\201\174\0"+ + "\1\317\32\201\1\320\7\201\1\u0460\2\201\174\0\1\346"+ + "\4\235\1\353\25\235\1\117\12\235\1\0\3\114\1\0"+ + "\2\114\1\115\3\114\3\0\1\114\4\0\2\114\147\0"+ + "\1\346\24\235\1\260\5\235\1\117\12\235\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\147\0\1\346\32\235\1\117\11\235\1\260\1\0\3\114"+ + "\1\0\2\114\1\115\3\114\3\0\1\114\4\0\2\114"+ + "\215\0\1\u0401\174\0\4\u0461\2\0\1\u0461\15\0\1\u0461"+ + "\6\0\12\u0461\1\u044a\174\0\4\u0462\2\0\1\u0462\15\0"+ + "\1\u0462\6\0\12\u0462\1\u0463\174\0\4\u0464\2\0\1\u0464"+ + "\15\0\1\u0464\6\0\12\u0464\1\u0465\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u0464\2\0\1\u0464\15\0\1\u0464\6\0\12\u0466"+ + "\1\u0465\13\0\1\u02c9\157\0\1\u0316\4\u0464\2\0\1\u0464"+ + "\15\0\1\u0464\6\0\12\u0467\1\u0465\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u0464\2\0\1\u0464\15\0\1\u0464\6\0\1\u0466"+ + "\1\u0468\1\u0467\2\u0466\2\u0467\2\u0466\1\u0467\1\u0465\13\0"+ + "\1\u02c9\160\0\4\u0469\2\0\1\u0469\15\0\1\u0469\6\0"+ + "\12\u0469\1\u042a\13\0\1\u02c9\157\0\1\u0316\4\u0469\2\0"+ + "\1\u0469\15\0\1\u0469\6\0\12\u0469\1\u042a\13\0\1\u02c9"+ + "\241\0\1\u02c9\213\0\2\u0451\1\0\2\u0451\2\0\2\u0451"+ + "\15\0\1\u02c9\160\0\4\u046a\2\0\1\u046a\15\0\1\u046a"+ + "\6\0\12\u046a\1\u0434\174\0\4\u046b\2\0\1\u046b\15\0"+ + "\1\u046b\6\0\12\u046b\1\u046c\174\0\4\u046d\2\0\1\u046d"+ + "\15\0\1\u046d\6\0\1\u046e\2\u046f\1\u046e\4\u046f\1\u0470"+ + "\1\u046f\14\0\1\u0286\160\0\4\u0471\2\0\1\u0471\15\0"+ + "\1\u0471\6\0\12\u0471\1\u0457\13\0\1\u0286\160\0\4\u046d"+ + "\2\0\1\u046d\15\0\1\u046d\6\0\1\u046e\2\u046f\1\u046e"+ + "\4\u046f\1\u0470\1\u046f\174\0\1\u02d6\4\u0471\2\0\1\u0471"+ + "\15\0\1\u0471\6\0\12\u0472\1\u0457\13\0\1\u0286\157\0"+ + "\1\u02d6\4\u0471\2\0\1\u0471\15\0\1\u0471\6\0\12\u0471"+ + "\1\u0457\13\0\1\u0286\157\0\1\u02d6\4\u0471\2\0\1\u0471"+ + "\15\0\1\u0471\6\0\2\u0472\1\u0471\2\u0472\2\u0471\2\u0472"+ + "\1\u0471\1\u0457\13\0\1\u0286\225\0\1\u040f\13\0\1\u0286"+ + "\157\0\1\317\1\u0473\31\201\1\320\12\201\174\0\1\317"+ + "\24\201\1\u0474\5\201\1\320\12\201\174\0\1\317\1\201"+ + "\1\u0475\30\201\1\320\12\201\174\0\1\317\32\201\1\320"+ + "\2\201\1\u0158\7\201\174\0\1\317\6\201\1\u0151\23\201"+ + "\1\320\12\201\175\0\4\u0476\2\0\1\u0476\15\0\1\u0476"+ + "\6\0\12\u0476\1\u044a\174\0\4\u0477\2\0\1\u0477\15\0"+ + "\1\u0477\6\0\12\u0477\1\u0478\174\0\4\u0479\2\0\1\u0479"+ + "\15\0\1\u0479\6\0\1\u047a\2\u047b\1\u047a\4\u047b\1\u047c"+ + "\1\u047b\14\0\1\u02c9\160\0\4\u047d\2\0\1\u047d\15\0"+ + "\1\u047d\6\0\12\u047d\1\u0465\13\0\1\u02c9\160\0\4\u0479"+ + "\2\0\1\u0479\15\0\1\u0479\6\0\1\u047a\2\u047b\1\u047a"+ + "\4\u047b\1\u047c\1\u047b\174\0\1\u0316\4\u047d\2\0\1\u047d"+ + "\15\0\1\u047d\6\0\12\u047e\1\u0465\13\0\1\u02c9\157\0"+ + "\1\u0316\4\u047d\2\0\1\u047d\15\0\1\u047d\6\0\12\u047d"+ + "\1\u0465\13\0\1\u02c9\157\0\1\u0316\4\u047d\2\0\1\u047d"+ + "\15\0\1\u047d\6\0\2\u047e\1\u047d\2\u047e\2\u047d\2\u047e"+ + "\1\u047d\1\u0465\13\0\1\u02c9\225\0\1\u042a\13\0\1\u02c9"+ + "\225\0\1\u0434\174\0\4\u047f\2\0\1\u047f\15\0\1\u047f"+ + "\6\0\12\u047f\1\u046c\174\0\4\u0480\2\0\1\u0480\15\0"+ + "\1\u0480\6\0\1\u0481\2\u0482\1\u0481\4\u0482\1\u0483\1\u0482"+ + "\1\u0484\174\0\4\u0485\2\0\1\u0485\15\0\1\u0485\6\0"+ + "\12\u0485\1\u0486\13\0\1\u0286\157\0\1\u02d6\4\u0485\2\0"+ + "\1\u0485\15\0\1\u0485\6\0\12\u0487\1\u0486\13\0\1\u0286"+ + "\157\0\1\u02d6\4\u0485\2\0\1\u0485\15\0\1\u0485\6\0"+ + "\12\u0488\1\u0486\13\0\1\u0286\157\0\1\u02d6\4\u0485\2\0"+ + "\1\u0485\15\0\1\u0485\6\0\1\u0487\1\u0489\1\u0488\2\u0487"+ + "\2\u0488\2\u0487\1\u0488\1\u0486\13\0\1\u0286\160\0\4\u048a"+ + "\2\0\1\u048a\15\0\1\u048a\6\0\12\u048a\1\u0457\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u048a\2\0\1\u048a\15\0\1\u048a"+ + "\6\0\12\u048a\1\u0457\13\0\1\u0286\157\0\1\317\4\201"+ + "\1\u0151\25\201\1\320\12\201\174\0\1\317\24\201\1\u0116"+ + "\5\201\1\320\12\201\174\0\1\317\32\201\1\320\11\201"+ + "\1\u0116\242\0\1\u044a\174\0\4\u048b\2\0\1\u048b\15\0"+ + "\1\u048b\6\0\12\u048b\1\u0478\174\0\4\u048c\2\0\1\u048c"+ + "\15\0\1\u048c\6\0\1\u048d\2\u048e\1\u048d\4\u048e\1\u048f"+ + "\1\u048e\1\u0490\174\0\4\u0491\2\0\1\u0491\15\0\1\u0491"+ + "\6\0\12\u0491\1\u0492\13\0\1\u02c9\157\0\1\u0316\4\u0491"+ + "\2\0\1\u0491\15\0\1\u0491\6\0\12\u0493\1\u0492\13\0"+ + "\1\u02c9\157\0\1\u0316\4\u0491\2\0\1\u0491\15\0\1\u0491"+ + "\6\0\12\u0494\1\u0492\13\0\1\u02c9\157\0\1\u0316\4\u0491"+ + "\2\0\1\u0491\15\0\1\u0491\6\0\1\u0493\1\u0495\1\u0494"+ + "\2\u0493\2\u0494\2\u0493\1\u0494\1\u0492\13\0\1\u02c9\160\0"+ + "\4\u0496\2\0\1\u0496\15\0\1\u0496\6\0\12\u0496\1\u0465"+ + "\13\0\1\u02c9\157\0\1\u0316\4\u0496\2\0\1\u0496\15\0"+ + "\1\u0496\6\0\12\u0496\1\u0465\13\0\1\u02c9\160\0\4\u0497"+ + "\2\0\1\u0497\15\0\1\u0497\6\0\12\u0497\1\u046c\174\0"+ + "\4\u0498\2\0\1\u0498\15\0\1\u0498\6\0\12\u0498\1\u0499"+ + "\173\0\1\u02d6\4\u0498\2\0\1\u0498\15\0\1\u0498\6\0"+ + "\12\u049a\1\u0499\173\0\1\u02d6\4\u0498\2\0\1\u0498\15\0"+ + "\1\u0498\6\0\12\u049b\1\u0499\173\0\1\u02d6\4\u0498\2\0"+ + "\1\u0498\15\0\1\u0498\6\0\1\u049a\1\u049c\1\u049b\2\u049a"+ + "\2\u049b\2\u049a\1\u049b\1\u0499\174\0\4\u049d\2\0\1\u049d"+ + "\15\0\1\u049d\6\0\12\u049d\14\0\1\u0286\160\0\4\u049e"+ + "\2\0\1\u049e\15\0\1\u049e\6\0\12\u049e\1\u0486\13\0"+ + "\1\u0286\160\0\4\u049d\2\0\1\u049d\15\0\1\u049d\6\0"+ + "\12\u049d\174\0\1\u02d6\4\u049e\2\0\1\u049e\15\0\1\u049e"+ + "\6\0\12\u049f\1\u0486\13\0\1\u0286\157\0\1\u02d6\4\u049e"+ + "\2\0\1\u049e\15\0\1\u049e\6\0\12\u049e\1\u0486\13\0"+ + "\1\u0286\157\0\1\u02d6\4\u049e\2\0\1\u049e\15\0\1\u049e"+ + "\6\0\2\u049f\1\u049e\2\u049f\2\u049e\2\u049f\1\u049e\1\u0486"+ + "\13\0\1\u0286\225\0\1\u0457\13\0\1\u0286\160\0\4\u04a0"+ + "\2\0\1\u04a0\15\0\1\u04a0\6\0\12\u04a0\1\u0478\174\0"+ + "\4\u04a1\2\0\1\u04a1\15\0\1\u04a1\6\0\12\u04a1\1\u04a2"+ + "\173\0\1\u0316\4\u04a1\2\0\1\u04a1\15\0\1\u04a1\6\0"+ + "\12\u04a3\1\u04a2\173\0\1\u0316\4\u04a1\2\0\1\u04a1\15\0"+ + "\1\u04a1\6\0\12\u04a4\1\u04a2\173\0\1\u0316\4\u04a1\2\0"+ + "\1\u04a1\15\0\1\u04a1\6\0\1\u04a3\1\u04a5\1\u04a4\2\u04a3"+ + "\2\u04a4\2\u04a3\1\u04a4\1\u04a2\174\0\4\u04a6\2\0\1\u04a6"+ + "\15\0\1\u04a6\6\0\12\u04a6\14\0\1\u02c9\160\0\4\u04a7"+ + "\2\0\1\u04a7\15\0\1\u04a7\6\0\12\u04a7\1\u0492\13\0"+ + "\1\u02c9\160\0\4\u04a6\2\0\1\u04a6\15\0\1\u04a6\6\0"+ + "\12\u04a6\174\0\1\u0316\4\u04a7\2\0\1\u04a7\15\0\1\u04a7"+ + "\6\0\12\u04a8\1\u0492\13\0\1\u02c9\157\0\1\u0316\4\u04a7"+ + "\2\0\1\u04a7\15\0\1\u04a7\6\0\12\u04a7\1\u0492\13\0"+ + "\1\u02c9\157\0\1\u0316\4\u04a7\2\0\1\u04a7\15\0\1\u04a7"+ + "\6\0\2\u04a8\1\u04a7\2\u04a8\2\u04a7\2\u04a8\1\u04a7\1\u0492"+ + "\13\0\1\u02c9\225\0\1\u0465\13\0\1\u02c9\225\0\1\u046c"+ + "\174\0\4\u04a9\2\0\1\u04a9\15\0\1\u04a9\6\0\12\u04a9"+ + "\1\u0499\174\0\4\u049d\2\0\1\u049d\15\0\1\u049d\6\0"+ + "\12\u049d\1\u043b\173\0\1\u02d6\4\u04a9\2\0\1\u04a9\15\0"+ + "\1\u04a9\6\0\12\u04aa\1\u0499\173\0\1\u02d6\4\u04a9\2\0"+ + "\1\u04a9\15\0\1\u04a9\6\0\12\u04a9\1\u0499\173\0\1\u02d6"+ + "\4\u04a9\2\0\1\u04a9\15\0\1\u04a9\6\0\2\u04aa\1\u04a9"+ + "\2\u04aa\2\u04a9\2\u04aa\1\u04a9\1\u0499\174\0\4\u04ab\2\0"+ + "\1\u04ab\15\0\1\u04ab\6\0\12\u04ab\14\0\1\u0286\160\0"+ + "\4\u04ac\2\0\1\u04ac\15\0\1\u04ac\6\0\12\u04ac\1\u0486"+ + "\13\0\1\u0286\157\0\1\u02d6\4\u04ac\2\0\1\u04ac\15\0"+ + "\1\u04ac\6\0\12\u04ac\1\u0486\13\0\1\u0286\225\0\1\u0478"+ + "\174\0\4\u04ad\2\0\1\u04ad\15\0\1\u04ad\6\0\12\u04ad"+ + "\1\u04a2\174\0\4\u04a6\2\0\1\u04a6\15\0\1\u04a6\6\0"+ + "\12\u04a6\1\u0451\173\0\1\u0316\4\u04ad\2\0\1\u04ad\15\0"+ + "\1\u04ad\6\0\12\u04ae\1\u04a2\173\0\1\u0316\4\u04ad\2\0"+ + "\1\u04ad\15\0\1\u04ad\6\0\12\u04ad\1\u04a2\173\0\1\u0316"+ + "\4\u04ad\2\0\1\u04ad\15\0\1\u04ad\6\0\2\u04ae\1\u04ad"+ + "\2\u04ae\2\u04ad\2\u04ae\1\u04ad\1\u04a2\174\0\4\u04af\2\0"+ + "\1\u04af\15\0\1\u04af\6\0\12\u04af\14\0\1\u02c9\160\0"+ + "\4\u04b0\2\0\1\u04b0\15\0\1\u04b0\6\0\12\u04b0\1\u0492"+ + "\13\0\1\u02c9\157\0\1\u0316\4\u04b0\2\0\1\u04b0\15\0"+ + "\1\u04b0\6\0\12\u04b0\1\u0492\13\0\1\u02c9\160\0\4\u04b1"+ + "\2\0\1\u04b1\15\0\1\u04b1\6\0\12\u04b1\1\u0499\173\0"+ + "\1\u02d6\4\u04b1\2\0\1\u04b1\15\0\1\u04b1\6\0\12\u04b1"+ + "\1\u0499\174\0\4\u04b2\2\0\1\u04b2\15\0\1\u04b2\6\0"+ + "\12\u04b2\14\0\1\u0286\225\0\1\u0486\13\0\1\u0286\160\0"+ + "\4\u04b3\2\0\1\u04b3\15\0\1\u04b3\6\0\12\u04b3\1\u04a2"+ + "\173\0\1\u0316\4\u04b3\2\0\1\u04b3\15\0\1\u04b3\6\0"+ + "\12\u04b3\1\u04a2\174\0\4\u04b4\2\0\1\u04b4\15\0\1\u04b4"+ + "\6\0\12\u04b4\14\0\1\u02c9\225\0\1\u0492\13\0\1\u02c9"+ + "\225\0\1\u0499\174\0\4\u043b\2\0\1\u043b\15\0\1\u043b"+ + "\6\0\12\u043b\14\0\1\u0286\225\0\1\u04a2\174\0\4\u0451"+ + "\2\0\1\u0451\15\0\1\u0451\6\0\12\u0451\14\0\1\u02c9"+ + "\11\0"; private static int [] zzUnpackTrans() { - int [] result = new int[80884]; + int [] result = new int[192294]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -2298,23 +2953,23 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\17\1\2\11\1\1\1\0\1\1\1\0"+ - "\1\1\6\0\2\1\1\0\3\1\1\0\1\1\1\0"+ - "\4\1\11\0\32\1\3\0\4\1\32\0\4\1\10\0"+ - "\1\11\1\0\23\1\2\0\1\1\1\0\7\1\3\0"+ - "\2\1\1\0\4\1\1\0\2\1\1\0\2\1\10\0"+ - "\1\1\32\0\1\1\1\0\11\1\1\0\1\1\2\0"+ - "\1\1\1\0\1\1\10\0\3\1\15\0\11\1\3\0"+ - "\2\1\1\0\4\1\1\0\4\1\1\0\2\1\1\0"+ - "\2\1\1\0\3\1\7\0\2\1\20\0\1\1\10\0"+ - "\1\1\3\0\1\1\32\0\3\1\23\0\1\1\27\0"+ - "\1\1\4\0\1\1\6\0\1\1\4\0\2\1\36\0"+ - "\1\1\51\0\1\1\42\0\1\1\50\0\1\1\122\0"+ - "\1\1\116\0\1\1\107\0\1\1\74\0\1\1\51\0"+ - "\1\1\333\0"; + "\1\0\1\11\27\1\2\11\12\1\15\0\1\1\1\0"+ + "\1\1\10\0\1\1\21\0\2\1\1\0\3\1\1\0"+ + "\1\1\1\0\4\1\46\0\32\1\3\0\4\1\32\0"+ + "\4\1\17\0\1\11\1\0\23\1\2\0\1\1\1\0"+ + "\7\1\3\0\2\1\1\0\4\1\1\0\2\1\1\0"+ + "\2\1\10\0\1\1\32\0\1\1\1\0\11\1\1\0"+ + "\1\1\2\0\1\1\1\0\1\1\10\0\3\1\15\0"+ + "\11\1\3\0\2\1\1\0\4\1\1\0\4\1\1\0"+ + "\2\1\1\0\2\1\1\0\3\1\7\0\2\1\20\0"+ + "\1\1\10\0\1\1\3\0\1\1\32\0\3\1\23\0"+ + "\1\1\27\0\1\1\4\0\1\1\6\0\1\1\4\0"+ + "\2\1\36\0\1\1\51\0\1\1\42\0\1\1\51\0"+ + "\1\1\122\0\1\1\117\0\1\1\107\0\1\1\74\0"+ + "\1\1\51\0\1\1\333\0"; private static int [] zzUnpackAttribute() { - int [] result = new int[1117]; + int [] result = new int[1204]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -2540,7 +3195,7 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 2336) { + while (i < 2802) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -2819,36 +3474,36 @@ public final class UAX29URLEmailTokenizer extends Tokenizer { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 8: - { if (populateAttributes(URL_TYPE)) return true; + case 7: + { if (populateAttributes(EMAIL_TYPE)) return true; } case 9: break; - case 5: - { if (populateAttributes(IDEOGRAPHIC_TYPE)) return true; - } - case 10: break; - case 1: - { /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ - } - case 11: break; - case 3: - { if (populateAttributes(NUMERIC_TYPE)) return true; - } - case 12: break; - case 6: - { if (populateAttributes(HIRAGANA_TYPE)) return true; - } - case 13: break; - case 4: - { if (populateAttributes(SOUTH_EAST_ASIAN_TYPE)) return true; - } - case 14: break; case 2: { if (populateAttributes(WORD_TYPE)) return true; } + case 10: break; + case 6: + { if (populateAttributes(HIRAGANA_TYPE)) return true; + } + case 11: break; + case 5: + { if (populateAttributes(IDEOGRAPHIC_TYPE)) return true; + } + case 12: break; + case 4: + { if (populateAttributes(SOUTH_EAST_ASIAN_TYPE)) return true; + } + case 13: break; + case 3: + { if (populateAttributes(NUMERIC_TYPE)) return true; + } + case 14: break; + case 1: + { /* Not numeric, word, ideographic, hiragana, or SE Asian -- ignore it. */ + } case 15: break; - case 7: - { if (populateAttributes(EMAIL_TYPE)) return true; + case 8: + { if (populateAttributes(URL_TYPE)) return true; } case 16: break; default: diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.jflex b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.jflex index fefd9c717cf..7d9dc405c37 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.jflex +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizer.jflex @@ -45,14 +45,6 @@ import org.apache.lucene.util.AttributeSource; *
  15. <IDEOGRAPHIC>: A single CJKV ideographic character
  16. *
  17. <HIRAGANA>: A single hiragana character
  18. * - * WARNING: Because JFlex does not support Unicode supplementary - * characters (characters above the Basic Multilingual Plane, which contains - * those up to and including U+FFFF), this scanner will not recognize them - * properly. If you need to be able to process text containing supplementary - * characters, consider using the ICU4J-backed implementation in modules/analysis/icu - * (org.apache.lucene.analysis.icu.segmentation.ICUTokenizer) - * instead of this class, since the ICU4J-backed implementation does not have - * this limitation. */ %% @@ -70,15 +62,30 @@ import org.apache.lucene.util.AttributeSource; super(in); %init} + +%include src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro +ALetter = ([\p{WB:ALetter}] | {ALetterSupp}) +Format = ([\p{WB:Format}] | {FormatSupp}) +Numeric = ([\p{WB:Numeric}] | {NumericSupp}) +Extend = ([\p{WB:Extend}] | {ExtendSupp}) +Katakana = ([\p{WB:Katakana}] | {KatakanaSupp}) +MidLetter = ([\p{WB:MidLetter}] | {MidLetterSupp}) +MidNum = ([\p{WB:MidNum}] | {MidNumSupp}) +MidNumLet = ([\p{WB:MidNumLet}] | {MidNumLetSupp}) +ExtendNumLet = ([\p{WB:ExtendNumLet}] | {ExtendNumLetSupp}) +ComplexContext = ([\p{LB:Complex_Context}] | {ComplexContextSupp}) +Han = ([\p{Script:Han}] | {HanSupp}) +Hiragana = ([\p{Script:Hiragana}] | {HiraganaSupp}) + // UAX#29 WB4. X (Extend | Format)* --> X // -ALetterEx = \p{WB:ALetter} [\p{WB:Format}\p{WB:Extend}]* +ALetterEx = {ALetter} ({Format} | {Extend})* // TODO: Convert hard-coded full-width numeric range to property intersection (something like [\p{Full-Width}&&\p{Numeric}]) once JFlex supports it -NumericEx = [\p{WB:Numeric}\uFF10-\uFF19] [\p{WB:Format}\p{WB:Extend}]* -KatakanaEx = \p{WB:Katakana} [\p{WB:Format}\p{WB:Extend}]* -MidLetterEx = [\p{WB:MidLetter}\p{WB:MidNumLet}] [\p{WB:Format}\p{WB:Extend}]* -MidNumericEx = [\p{WB:MidNum}\p{WB:MidNumLet}] [\p{WB:Format}\p{WB:Extend}]* -ExtendNumLetEx = \p{WB:ExtendNumLet} [\p{WB:Format}\p{WB:Extend}]* +NumericEx = ({Numeric} | [\uFF10-\uFF19]) ({Format} | {Extend})* +KatakanaEx = {Katakana} ({Format} | {Extend})* +MidLetterEx = ({MidLetter} | {MidNumLet}) ({Format} | {Extend})* +MidNumericEx = ({MidNum} | {MidNumLet}) ({Format} | {Extend})* +ExtendNumLetEx = {ExtendNumLet} ({Format} | {Extend})* // URL and E-mail syntax specifications: @@ -348,12 +355,12 @@ EMAIL = {EMAILlocalPart} "@" ({DomainNameStrict} | {EMAILbracketedHost}) // // http://www.unicode.org/reports/tr14/#SA // -\p{LB:Complex_Context}+ { if (populateAttributes(SOUTH_EAST_ASIAN_TYPE)) return true; } +{ComplexContext}+ { if (populateAttributes(SOUTH_EAST_ASIAN_TYPE)) return true; } // UAX#29 WB14. Any 梅 Any // -\p{Script:Han} { if (populateAttributes(IDEOGRAPHIC_TYPE)) return true; } -\p{Script:Hiragana} { if (populateAttributes(HIRAGANA_TYPE)) return true; } +{Han} { if (populateAttributes(IDEOGRAPHIC_TYPE)) return true; } +{Hiragana} { if (populateAttributes(HIRAGANA_TYPE)) return true; } // UAX#29 WB3. CR 脳 LF diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java b/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java index cff13e3b68d..5c7a46f0461 100644 --- a/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java +++ b/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestStandardAnalyzer.java @@ -201,4 +201,10 @@ public class TestStandardAnalyzer extends BaseTokenStreamTestCase { WordBreakTestUnicode_6_0_0 wordBreakTest = new WordBreakTestUnicode_6_0_0(); wordBreakTest.test(a); } + + public void testSupplementary() throws Exception { + BaseTokenStreamTestCase.assertAnalyzesTo(a, "皓瑓鑹遍崯鋰规劘鐎", + new String[] {"皓瑓", "鑹", "閸", "鋰", "鎰", "鐎"}, + new String[] { "", "", "", "", "", "" }); + } } diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java b/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java index 7111920d895..71b37361789 100644 --- a/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java +++ b/modules/analysis/common/src/test/org/apache/lucene/analysis/core/TestUAX29URLEmailTokenizer.java @@ -400,4 +400,10 @@ public class TestUAX29URLEmailTokenizer extends BaseTokenStreamTestCase { WordBreakTestUnicode_6_0_0 wordBreakTest = new WordBreakTestUnicode_6_0_0(); wordBreakTest.test(a); } + + public void testSupplementary() throws Exception { + BaseTokenStreamTestCase.assertAnalyzesTo(a, "皓瑓鑹遍崯鋰规劘鐎", + new String[] {"皓瑓", "鑹", "閸", "鋰", "鎰", "鐎"}, + new String[] { "", "", "", "", "", "" }); + } } diff --git a/modules/analysis/icu/build.xml b/modules/analysis/icu/build.xml index 3af4aaa66f8..db7969a114b 100644 --- a/modules/analysis/icu/build.xml +++ b/modules/analysis/icu/build.xml @@ -107,6 +107,23 @@ are part of the ICU4C package. See http://site.icu-project.org/ + + + + + + + + + + + BMP */ +public class GenerateJFlexSupplementaryMacros { + private static final UnicodeSet BMP = new UnicodeSet("[\u0000-\uFFFF]"); + + public static void main(String args[]) throws Exception { + outputMacro("ALetterSupp", "[:WordBreak=ALetter:]"); + outputMacro("FormatSupp", "[:WordBreak=Format:]"); + outputMacro("ExtendSupp", "[:WordBreak=Extend:]"); + outputMacro("NumericSupp", "[:WordBreak=Numeric:]"); + outputMacro("KatakanaSupp", "[:WordBreak=Katakana:]"); + outputMacro("MidLetterSupp", "[:WordBreak=MidLetter:]"); + outputMacro("MidNumSupp", "[:WordBreak=MidNum:]"); + outputMacro("MidNumLetSupp", "[:WordBreak=MidNumLet:]"); + outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); + outputMacro("ExtendNumLetSupp", "[:WordBreak=ExtendNumLet:]"); + outputMacro("ComplexContextSupp", "[:LineBreak=Complex_Context:]"); + outputMacro("HanSupp", "[:Script=Han:]"); + outputMacro("HiraganaSupp", "[:Script=Hiragana:]"); + } + + // we have to carefully output the possibilities as compact utf-16 + // range expressions, or jflex will OOM! + static void outputMacro(String name, String pattern) { + UnicodeSet set = new UnicodeSet(pattern); + set.removeAll(BMP); + System.out.println(name + " = ("); + // if the set is empty, we have to do this or jflex will barf + if (set.isEmpty()) { + System.out.println("\t []"); + } + + HashMap utf16ByLead = new HashMap(); + for (UnicodeSetIterator it = new UnicodeSetIterator(set); it.next();) { + char utf16[] = Character.toChars(it.codepoint); + UnicodeSet trails = utf16ByLead.get(utf16[0]); + if (trails == null) { + trails = new UnicodeSet(); + utf16ByLead.put(utf16[0], trails); + } + trails.add(utf16[1]); + } + + boolean isFirst = true; + for (Character c : utf16ByLead.keySet()) { + UnicodeSet trail = utf16ByLead.get(c); + System.out.print( isFirst ? "\t " : "\t| "); + isFirst = false; + System.out.println("([\\u" + Integer.toHexString(c) + "]" + trail.getRegexEquivalent() + ")"); + } + System.out.println(")"); + } +} From 61872be09dfd549f9b81db57564137a776c75701 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 6 Jan 2011 14:30:37 +0000 Subject: [PATCH 011/252] LUCENE-2842: add Galician analyzer, Portuguese RSLP git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055892 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/contrib/CHANGES.txt | 3 + .../lucene/analysis/gl/GalicianAnalyzer.java | 129 ++++ .../analysis/gl/GalicianStemFilter.java | 60 ++ .../lucene/analysis/gl/GalicianStemmer.java | 83 +++ .../apache/lucene/analysis/gl/package.html | 22 + .../analysis/pt/PortugueseMinimalStemmer.java | 90 +-- .../analysis/pt/PortugueseStemFilter.java | 60 ++ .../lucene/analysis/pt/PortugueseStemmer.java | 102 +++ .../lucene/analysis/pt/RSLPStemmerBase.java | 345 ++++++++++ .../lucene/analysis/util/StemmerUtil.java | 19 + .../apache/lucene/analysis/gl/galician.rslp | 647 ++++++++++++++++++ .../apache/lucene/analysis/gl/stopwords.txt | 161 +++++ .../apache/lucene/analysis/pt/portuguese.rslp | 456 ++++++++++++ .../analysis/gl/TestGalicianAnalyzer.java | 53 ++ .../analysis/gl/TestGalicianStemFilter.java | 52 ++ .../apache/lucene/analysis/gl/gltestdata.zip | Bin 0 -> 40515 bytes .../analysis/pt/TestPortugueseStemFilter.java | 69 ++ .../lucene/analysis/pt/ptrslptestdata.zip | Bin 0 -> 132599 bytes .../analysis/GalicianStemFilterFactory.java | 28 + .../analysis/PortugueseStemFilterFactory.java | 28 + .../TestGalicianStemFilterFactory.java | 36 + .../TestPortugueseStemFilterFactory.java | 36 + 22 files changed, 2394 insertions(+), 85 deletions(-) create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianAnalyzer.java create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilter.java create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemmer.java create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/gl/package.html create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilter.java create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemmer.java create mode 100644 modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java create mode 100644 modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp create mode 100644 modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/stopwords.txt create mode 100644 modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp create mode 100644 modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianAnalyzer.java create mode 100644 modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilter.java create mode 100644 modules/analysis/common/src/test/org/apache/lucene/analysis/gl/gltestdata.zip create mode 100644 modules/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilter.java create mode 100644 modules/analysis/common/src/test/org/apache/lucene/analysis/pt/ptrslptestdata.zip create mode 100644 solr/src/java/org/apache/solr/analysis/GalicianStemFilterFactory.java create mode 100644 solr/src/java/org/apache/solr/analysis/PortugueseStemFilterFactory.java create mode 100644 solr/src/test/org/apache/solr/analysis/TestGalicianStemFilterFactory.java create mode 100644 solr/src/test/org/apache/solr/analysis/TestPortugueseStemFilterFactory.java diff --git a/lucene/contrib/CHANGES.txt b/lucene/contrib/CHANGES.txt index 24eed06507a..25ada890702 100644 --- a/lucene/contrib/CHANGES.txt +++ b/lucene/contrib/CHANGES.txt @@ -281,6 +281,9 @@ New features BooleanModifiersQueryNodeProcessor, for example instead of GroupQueryNodeProcessor. (Adriano Crestani via Robert Muir) + * LUCENE-2842: Add analyzer for Galician. Also adds the RSLP (Orengo) stemmer + for Portuguese. (Robert Muir) + Build * LUCENE-2124: Moved the JDK-based collation support from contrib/collation diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianAnalyzer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianAnalyzer.java new file mode 100644 index 00000000000..9a64f045d9e --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianAnalyzer.java @@ -0,0 +1,129 @@ +package org.apache.lucene.analysis.gl; + +/** + * 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.io.Reader; +import java.util.Set; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.core.LowerCaseFilter; +import org.apache.lucene.analysis.core.StopFilter; +import org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.standard.StandardFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; +import org.apache.lucene.analysis.util.CharArraySet; +import org.apache.lucene.analysis.util.StopwordAnalyzerBase; +import org.apache.lucene.analysis.util.WordlistLoader; +import org.apache.lucene.util.Version; + +/** + * {@link Analyzer} for Galician. + */ +public final class GalicianAnalyzer extends StopwordAnalyzerBase { + private final Set stemExclusionSet; + + /** File containing default Galician stopwords. */ + public final static String DEFAULT_STOPWORD_FILE = "stopwords.txt"; + + /** + * Returns an unmodifiable instance of the default stop words set. + * @return default stop words set. + */ + public static Set getDefaultStopSet(){ + return DefaultSetHolder.DEFAULT_STOP_SET; + } + + /** + * Atomically loads the DEFAULT_STOP_SET in a lazy fashion once the outer class + * accesses the static final set the first time.; + */ + private static class DefaultSetHolder { + static final Set DEFAULT_STOP_SET; + + static { + try { + DEFAULT_STOP_SET = WordlistLoader.getWordSet(GalicianAnalyzer.class, + DEFAULT_STOPWORD_FILE); + } catch (IOException ex) { + // default set should always be present as it is part of the + // distribution (JAR) + throw new RuntimeException("Unable to load default stopword set"); + } + } + } + + /** + * Builds an analyzer with the default stop words: {@link #DEFAULT_STOPWORD_FILE}. + */ + public GalicianAnalyzer(Version matchVersion) { + this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET); + } + + /** + * Builds an analyzer with the given stop words. + * + * @param matchVersion lucene compatibility version + * @param stopwords a stopword set + */ + public GalicianAnalyzer(Version matchVersion, Set stopwords) { + this(matchVersion, stopwords, CharArraySet.EMPTY_SET); + } + + /** + * Builds an analyzer with the given stop words. If a non-empty stem exclusion set is + * provided this analyzer will add a {@link KeywordMarkerFilter} before + * stemming. + * + * @param matchVersion lucene compatibility version + * @param stopwords a stopword set + * @param stemExclusionSet a set of terms not to be stemmed + */ + public GalicianAnalyzer(Version matchVersion, Set stopwords, Set stemExclusionSet) { + super(matchVersion, stopwords); + this.stemExclusionSet = CharArraySet.unmodifiableSet(CharArraySet.copy( + matchVersion, stemExclusionSet)); + } + + /** + * Creates a + * {@link org.apache.lucene.analysis.util.ReusableAnalyzerBase.TokenStreamComponents} + * which tokenizes all the text in the provided {@link Reader}. + * + * @return A + * {@link org.apache.lucene.analysis.util.ReusableAnalyzerBase.TokenStreamComponents} + * built from an {@link StandardTokenizer} filtered with + * {@link StandardFilter}, {@link LowerCaseFilter}, {@link StopFilter} + * , {@link KeywordMarkerFilter} if a stem exclusion set is + * provided and {@link GalicianStemFilter}. + */ + @Override + protected TokenStreamComponents createComponents(String fieldName, + Reader reader) { + final Tokenizer source = new StandardTokenizer(matchVersion, reader); + TokenStream result = new StandardFilter(matchVersion, source); + result = new LowerCaseFilter(matchVersion, result); + result = new StopFilter(matchVersion, result, stopwords); + if(!stemExclusionSet.isEmpty()) + result = new KeywordMarkerFilter(result, stemExclusionSet); + result = new GalicianStemFilter(result); + return new TokenStreamComponents(source, result); + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilter.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilter.java new file mode 100644 index 00000000000..38bf6a181ec --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilter.java @@ -0,0 +1,60 @@ +package org.apache.lucene.analysis.gl; + +/** + * 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.analysis.TokenFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +import org.apache.lucene.analysis.tokenattributes.KeywordAttribute; + +/** + * A {@link TokenFilter} that applies {@link GalicianStemmer} to stem + * Galician words. + *

    + * To prevent terms from being stemmed use an instance of + * {@link KeywordMarkerFilter} or a custom {@link TokenFilter} that sets + * the {@link KeywordAttribute} before this {@link TokenStream}. + *

    + */ +public final class GalicianStemFilter extends TokenFilter { + private final GalicianStemmer stemmer = new GalicianStemmer(); + private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); + private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class); + + public GalicianStemFilter(TokenStream input) { + super(input); + } + + @Override + public boolean incrementToken() throws IOException { + if (input.incrementToken()) { + if (!keywordAttr.isKeyword()) { + // this stemmer increases word length by 1: worst case '*莽om' -> '*ci贸n' + final int len = termAtt.length(); + final int newlen = stemmer.stem(termAtt.resizeBuffer(len+1), len); + termAtt.setLength(newlen); + } + return true; + } else { + return false; + } + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemmer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemmer.java new file mode 100644 index 00000000000..ba2ffb32964 --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemmer.java @@ -0,0 +1,83 @@ +package org.apache.lucene.analysis.gl; + +/** + * 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.util.Map; + +import org.apache.lucene.analysis.pt.RSLPStemmerBase; + +/** + * Galician stemmer implementing "Regras do lematizador para o galego". + * + * @see RSLPStemmerBase + * @see Description of rules + */ +public class GalicianStemmer extends RSLPStemmerBase { + private static final Step plural, unification, adverb, augmentative, noun, verb, vowel; + + static { + Map steps = parse(GalicianStemmer.class, "galician.rslp"); + plural = steps.get("Plural"); + unification = steps.get("Unification"); + adverb = steps.get("Adverb"); + augmentative = steps.get("Augmentative"); + noun = steps.get("Noun"); + verb = steps.get("Verb"); + vowel = steps.get("Vowel"); + } + + /** + * @param s buffer, oversized to at least len+1 + * @param len initial valid length of buffer + * @return new valid length, stemmed + */ + public int stem(char s[], int len) { + assert s.length >= len + 1 : "this stemmer requires an oversized array of at least 1"; + + len = plural.apply(s, len); + len = unification.apply(s, len); + len = adverb.apply(s, len); + + int oldlen; + do { + oldlen = len; + len = augmentative.apply(s, len); + } while (len != oldlen); + + oldlen = len; + len = noun.apply(s, len); + if (len == oldlen) { /* suffix not removed */ + len = verb.apply(s, len); + } + + len = vowel.apply(s, len); + + // RSLG accent removal + for (int i = 0; i < len; i++) + switch(s[i]) { + case '谩': s[i] = 'a'; break; + case '茅': + case '锚': s[i] = 'e'; break; + case '铆': s[i] = 'i'; break; + case '贸': s[i] = 'o'; break; + case '煤': s[i] = 'u'; break; + } + + return len; + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/package.html b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/package.html new file mode 100644 index 00000000000..f6d977a77c4 --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/gl/package.html @@ -0,0 +1,22 @@ + + + + +Analyzer for Galician. + + diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemmer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemmer.java index 7ce19e37445..01342ce9a11 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemmer.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemmer.java @@ -1,10 +1,5 @@ package org.apache.lucene.analysis.pt; -import java.util.Arrays; - -import org.apache.lucene.analysis.util.CharArraySet; -import org.apache.lucene.util.Version; - /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -31,89 +26,14 @@ import org.apache.lucene.util.Version; * which is just the plural reduction step of the RSLP * algorithm from A Stemming Algorithmm for the Portuguese Language, * Orengo et al. + * @see RSLPStemmerBase */ -public class PortugueseMinimalStemmer { +public class PortugueseMinimalStemmer extends RSLPStemmerBase { - private static final CharArraySet excIS = new CharArraySet(Version.LUCENE_31, - Arrays.asList("l谩pis", "cais", "mais", "cr煤cis", "biqu铆nis", "pois", - "depois","dois","leis"), - false); - - private static final CharArraySet excS = new CharArraySet(Version.LUCENE_31, - Arrays.asList("ali谩s", "pires", "l谩pis", "cais", "mais", "mas", "menos", - "f茅rias", "fezes", "p锚sames", "cr煤cis", "g谩s", "atr谩s", "mois茅s", - "atrav茅s", "conv茅s", "锚s", "pa铆s", "ap贸s", "ambas", "ambos", - "messias", "depois"), - false); + private static final Step pluralStep = + parse(PortugueseMinimalStemmer.class, "portuguese.rslp").get("Plural"); public int stem(char s[], int len) { - if (len < 3 || s[len-1] != 's') - return len; - - if (s[len-2] == 'n') { - len--; - s[len-1] = 'm'; - return len; - } - - if (len >= 6 && s[len-3] == '玫' && s[len-2] == 'e') { - len--; - s[len-2] = '茫'; - s[len-1] = 'o'; - return len; - } - - if (len >= 4 && s[len-3] == '茫' && s[len-2] == 'e') - if (!(len == 4 && s[0] == 'm')) { - len--; - s[len-1] = 'o'; - return len; - } - - if (len >= 4 && s[len-2] == 'i') { - if (s[len-3] == 'a') - if (!(len == 4 && (s[0] == 'c' || s[0] == 'm'))) { - len--; - s[len-1] = 'l'; - return len; - } - - if (len >= 5 && s[len-3] == '茅') { - len--; - s[len-2] = 'e'; - s[len-1] = 'l'; - return len; - } - - if (len >= 5 && s[len-3] == 'e') { - len--; - s[len-1] = 'l'; - return len; - } - - if (len >= 5 && s[len-3] == '贸') { - len--; - s[len-2] = 'o'; - s[len-1] = 'l'; - return len; - } - - if (!excIS.contains(s, 0, len)) { - s[len-1] = 'l'; - return len; - } - } - - if (len >= 6 && s[len-3] == 'l' && s[len-2] == 'e') - return len - 2; - - if (len >= 6 && s[len-3] == 'r' && s[len-2] == 'e') - if (!(len == 7 && s[0] == '谩' && s[1] == 'r' && s[2] == 'v' && s[3] == 'o')) - return len - 2; - - if (excS.contains(s, 0, len)) - return len; - else - return len-1; + return pluralStep.apply(s, len); } } diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilter.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilter.java new file mode 100644 index 00000000000..c761abd14e9 --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilter.java @@ -0,0 +1,60 @@ +package org.apache.lucene.analysis.pt; + +/** + * 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.analysis.TokenFilter; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter; +import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; +import org.apache.lucene.analysis.tokenattributes.KeywordAttribute; + +/** + * A {@link TokenFilter} that applies {@link PortugueseStemmer} to stem + * Portuguese words. + *

    + * To prevent terms from being stemmed use an instance of + * {@link KeywordMarkerFilter} or a custom {@link TokenFilter} that sets + * the {@link KeywordAttribute} before this {@link TokenStream}. + *

    + */ +public final class PortugueseStemFilter extends TokenFilter { + private final PortugueseStemmer stemmer = new PortugueseStemmer(); + private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); + private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class); + + public PortugueseStemFilter(TokenStream input) { + super(input); + } + + @Override + public boolean incrementToken() throws IOException { + if (input.incrementToken()) { + if (!keywordAttr.isKeyword()) { + // this stemmer increases word length by 1: worst case '*茫' -> '*茫o' + final int len = termAtt.length(); + final int newlen = stemmer.stem(termAtt.resizeBuffer(len+1), len); + termAtt.setLength(newlen); + } + return true; + } else { + return false; + } + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemmer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemmer.java new file mode 100644 index 00000000000..de0e497db9c --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemmer.java @@ -0,0 +1,102 @@ +package org.apache.lucene.analysis.pt; + +/** + * 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.util.Map; + +/** + * Portuguese stemmer implementing the RSLP (Removedor de Sufixos da Lingua Portuguesa) + * algorithm. This is sometimes also referred to as the Orengo stemmer. + * + * @see RSLPStemmerBase + */ +public class PortugueseStemmer extends RSLPStemmerBase { + private static final Step plural, feminine, adverb, augmentative, noun, verb, vowel; + + static { + Map steps = parse(PortugueseStemmer.class, "portuguese.rslp"); + plural = steps.get("Plural"); + feminine = steps.get("Feminine"); + adverb = steps.get("Adverb"); + augmentative = steps.get("Augmentative"); + noun = steps.get("Noun"); + verb = steps.get("Verb"); + vowel = steps.get("Vowel"); + } + + /** + * @param s buffer, oversized to at least len+1 + * @param len initial valid length of buffer + * @return new valid length, stemmed + */ + public int stem(char s[], int len) { + assert s.length >= len + 1 : "this stemmer requires an oversized array of at least 1"; + + len = plural.apply(s, len); + len = adverb.apply(s, len); + len = feminine.apply(s, len); + len = augmentative.apply(s, len); + + int oldlen = len; + len = noun.apply(s, len); + + if (len == oldlen) { /* suffix not removed */ + oldlen = len; + + len = verb.apply(s, len); + + if (len == oldlen) { /* suffix not removed */ + len = vowel.apply(s, len); + } + } + + // rslp accent removal + for (int i = 0; i < len; i++) { + switch(s[i]) { + case '脿': + case '谩': + case '芒': + case '茫': + case '盲': + case '氓': s[i] = 'a'; break; + case '莽': s[i] = 'c'; break; + case '猫': + case '茅': + case '锚': + case '毛': s[i] = 'e'; break; + case '矛': + case '铆': + case '卯': + case '茂': s[i] = 'i'; break; + case '帽': s[i] = 'n'; break; + case '貌': + case '贸': + case '么': + case '玫': + case '枚': s[i] = 'o'; break; + case '霉': + case '煤': + case '没': + case '眉': s[i] = 'u'; break; + case '媒': + case '每': s[i] = 'y'; break; + } + } + return len; + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java new file mode 100644 index 00000000000..e27f6d35137 --- /dev/null +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java @@ -0,0 +1,345 @@ +package org.apache.lucene.analysis.pt; + +/** + * 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.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.lucene.analysis.util.CharArraySet; +import org.apache.lucene.util.Version; + +import static org.apache.lucene.analysis.util.StemmerUtil.*; + +/** + * Base class for stemmers that use a set of RSLP-like stemming steps. + *

    + * RSLP (Removedor de Sufixos da Lingua Portuguesa) is an algorithm designed + * originally for stemming the Portuguese language, described in the paper + * A Stemming Algorithm for the Portuguese Language, Orengo et. al. + *

    + * Since this time a plural-only modification (RSLP-S) as well as a modification + * for the Galician language have been implemented. This class parses a configuration + * file that describes {@link Step}s, where each Step contains a set of {@link Rule}s. + *

    + * The general rule format is: + *

    { "suffix", N, "replacement", { "exception1", "exception2", ...}}
    + * where: + *
      + *
    • suffix is the suffix to be removed (such as "inho"). + *
    • N is the min stem size, where stem is defined as the candidate stem + * after removing the suffix (but before appending the replacement!) + *
    • replacement is an optimal string to append after removing the suffix. + * This can be the empty string. + *
    • exceptions is an optional list of exceptions, patterns that should + * not be stemmed. These patterns can be specified as whole word or suffix (ends-with) + * patterns, depending upon the exceptions format flag in the step header. + *
    + *

    + * A step is an ordered list of rules, with a structure in this format: + *

    { "name", N, B, { "cond1", "cond2", ... } + * ... rules ... }; + *
    + * where: + *
      + *
    • name is a name for the step (such as "Plural"). + *
    • N is the min word size. Words that are less than this length bypass + * the step completely, as an optimization. Note: N can be zero, in this case this + * implementation will automatically calculate the appropriate value from the underlying + * rules. + *
    • B is a "boolean" flag specifying how exceptions in the rules are matched. + * A value of 1 indicates whole-word pattern matching, a value of 0 indicates that + * exceptions are actually suffixes and should be matched with ends-with. + *
    • conds are an optional list of conditions to enter the step at all. If + * the list is non-empty, then a word must end with one of these conditions or it will + * bypass the step completely as an optimization. + *
    + *

    + * @see RSLP description + * @lucene.internal + */ +public abstract class RSLPStemmerBase { + + /** + * A basic rule, with no exceptions. + */ + protected static class Rule { + protected final char suffix[]; + protected final char replacement[]; + protected final int min; + + /** + * Create a rule. + * @param suffix suffix to remove + * @param min minimum stem length + * @param replacement replacement string + */ + public Rule(String suffix, int min, String replacement) { + this.suffix = suffix.toCharArray(); + this.replacement = replacement.toCharArray(); + this.min = min; + } + + /** + * @return true if the word matches this rule. + */ + public boolean matches(char s[], int len) { + return (len - suffix.length >= min && endsWith(s, len, suffix)); + } + + /** + * @return new valid length of the string after firing this rule. + */ + public int replace(char s[], int len) { + if (replacement.length > 0) { + System.arraycopy(replacement, 0, s, len - suffix.length, replacement.length); + } + return len - suffix.length + replacement.length; + } + } + + /** + * A rule with a set of whole-word exceptions. + */ + protected static class RuleWithSetExceptions extends Rule { + protected final CharArraySet exceptions; + + public RuleWithSetExceptions(String suffix, int min, String replacement, + String[] exceptions) { + super(suffix, min, replacement); + for (int i = 0; i < exceptions.length; i++) { + if (!exceptions[i].endsWith(suffix)) + System.err.println("warning: useless exception '" + exceptions[i] + "' does not end with '" + suffix + "'"); + } + this.exceptions = new CharArraySet(Version.LUCENE_31, + Arrays.asList(exceptions), false); + } + + @Override + public boolean matches(char s[], int len) { + return super.matches(s, len) && !exceptions.contains(s, 0, len); + } + } + + /** + * A rule with a set of exceptional suffixes. + */ + protected static class RuleWithSuffixExceptions extends Rule { + // TODO: use a more efficient datastructure: automaton? + protected final char[][] exceptions; + + public RuleWithSuffixExceptions(String suffix, int min, String replacement, + String[] exceptions) { + super(suffix, min, replacement); + for (int i = 0; i < exceptions.length; i++) { + if (!exceptions[i].endsWith(suffix)) + System.err.println("warning: useless exception '" + exceptions[i] + "' does not end with '" + suffix + "'"); + } + this.exceptions = new char[exceptions.length][]; + for (int i = 0; i < exceptions.length; i++) + this.exceptions[i] = exceptions[i].toCharArray(); + } + + @Override + public boolean matches(char s[], int len) { + if (!super.matches(s, len)) + return false; + + for (int i = 0; i < exceptions.length; i++) + if (endsWith(s, len, exceptions[i])) + return false; + + return true; + } + } + + /** + * A step containing a list of rules. + */ + protected static class Step { + protected final String name; + protected final Rule rules[]; + protected final int min; + protected final char[][] suffixes; + + /** + * Create a new step + * @param name Step's name. + * @param rules an ordered list of rules. + * @param min minimum word size. if this is 0 it is automatically calculated. + * @param suffixes optional list of conditional suffixes. may be null. + */ + public Step(String name, Rule rules[], int min, String suffixes[]) { + this.name = name; + this.rules = rules; + if (min == 0) { + min = Integer.MAX_VALUE; + for (Rule r : rules) + min = Math.min(min, r.min + r.suffix.length); + } + this.min = min; + + if (suffixes == null || suffixes.length == 0) { + this.suffixes = null; + } else { + this.suffixes = new char[suffixes.length][]; + for (int i = 0; i < suffixes.length; i++) + this.suffixes[i] = suffixes[i].toCharArray(); + } + } + + /** + * @return new valid length of the string after applying the entire step. + */ + public int apply(char s[], int len) { + if (len < min) + return len; + + if (suffixes != null) { + boolean found = false; + + for (int i = 0; i < suffixes.length; i++) + if (endsWith(s, len, suffixes[i])) { + found = true; + break; + } + + if (!found) return len; + } + + for (int i = 0; i < rules.length; i++) { + if (rules[i].matches(s, len)) + return rules[i].replace(s, len); + } + + return len; + } + } + + /** + * Parse a resource file into an RSLP stemmer description. + * @return a Map containing the named Steps in this description. + */ + protected static Map parse(Class clazz, String resource) { + // TODO: this parser is ugly, but works. use a jflex grammar instead. + try { + InputStream is = clazz.getResourceAsStream(resource); + LineNumberReader r = new LineNumberReader(new InputStreamReader(is, "UTF-8")); + Map steps = new HashMap(); + String step; + while ((step = readLine(r)) != null) { + Step s = parseStep(r, step); + steps.put(s.name, s); + } + r.close(); + return steps; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static final Pattern headerPattern = + Pattern.compile("^\\{\\s*\"([^\"]*)\",\\s*([0-9]+),\\s*(0|1),\\s*\\{(.*)\\},\\s*$"); + private static final Pattern stripPattern = + Pattern.compile("^\\{\\s*\"([^\"]*)\",\\s*([0-9]+)\\s*\\}\\s*(,|(\\}\\s*;))$"); + private static final Pattern repPattern = + Pattern.compile("^\\{\\s*\"([^\"]*)\",\\s*([0-9]+),\\s*\"([^\"]*)\"\\}\\s*(,|(\\}\\s*;))$"); + private static final Pattern excPattern = + Pattern.compile("^\\{\\s*\"([^\"]*)\",\\s*([0-9]+),\\s*\"([^\"]*)\",\\s*\\{(.*)\\}\\s*\\}\\s*(,|(\\}\\s*;))$"); + + private static Step parseStep(LineNumberReader r, String header) throws IOException { + Matcher matcher = headerPattern.matcher(header); + if (!matcher.find()) { + throw new RuntimeException("Illegal Step header specified at line " + r.getLineNumber()); + } + assert matcher.groupCount() == 4; + String name = matcher.group(1); + int min = Integer.parseInt(matcher.group(2)); + int type = Integer.parseInt(matcher.group(3)); + String suffixes[] = parseList(matcher.group(4)); + Rule rules[] = parseRules(r, type); + return new Step(name, rules, min, suffixes); + } + + private static Rule[] parseRules(LineNumberReader r, int type) throws IOException { + List rules = new ArrayList(); + String line; + while ((line = readLine(r)) != null) { + Matcher matcher = stripPattern.matcher(line); + if (matcher.matches()) { + rules.add(new Rule(matcher.group(1), Integer.parseInt(matcher.group(2)), "")); + } else { + matcher = repPattern.matcher(line); + if (matcher.matches()) { + rules.add(new Rule(matcher.group(1), Integer.parseInt(matcher.group(2)), matcher.group(3))); + } else { + matcher = excPattern.matcher(line); + if (matcher.matches()) { + if (type == 0) { + rules.add(new RuleWithSuffixExceptions(matcher.group(1), + Integer.parseInt(matcher.group(2)), + matcher.group(3), + parseList(matcher.group(4)))); + } else { + rules.add(new RuleWithSetExceptions(matcher.group(1), + Integer.parseInt(matcher.group(2)), + matcher.group(3), + parseList(matcher.group(4)))); + } + } else { + throw new RuntimeException("Illegal Step rule specified at line " + r.getLineNumber()); + } + } + } + if (line.endsWith(";")) + return rules.toArray(new Rule[rules.size()]); + } + return null; + } + + private static String[] parseList(String s) { + if (s.isEmpty()) + return null; + String list[] = s.split(","); + for (int i = 0; i < list.length; i++) + list[i] = parseString(list[i].trim()); + return list; + } + + private static String parseString(String s) { + return s.substring(1, s.length()-1); + } + + private static String readLine(LineNumberReader r) throws IOException { + String line = null; + while ((line = r.readLine()) != null) { + line = line.trim(); + if (!line.isEmpty() && line.charAt(0) != '#') + return line; + } + return line; + } +} diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/util/StemmerUtil.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/util/StemmerUtil.java index bb5e04fbe7e..7aceadfae78 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/util/StemmerUtil.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/util/StemmerUtil.java @@ -56,6 +56,25 @@ public class StemmerUtil { return true; } + /** + * Returns true if the character array ends with the suffix. + * + * @param s Input Buffer + * @param len length of input buffer + * @param suffix Suffix string to test + * @return true if s ends with suffix + */ + public static boolean endsWith(char s[], int len, char suffix[]) { + final int suffixLen = suffix.length; + if (suffixLen > len) + return false; + for (int i = suffixLen - 1; i >= 0; i--) + if (s[len -(suffixLen - i)] != suffix[i]) + return false; + + return true; + } + /** * Delete a character in-place * diff --git a/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp new file mode 100644 index 00000000000..8be8478fd73 --- /dev/null +++ b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp @@ -0,0 +1,647 @@ +# Steps file for the RSLP stemmer. + +# Step 1: Plural Reduction +{ "Plural", 3, 1, {"s"}, + # bons -> bon + {"ns",1,"n",{"luns","furatap贸ns","furatapons"}}, + # xam贸s -> xam贸n + {"贸s",3,"贸n"}, + # bal玫es -> bal贸n + {"玫es",3,"贸n"}, + # capit茫es -> capit茫o + {"茫es",1,"茫o",{"m茫es","magalh茫es"}}, + # normais -> normal + {"ais",2,"al",{"cais","tais","mais","pais","ademais"}}, + {"谩is",2,"al",{"c谩is","t谩is", "m谩is", "p谩is", "adem谩is"}}, + # pap茅is -> papel + {"茅is",2,"el"}, + # pos铆beis -> pos铆bel + {"eis",2,"el"}, + # espanh贸is -> espanhol + {"贸is",2,"ol",{"escornab贸is"}}, + # caracois -> caracol + {"ois",2,"ol",{"escornabois"}}, + # cadr铆s -> cadril + {"铆s",2,"il",{"pa铆s"}}, + # cadris -> cadril + {"is",2,"il",{"menfis","pais","kinguis"}}, + # males -> mal + {"les",2,"l",{"ingles","marselles","montreales","senegales","manizales","m贸stoles","n谩poles"}}, + # mares -> mar + {"res",3,"r",{"petres","henares","c谩ceres","baleares","linares","londres","mieres","miraflores","m茅rcores","venres", "pires"}}, + # luces -> luz + {"ces",2,"z"}, + # luzes -> luz + {"zes",2,"z"}, + # leises -> lei + {"ises",3,"z"}, + # anim谩s -> animal + {"谩s",1,"al",{"m谩s"}}, + # gases -> gas + {"ses",2,"s"}, + # casas -> casa + {"s",2,"",{"barbad茅s","barcelon茅s","canton茅s","gabon茅s","llan茅s","medin茅s","escoc茅s","escoc锚s","franc锚s","barcelon锚s","canton锚s","macram茅s","reves","barcelones","cantones","gabones","llanes","magallanes","medines","escoces","frances","xoves","martes","ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","p锚sames","cr煤cis","pa铆s","cangas","atenas","asturias","canarias","filipinas","honduras","molucas","caldas","mascare帽as","micenas","covarrubias","psoas","贸culos","nupcias","xoves","martes","llanes"}}}; + +{ "Unification", 0, 0, {}, + # cansad铆simo -> cansad铆simo + {"铆ssimo",5,"铆simo"}, + # cansad铆sima -> cansad铆sima + {"铆ssima",5,"铆sima"}, + # homa莽o -> homazo + {"a莽o",4,"azo"}, + # mulhera莽a -> mulheraza + {"a莽a",4,"aza"}, + # xentu莽a -> xentuza + {"u莽a",4,"uza"}, + # manilhar -> manillar + {"lhar",2,"llar"}, + # colher -> coller + {"lher",2,"ller"}, + # melhor -> mellor + {"lhor",2,"llor"}, + # alho -> allo + {"lho",1,"llo"}, + # linhar -> li帽ar + {"nhar",2,"帽ar"}, + # penhor -> pe帽or + {"nhor",2,"帽or"}, + # anho -> a帽o + {"nho",1,"帽o"}, + # cunha -> cu帽a + {"nha",1,"帽a"}, + # hospital谩rio -> hospitalario + {"谩rio",3,"ario"}, + # bibliotec谩ria -> bibliotecaria + {"谩ria",3,"aria"}, + # agradable -> agrad谩bel + {"able",2,"谩bel"}, + # agrad谩vele -> agrad谩bel + {"谩vel",2,"谩bel"}, + # imposible -> impos铆bel + {"ible",2,"铆bel"}, + # impos铆vel -> impos铆bel + {"铆vel",2,"铆bel"}, + # imposi莽om -> imposici贸n + {"莽om",2,"ci贸n"}, + # garagem -> garaxe + {"agem",2,"axe"}, + # garage -> garaxe + {"age",2,"axe"}, + # impress茫o -> impress贸n + {"茫o",3,"贸n"}, + # irmao -> irm谩n + {"ao",1,"谩n"}, + # irmau -> irm谩n + {"au",1,"谩n"}, + # garrafom -> garraf贸n + {"om",3,"贸n"}, + # cantem -> canten + {"m",2,"n"}}; + +{ "Adverb", 0, 0, {}, + # felizmente -> feliz + {"mente",4,"",{"experimente","vehemente","sedimente"}}}; + +{ "Augmentative", 0, 1, {}, + # cansad铆simo -> cansad + {"d铆simo",5}, + # cansad铆sima -> cansad + {"d铆sima",5}, + # amabil铆simo -> ama + {"bil铆simo",3}, + # amabil铆sima -> ama + {"bil铆sima",3}, + # fort铆simo -> fort + {"铆simo",3}, + # fort铆sima -> fort + {"铆sima",3}, + # cent茅simo -> cent + {"茅simo",3}, + # cent茅sima -> cent + {"茅sima",3}, + # paup茅rrimo -> paup + {"茅rrimo",4}, + # paup茅rrima -> paup + {"茅rrima",4}, + # charlatana -> charlat + {"ana",2,"",{"argana","banana","choupana","espadana","faciana","iguana","lantana","macana","membrana","mesana","nirvana","obsidiana","palangana","pavana","persiana","pestana","porcelana","pseudomembrana","roldana","s谩bana","salangana","saragana","ventana"}}, + # charlat谩n -> charlat + {"谩n",3,"",{"adem谩n","bard谩n","barreg谩n","corric谩n","curric谩n","fais谩n","furac谩n","fust谩n","gab谩n","gabi谩n","gal谩n","ga帽谩n","lavac谩n","maz谩n","mour谩n","rabad谩n","ser谩n","serr谩n","tab谩n","tit谩n","tobog谩n","ver谩n","volc谩n","volov谩n"}}, + # homazo -> hom + {"azo",4,"",{"abrazo","espazo","andazo","bagazo","balazo","bandazo","cachazo","carazo","denazo","engazo","famazo","lampreazo","pantocazo","pedazo","pre帽azo","regazo","ribazo","sobrazo","terrazo","trompazo"}}, + # mulleraza -> muller + {"aza",3,"",{"alcarraza","ameaza","baraza","broucaza","burgaza","cabaza","cachaza","calaza","carpaza","carraza","coiraza","colmaza","fogaza","famaza","labaza","li帽aza","melaza","mordaza","paraza","pinaza","rabaza","rapaza","trancaza"}}, + # cascallo -> casc + {"allo",4,"",{"traballo"}}, + # xentalla -> xent + {"alla",4}, + # bocarra -> boc + {"arra",3,"",{"cigarra","cinzarra"}}, + # medicastro -> medic + {"astro",3,"",{"balastro","bimbastro","canastro","retropilastro"}}, + # poetastra -> poet + {"astra",3,"",{"banastra","canastra","contrapilastra","piastra","pilastra"}}, + # corp谩zio -> corp + {"谩zio",3,"",{"top谩zio"}}, + # soutelo -> sout + {"elo",4,"",{"bacelo","barrelo","bicarelo","biquelo","boquelo","botelo","bouquelo","cacarelo","cachelo","cadrelo","campelo","candelo","cantelo","carabelo","carambelo","caramelo","cercelo","cerebelo","chocarelo","coitelo","conchelo","corbelo","cotobelo","couselo","destelo","desvelo","esf谩celo","fandelo","fardelo","farelo","farnelo","flabelo","ganchelo","garfelo","involucelo","mantelo","montelo","outerelo","padicelo","pesadelo","pinguelo","piquelo","rampelo","rastrelo","restelo","tornecelo","trabelo","restrelo","portelo","ourelo","zarapelo"}}, + # avioneta -> avion + {"eta",3,"",{"arqueta","atleta","avoceta","baioneta","baldeta","banqueta","barraganeta","barreta","borleta","buceta","caceta","calceta","caldeta","cambeta","canaleta","caneta","carreta","cerceta","chaparreta","chapeta","chareta","chincheta","colcheta","cometa","corbeta","corveta","cuneta","desteta","espeta","espoleta","estafeta","esteta","faceta","falanxeta","frasqueta","gaceta","gabeta","galleta","garabeta","gaveta","glorieta","lagareta","lambeta","lanceta","libreta","maceta","macheta","maleta","malleta","mareta","marreta","meseta","mofeta","muleta","peseta","planeta","raqueta","regreta","saqueta","veleta","vendeta","vi帽eta"}}, + # guapete -> guap + {"ete",3,"",{"alfinete","ariete","bacinete","banquete","barallete","barrete","billete","binguelete","birrete","bonete","bosquete","bufete","burlete","cabalete","cacahuete","cavinete","capacete","carrete","casarete","casete","chupete","clarinete","colchete","colete","capete","curupete","disquete","estilete","falsete","ferrete","filete","gallardete","gobelete","inglete","machete","miquelete","molete","mosquete","piquete","ribete","rodete","rolete","roquete","sorvete","vedete","vendete"}}, + # pr谩ctica -> pr谩ct + {"ica",3,"",{"andarica","bot谩nica","botica","dial茅ctica","din谩mica","f铆sica","formica","gr谩fica","marica","t煤nica"}}, + # pr谩ctico -> pr谩ct + {"ico",3,"",{"conico","acetifico","acidifico"}}, + # trapexo -> trap + {"exo",3,"",{"arpexo","arquexo","asexo","axexo","azulexo","badexo","bafexo","bocexo","bosquexo","boubexo","cacarexo","carrexo","cascarexo","castrexo","convexo","cotexo","desexo","despexo","forcexo","gabexo","gargarexo","gorgolexo","inconexo","manexo","merexo","narnexo","padexo","patexo","sopexo","varexo"}}, + {"exa",3,"",{"airexa","bandexa","carrexa","envexa","igrexa","larexa","patexa","presexa","sobexa"}}, + # multid茫o -> mult + {"id茫o",3}, + # pequeni帽o -> pequeno + {"i帽o",3,"o",{"cami帽o","cari帽o","comi帽o","golfi帽o","padri帽o","sobri帽o","vici帽o","veci帽o"}}, + # pequeni帽a -> pequena + {"i帽a",3,"a",{"camari帽a","campi帽a","entreli帽a","espi帽a","fari帽a","mori帽a","vali帽a"}}, + # grandito -> grand + {"ito",3,""}, + # grandita -> grand + {"ita",3,""}, + # anomaloide -> animal + {"oide",3,"",{"anaroide","aneroide","asteroide","axoide","cardioide","celuloide","coronoide","discoide","espermatozoide","espiroide","esquizoide","esteroide","glenoide","linfoide","hemorroide","melaloide","sacaroide","tetraploide","varioloide"}}, + # cazola -> caz + {"ola",3,"",{"aixola","ampola","argola","arola","arter铆ola","bandola","b铆tola","bract茅ola","cachola","carambola","carapola","carola","carrandiola","catrapola","cebola","centola","champola","chatola","cirola","c铆tola","consola","corola","empola","escarola","esmola","estola","fitola","flor铆cola","gara帽ola","g谩rgola","garxola","glicocola","g贸ndola","mariola","marola","michola","pirola","rebola","rup铆cola","sax铆cola","s茅mola","tachola","t贸mbola"}}, + # pedrolo -> pedr + {"olo",3,"",{"arrolo","babiolo","cacharolo","caixarolo","carolo","carramolo","cascarolo","cirolo","codrolo","correolo","cotrolo","desconsolo","rebolo","repolo","subsolo","tixolo","t贸mbolo","torolo","tr茅molo","vac煤olo","xermolo","z贸colo"}}, + # vellote -> vell + {"ote",3,"",{"aigote","alcaiote","barbarote","balote","billote","cachote","camarote","capote","cebote","chichote","citote","cocorote","escote","ga帽ote","garrote","gavote","lamote","lapote","larapote","lingote","l铆tote","magote","marrote","matalote","pandote","paparote","rebote","tagarote","zarrote"}}, + # mozota -> moz + {"ota",3,"",{"as铆ntota","caiota","cambota","chacota","compota","creosota","curota","derrota","d铆spota","gamota","maniota","pelota","picota","pillota","pixota","queirota","remota"}}, + # gordocho -> gord + {"cho",3,"",{"abrocho","arrocho","carocho","falucho","bombacho","borracho","mostacho"}}, + # gordecha -> gord + {"cha",3,"",{"borracha","carracha","estacha","garnacha","limacha","remolacha","abrocha"}}, + # baratuco -> barat + {"uco",4,"",{"caduco","estuco","fachuco","malluco","saluco","trabuco"}}, + # borrachuzo -> borrach + {"uzo",3,"",{"carri帽ouzo","fachuzo","ma帽uzo","mestruzo","tapuzo"}}, + # xentuza -> xent + {"uza",3,"",{"barruza","chamuza","chapuza","charamuza","conduza","deduza","desluza","entreluza","induza","reluza","seduza","traduza","trasluza"}}, + # babuxa -> bab + {"uxa",3,"",{"caramuxa","carrabouxa","cartuxa","coruxa","curuxa","gaturuxa","maruxa","meruxa","miruxa","moruxa","muruxa","papuxa","rabuxa","trouxa"}}, + {"uxo",3,"",{"caramuxo","carouxo","carrabouxo","curuxo","debuxo","ganduxo","influxo","negouxo","pertuxo","refluxo"}}, + # grupello -> grup + {"ello",3,"",{"alborello","artello","botello","cachafello","calello","casarello","cazabello","cercello","cocerello","concello","consello","desparello","escaravello","espello","fedello","fervello","gagafello","gorrobello","nortello","pendello","troupello","trebello"}}, + # pontella -> pont + {"ella",3,"",{"alborella","bertorella","bocatella","botella","calella","cercella","gadella","grosella","lentella","movella","nocella","noitevella","parella","pelella","percebella","segorella","sabella"}}}; + +{ "Noun", 0, 0, {}, + # lealdade -> leal + {"dade",3,"",{"acridade","calidade"}}, + # clarificar -> clar + {"ificar",2}, + # brasileiro->brasil + {"eiro",3,"",{"agoireiro","bardalleiro","braseiro","barreiro","canteiro","capoeiro","carneiro","carteiro","cinceiro","faroleiro","mareiro","preguiceiro","quinteiro","raposeiro","retranqueiro","regueiro","sineiro","troleiro","ventureiro"}}, + # marisqueira -> marisqu + {"eira",3,"",{"cabeleira","canteira","cocheira","folleira","milleira"}}, + # hospitalario -> hospital + {"ario",3,"",{"armario","calcario","lionario","salario"}}, + # bibliotecaria -> bibliotec + {"aria",3,"",{"cetaria","coronaria","fumaria","linaria","lunaria","parietaria","saponaria","serpentaria"}}, + # humor铆stico -> humor + {"铆stico",3,"",{"bal铆stico", "ensa铆stico"}}, + # castrista -> castr + {"ista",3,"",{"batista","ciclista","fadista","operista","tenista","verista"}}, + # lavado -> lav + {"ado",2,"",{"grado","agrado"}}, + # decanato -> decan + {"ato",2,"",{"agnato"}}, + # xemido -> xem + {"ido",3,"",{"c谩ndido","c芒ndido","consolido","decidido","duvido","marido","r谩pido"}}, + # mantida -> mant + {"ida",3,"",{"bastida","d煤bida","dubida","duvida","ermida","茅xida","guarida","lapicida","medida","morida"}}, + {"铆da",3}, + # mant铆do -> mant + {"ido",3}, + # orelludo -> orell + {"udo",3,"",{"estudo","escudo"}}, + # orelluda -> orell + {"uda",3}, + {"ada",3,"",{"abada","alhada","allada","pitada"}}, + # comedela -> come + {"dela",3,"",{"cambadela","cavadela","forcadela","erisipidela","mortadela","espadela","fondedela","picadela","arandela","candela","cordela","escudela","pardela"}}, + # fontela -> font + {"ela",3,"",{"canela","capela","cotela","cubela","curupela","escarapela","esparrela","estela","fardela","flanela","fornela","franela","gabela","gamela","gavela","glumela","granicela","lamela","lapela","malvela","manela","manganela","mexarela","micela","mistela","novela","ourela","panela","parcela","pasarela","patamela","patela","paxarela","pipela","pitela","postela","pubela","restela","sabela","salmonela","secuela","sentinela","soldanela","subela","temoncela","tesela","tixela","tramela","trapela","varela","vitela","xanela","xestela"}}, + # agrad谩bel -> agrad + {"谩bel",2,"",{"af谩bel","fi谩bel"}}, + # combust铆bel -> combust + {"铆bel",2,"",{"cr铆bel","impos铆bel","pos铆bel","fis铆bel","fal铆bel"}}, + # fabricante -> frabrica + {"nte",3,"",{"alimente","adiante","acrescente","elefante","frequente","freq眉ente","gigante","instante","oriente","permanente","posante","possante","restaurante"}}, + # ignorancia -> ignora + {"ncia",3}, + # temperanza -> tempera + {"nza",3}, + {"acia",3,"",{"acracia","audacia","falacia","farmacia"}}, + # inmundicia -> inmund + {"icia",3,"",{"caricia","delicia","ledicia","malicia","milicia","noticia","pericia","presbicia","primicia","regalicia","sevicia","tiricia"}}, + # xustiza -> xust + {"iza",3,"",{"alvariza","baliza","cachiza","caniza","ca帽iza","carbaliza","carriza","chamariza","chapiza","fraguiza","latiza","longaniza","ma帽iza","nabiza","peliza","preguiza","rabiza"}}, + # clarexar -> clar + {"exar",3,"",{"palmexar"}}, + # administraci贸n -> administr + {"aci贸n",2,"",{"aeraci贸n"}}, + # expedici贸n -> exped + {"ici贸n",3,"",{"condici贸n","gornici贸n","monici贸n","nutrici贸n","petici贸n","posici贸n","sedici贸n","volici贸n"}}, + # excepci贸n -> except + {"ci贸n",3,"t"}, + # comprensi贸n -> comprens + {"si贸n",3,"s",{"abrasi贸n", "alusi贸n"}}, + # doaz贸n -> do + {"az贸n",2,"",{"armaz贸n"}}, + # garraf贸n -> garraf + {"贸n",3,"",{"abal贸n","acorde贸n","alci贸n","aldrab贸n","aler贸n","ali帽贸n","amb贸n","bomb贸n","calz贸n","camp贸n","canal贸n","cant贸n","capit贸n","ca帽贸n","cent贸n","cicl贸n","coll贸n","colof贸n","cop贸n","cot贸n","cup贸n","pet贸n","tir贸n","tour贸n","tur贸n","unci贸n","versi贸n","zub贸n","zurr贸n"}}, + # lambona -> lamb + {"ona",3,"",{"abandona","acetona","aleurona","amazona","an茅mona","bombona","cambona","carona","chacona","charamona","cincona","condona","cortisona","cretona","cretona","detona","estona","fitohormona","fregona","gerona","hidroquinona","hormona","lesiona","madona","maratona","matrona","metadona","mon贸tona","neurona","pamplona","peptona","poltrona","proxesterona","quinona","quinona","silicona","sulfona"}}, + # bretoa -> bret贸n + {"oa",3,"",{"abandoa","madroa","barbacoa","estoa","airoa","eiroa","amalloa","谩mboa","am茅ndoa","anchoa","antin茅boa","av茅ntoa","avoa","b谩goa","balboa","bisavoa","boroa","canoa","caroa","comadroa","coroa","茅ngoa","esp谩coa","filloa","f铆rgoa","gra帽oa","lagoa","lanzoa","magoa","m谩moa","morzoa","noiteboa","noraboa","para帽oa","persoa","queiroa","ra帽oa","t谩boa","tataravoa","teiroa"}}, + # demon铆aco -> demon铆 + {"aco",3}, + # demon铆aca -> demon铆 + {"aca",3,"",{"alpaca","barraca","bullaca","buraca","carraca","casaca","cavaca","cloaca","entresaca","ervellaca","espinaca","estaca","farraca","millaca","pastinaca","pataca","resaca","urraca","purraca"}}, + # carballal -> carball + {"al",4,"",{"afinal","animal","estatal","bisexual","bissexual","desleal","fiscal","formal","pessoal","persoal","liberal","postal","virtual","visual","pontual","puntual","homosexual","heterosexual"}}, + # nadador -> nada + {"dor",2,"",{"abaixador"}}, + # benfeitor -> benfei + {"tor",3,"",{"autor","motor","pastor","pintor"}}, + # produtor -> produt + {"or",2,"",{"asesor","assessor","favor","mellor","melhor","redor","rigor","sensor","tambor","tumor"}}, + # profesora -> profes + {"ora",3,"",{"albacora","an谩fora","谩ncora","apisoadora","ardora","ascospora","aurora","av茅spora","bit谩cora","can茅fora","cantimplora","cat谩fora","cepilladora","demora","descalcificadora","di谩spora","empacadora","ep铆fora","ecavadora","escora","eslora","espora","fotocompo帽edora","fotocopiadora","grampadora","is铆cora","lavadora","lixadora","macrospora","madr茅pora","madr谩gora","masora","mellora","met谩fora","microspora","mil茅pora","milp茅ndora","n茅cora","oospora","padeadora","pasiflora","p茅cora","p铆ldora","p贸lvora","ratinadora","r茅mora","retroescavadora","s贸fora","torradora","tr茅mbora","uredospora","v铆bora","v铆ncora","zoospora"}}, + # zapatar铆a -> zapat + {"ar铆a",3,"",{"librar铆a"}}, + # etiquetaxe -> etiquet + {"axe",3,"",{"aluaxe","amaraxe","amperaxe","bagaxe","balaxe","barcaxe","borraxe","bescaxe","cabotaxe","carraxe","cartilaxe","chantaxe","colaxe","coraxe","carruaxe","dragaxe","embalaxe","ensilaxe","epistaxe","fagundaxe","fichaxe","fogaxe","forraxe","fretaxe","friaxe","garaxe","homenaxe","leitaxe","li帽axe","listaxe","maraxe","marcaxe","maridaxe","masaxe","miraxe","montaxe","pasaxe","peaxe","portaxe","ramaxe","rebelaxe","rodaxe","romaxe","sintaxe","sondaxe","tiraxe","vantaxe","vendaxe","viraxe"}}, + # movedizo -> move + {"dizo",3}, + # limpeza -> limp + {"eza",3,"",{"alteza","beleza","fereza","fineza","vasteza","vileza"}}, + # rixidez -> rixid + {"ez",3,"",{"acidez","adultez","adustez","avidez","candidez","mudez","nenez","nudez","pomez"}}, + # mullerengo -> muller + {"engo",3}, + # chairego -> chair + {"ego",3,"",{"corego","derrego","entrego","lamego","sarego","sartego"}}, + # cari帽oso -> cari帽 + {"oso",3,"",{"afanoso","algoso","caldoso","caloso","cocoso","ditoso","favoso","fogoso","lamoso","mecoso","mocoso","precioso","rixoso","venoso","viroso","xesoso"}}, + # cari帽osa -> cari帽 + {"osa",3,"",{"mucosa","glicosa","baldosa","celulosa","isoglosa","nitrocelulosa","levulosa","ortosa","pectosa","preciosa","sacarosa","serosa","ventosa"}}, + # negrume -> negr + {"ume",3,"",{"agrume","albume","alcume","batume","cacume","cerrume","chorume","churume","costume","curtume","estrume","gafume","legume","perfume","queixume","zarrume"}}, + # altura -> alt + {"ura",3,"",{"albura","armadura","imatura","costura"}}, + # cuspi帽ar -> cusp + {"i帽ar",3}, + # febril -> febr + {"il",3,"",{"abril","alfil","anil","atril","badil","baril","barril","brasil","cadril","candil","cantil","carril","chamil","chancil","civil","cubil","d谩til","dif铆cil","d贸cil","edil","est茅ril","f谩cil","fr谩xil","funil","fusil","gr谩cil","gradil","h谩bil","hostil","marfil"}}, + # principesco -> princip + {"esco",4}, + # mourisco -> mour + {"isco",4}, + # esportivo -> esport + {"ivo",3,"",{"pasivo","positivo","passivo","possessivo","posesivo","pexotarivo","relativo"}}}; + +{ "Verb", 0, 0, {}, + # amaba -> am + {"aba",2}, + # andabade -> and + {"abade",2}, + # and谩bade -> and + {"谩bade",2}, + # chorabamo -> chor + {"abamo",2}, + # chor谩bamo -> chor + {"谩bamo",2}, + # moraban -> morab + {"aban",2}, + # andache -> and + {"ache",2}, + # andade -> and + {"ade",2}, + {"an",2}, + # cantando -> cant + {"ando",2}, + # cantar -> cant + {"ar",2,"",{"azar","bazar","patamar"}}, + # lembrarade -> lembra + {"arade",2}, + {"aramo",2}, + {"ar谩n",2}, + # cantaran -> cant + {"aran",2}, + # convid谩rade -> convid + {"谩rade",2}, + # convidar铆a -> convid + {"ar铆a",2}, + # cantariade -> cant + {"ariade",2}, + # cantar铆ade -> cant + {"ar铆ade",2}, + # cantarian -> cant + {"arian",2}, + # cantariamo -> cant + {"ariamo",2}, + # pescaron -> pesc + {"aron",2}, + # cantase -> cant + {"ase",2}, + # cantasede -> cant + {"asede",2}, + # cant谩sede -> cant + {"谩sede",2}, + # cantasemo -> cant + {"asemo",2}, + # cant谩semo -> cant + {"谩semo",2}, + # cantasen -> cant + {"asen",2}, + # loitavan -> loitav + {"avan",2}, + # cantar铆amo -> cant + {"ar铆amo",2}, + # cantassen -> cant + {"assen",2}, + # cant谩ssemo -> cant + {"谩ssemo",2}, + # beber铆amo -> beb + {"er铆amo",2}, + # beb锚ssemo -> beb + {"锚ssemo",2}, + # partir铆amo -> part + {"ir铆amo",3}, + # part铆ssemo -> part + {"铆ssemo",3}, + # cant谩ramo -> cant + {"谩ramo",2}, + # cant谩rei -> cant + {"谩rei",2}, + # cantaren -> cant + {"aren",2}, + # cantaremo -> cant + {"aremo",2}, + # cantar铆ei -> cant + {"ar铆ei",2}, + {"谩ssei",2}, + # cant谩vamo-> cant + {"谩vamo",2}, + # beb锚ramo -> beb + {"锚ramo",1}, + # beberemo -> beb + {"eremo",1}, + # beber铆ei -> beb + {"er铆ei",1}, + # beb锚ssei -> beb + {"锚ssei",1}, + # partir铆amo -> part + {"铆ramo",3}, + # partiremo -> part + {"iremo",3}, + # partir铆ei -> part + {"ir铆ei",3}, + # part铆ssei -> part + {"铆ssei",3}, + # partissen -> part + {"issen",3}, + # bebendo -> beb + {"endo",1}, + # partindo -> part + {"indo",3}, + # propondo -> prop + {"ondo",3}, + # cantarde -> cant + {"arde",2}, + # cantarei -> cant + {"arei",2}, + # cantaria -> cant + {"aria",2}, + # cantarmo -> cant + {"armo",2}, + # cantasse -> cant + {"asse",2}, + {"aste",2}, + # cant谩vei -> cant + {"谩vei",2}, + # perder茫o -> perd + {"er茫o",1}, + # beberde -> beb + {"erde",1}, + # beberei -> beb + {"erei",1}, + # beb锚rei -> beb + {"锚rei",1}, + # beberen -> beb + {"eren",2}, + # beberia -> beb + {"eria",1}, + # bebermo -> beb + {"ermo",1}, + # bebeste -> beb + {"este",1,"",{"faroeste","agreste"}}, + # beb铆amo -> beb + {"铆amo",1}, + # fuxian -> fux + {"ian",2,"",{"enfian","eloxian","ensaian"}}, + # partirde -> part + {"irde",2}, + # part铆rei -> part + {"irei",3,"",{"admirei"}}, + # partiren -> part + {"iren",3}, + # partiria -> part + {"iria",3}, + # partirmo -> part + {"irmo",3}, + # partisse -> part + {"isse",3}, + # partiste -> part + {"iste",4}, + {"iava",1,"",{"ampliava"}}, + # cantamo -> cant + {"amo",2}, + # funciona -> func + {"iona",3}, + # cantara -> cant + {"ara",2,"",{"arara","prepara"}}, + # enviar谩 -> envi + {"ar谩",2,"",{"alvar谩","bacar谩"}}, + # cantare -> cant + {"are",2,"",{"prepare"}}, + # cantava -> cant + {"ava",2,"",{"agrava"}}, + # cantemo -> cant + {"emo",2}, + # bebera -> beb + {"era",1,"",{"acelera","espera"}}, + # beber谩 -> beb + {"er谩",1}, + # bebere -> beb + {"ere",1,"",{"espere"}}, + # beb铆ei -> beb + {"铆ei",1}, + # metin -> met + {"in",3}, + # partimo -> part + {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, + # partira -> part + {"ira",3,"",{"fronteira","s谩tira"}}, + {"铆do",3}, + # partir谩 -> part + {"ir谩",3}, + # concretizar -> concret + {"tizar",4,"",{"alfabetizar"}}, + {"izar",3,"",{"organizar"}}, + # saltitar -> salt + {"itar",5,"",{"acreditar","explicitar","estreitar"}}, + # partire -> part + {"ire",3,"",{"adquire"}}, + # compomo -> comp + {"omo",3}, + {"ai",2}, + # barbear -> barb + {"ear",4,"",{"alardear","nuclear"}}, + # cheguei -> cheg + {"uei",3}, + {"u铆a",5,"u"}, + # cantei -> cant + {"ei",3}, + # beber -> beb + {"er",1,"",{"茅ter","pier"}}, + # bebeu -> beb + {"eu",1,"",{"chapeu"}}, + # bebia -> beb + {"ia",1,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, + # partir -> part + {"ir",3}, + # partiu -> part + {"iu",3}, + # fraqueou -> fraqu + {"eou",5}, + # chegou -> cheg + {"ou",3}, + # bebi -> beb + {"i",1}, + # varrede -> varr + {"ede",1,"",{"rede","b铆pede","c茅spede","parede","palm铆pede","vostede","h贸spede","adrede"}}, + # cantei -> cant + {"ei",3}, + # anden -> and + {"en",2}, + # descerade -> desc + {"erade",1}, + # viv茅rade -> viv + {"茅rade",1}, + # beberan -> beb + {"eran",2}, + # colleramo -> coller + {"eramo",1}, + # beb茅ramo -> beb + {"茅ramo",1}, + # perder谩n -> perd + {"er谩n",1}, + # varrer铆a -> varr + {"er铆a",1}, + # beberiade -> beb + {"eriade",1}, + # beber铆ade -> beb + {"er铆ade",1}, + # beberiamo -> beb + {"eriamo",1}, + # beberian -> beb + {"erian",1}, + # beber铆an -> beb + {"er铆an",1}, + # perderon -> perd + {"eron",1}, + # bebese -> beb + {"ese",1}, + # bebesedes -> beb + {"esedes",1}, + # beb茅sedes -> beb + {"茅sedes",1}, + # bebesemo -> beb + {"esemo",1}, + # beb茅semo -> beb + {"茅semo",1}, + # bebesen -> beb + {"esen",1}, + # beb锚ssede -> beb + {"锚ssede",1}, + # chov铆a -> chov + {"铆a",1}, + # faciade -> fac + {"iade",1}, + # fac铆ade -> fac + {"铆ade",1}, + # perdiamo -> perd + {"iamo",1}, + # fux铆an -> fux + {"铆an",1}, + # corriche -> corr + {"iche",1}, + # partide -> part + {"ide",1}, + # escribirade -> escrib + {"irade",3}, + # par铆rade -> par + {"铆rade",3}, + # partiramo -> part + {"iramo",3}, + # fugir谩n -> fug + {"ir谩n",3}, + # vivir铆a -> viv + {"ir铆a",3}, + # partiriade -> part + {"iriade",3}, + # partir铆ade -> part + {"ir铆ade",3}, + # partiriamo -> part + {"iriamo",3}, + # partirian -> part + {"irian",3}, + # partir铆an -> part + {"ir铆an",3}, + # reflectiron -> reflect + {"iron",3}, + # partise -> part + {"ise",3}, + # partisede -> part + {"isede",3}, + # part铆sede -> part + {"铆sede",3}, + # partisemo -> part + {"isemo",3}, + # part铆semo -> part + {"铆semo",3}, + # partisen -> part + {"isen",3}, + # part铆ssede -> part + {"铆ssede",3}, + {"tizar",3,"",{"alfabetizar"}}, + {"ondo",3}}; + +{ "Vowel", 0, 0, {}, + # segue -> seg + {"gue",2,"g",{"azougue","dengue","merengue","nurague","merengue","rengue"}}, + {"que",2,"c",{"alambique","albaricoque","abaroque","alcrique","almadraque","almanaque","arenque","arinque","baduloque","ballestrinque","betoque","bivaque","bloque","bodaque","bosque","breque","buque","cacique","cheque","claque","contradique","coque","croque","dique","duque","enroque","espeque","estoque","estoraque","estraloque","estrinque","milicroque","monicreque","orinque","arinque","palenque","parque","penique","picabeque","pique","psique","raque","remolque","xeque","repenique","roque","sotobosque","tabique","tanque","toque","traque","truque","vivaque","xaque"}}, + {"a",3,"",{"amasadela","cerva"}}, + {"e",3,"",{"marte"}}, + {"o",3,"",{"barro","fado","cabo","libro","cervo"}}, + {"芒",3}, + {"茫",3,"",{"amanh茫","arapu茫","f茫","div茫","manh茫"}}, + {"锚",3}, + {"么",3}, + {"谩",3}, + {"茅",3}, + {"贸",3}, + # munxi -> munx + {"i",3}}; diff --git a/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/stopwords.txt b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/stopwords.txt new file mode 100644 index 00000000000..d8760b12c14 --- /dev/null +++ b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/stopwords.txt @@ -0,0 +1,161 @@ +# galican stopwords +a +a铆nda +al铆 +aquel +aquela +aquelas +aqueles +aquilo +aqu铆 +ao +aos +as +as铆 +谩 +ben +cando +che +co +coa +comigo +con +connosco +contigo +convosco +coas +cos +cun +cuns +cunha +cunhas +da +dalgunha +dalgunhas +dalg煤n +dalg煤ns +das +de +del +dela +delas +deles +desde +deste +do +dos +dun +duns +dunha +dunhas +e +el +ela +elas +eles +en +era +eran +esa +esas +ese +eses +esta +estar +estaba +est谩 +est谩n +este +estes +estiven +estou +eu +茅 +facer +foi +foron +fun +hab铆a +hai +iso +isto +la +las +lle +lles +lo +los +mais +me +meu +meus +min +mi帽a +mi帽as +moi +na +nas +neste +nin +no +non +nos +nosa +nosas +noso +nosos +n贸s +nun +nunha +nuns +nunhas +o +os +ou +贸 +贸s +para +pero +pode +pois +pola +polas +polo +polos +por +que +se +sen贸n +ser +seu +seus +sexa +sido +sobre +s煤a +s煤as +tam茅n +tan +te +ten +te帽en +te帽o +ter +teu +teus +ti +tido +ti帽a +tiven +t煤a +t煤as +un +unha +unhas +uns +vos +vosa +vosas +voso +vosos +v贸s diff --git a/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp b/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp new file mode 100644 index 00000000000..1cca5f5c1d3 --- /dev/null +++ b/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp @@ -0,0 +1,456 @@ +# Steps file for the RSLP stemmer. + +# Step 1: Plural Reduction +{ "Plural", 3, 1, {"s"}, + # bons -> bom + {"ns",1,"m"}, + # bal玫es -> bal茫o + {"玫es",3,"茫o"}, + # capit茫es -> capit茫o + {"茫es",1,"茫o",{"m茫es"}}, + # normais -> normal + {"ais",1,"al",{"cais","mais"}}, + # pap茅is -> papel + {"茅is",2,"el"}, + # am谩veis -> am谩vel + {"eis",2,"el"}, + # len莽贸is -> len莽ol + {"贸is",2,"ol"}, + # barris -> barril + {"is",2,"il",{"l谩pis","cais","mais","cr煤cis","biqu铆nis","pois","depois","dois","leis"}}, + # males -> mal + {"les",3,"l"}, + # mares -> mar + {"res",3,"r", {"谩rvores"}}, + # casas -> casa + {"s",2,"",{"ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","fezes","p锚sames","cr煤cis","g谩s","atr谩s","mois茅s","atrav茅s","conv茅s","锚s","pa铆s","ap贸s","ambas","ambos","messias", "depois"}}}; + +# Step 2: Adverb Reduction +{ "Adverb", 0, 0, {}, + # felizmente -> feliz + {"mente",4,"",{"experimente"}}}; + +# Step 3: Feminine Reduction +{ "Feminine", 3, 1, {"a","茫"}, + # chefona -> chef茫o + {"ona",3,"茫o",{"abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","carona"}}, + # vil茫 -> vil茫o + {"茫",2,"茫o",{"amanh茫","arapu茫","f茫","div茫"}}, + # professora -> professor + {"ora",3,"or"}, + # americana -> americano + {"na",4,"no",{"carona","abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","guiana","campana","grana","caravana","banana","paisana"}}, + # sozinha -> sozinho + {"inha",3,"inho",{"rainha","linha","minha"}}, + # inglesa -> ingl锚s + {"esa",3,"锚s",{"mesa","obesa","princesa","turquesa","ilesa","pesa","presa"}}, + # famosa -> famoso + {"osa",3,"oso",{"mucosa","prosa"}}, + # man铆aca -> man铆aco + {"铆aca",3,"铆aco"}, + # pr谩tica -> pr谩tico + {"ica",3,"ico",{"dica"}}, + # cansada -> cansado + {"ada",2,"ado",{"pitada"}}, + # mantida -> mantido + {"ida",3,"ido",{"vida","d煤vida"}}, + {"铆da",3,"ido",{"reca铆da","sa铆da"}}, + # prima -> primo + {"ima",3,"imo",{"v铆tima"}}, + # passiva -> passivo + {"iva",3,"ivo",{"saliva","oliva"}}, + # primeira -> primeiro + {"eira",3,"eiro",{"beira","cadeira","frigideira","bandeira","feira","capoeira","barreira","fronteira","besteira","poeira"}}}; + +# Step 4: Augmentative/Diminutive Reduction +{ "Augmentative", 0, 1, {}, + # cansad铆ssimo -> cansad + {"d铆ssimo",5}, + # amabil铆ssimo -> ama + {"abil铆ssimo",5}, + # fort铆ssimo -> fort + {"铆ssimo",3}, + {"茅simo",3}, + # chiqu茅rrimo -> chiqu + {"茅rrimo",4}, + # pezinho -> pe + {"zinho",2}, + # maluquinho -> maluc + {"quinho",4,"c"}, + # amiguinho -> amig + {"uinho",4}, + # cansadinho -> cansad + {"adinho",3}, + # carrinho -> carr + {"inho",3,"",{"caminho","cominho"}}, + # grandalh茫o -> grand + {"alh茫o",4}, + # dentu莽a -> dent + {"u莽a",4}, + # rica莽o -> ric + {"a莽o",4,"",{"antebra莽o"}}, + {"a莽a",4}, + # casad茫o -> cans + {"ad茫o",4}, + {"id茫o",4}, + # corp谩zio -> corp + {"谩zio",3,"",{"top谩zio"}}, + # pratarraz -> prat + {"arraz",4}, + {"zarr茫o",3}, + {"arr茫o",4}, + # bocarra -> boc + {"arra",3}, + # calorz茫o -> calor + {"z茫o",2,"",{"coaliz茫o"}}, + # menin茫o -> menin + {"茫o",3,"",{"camar茫o","chimarr茫o","can莽茫o","cora莽茫o","embri茫o","grot茫o","glut茫o","fic莽茫o","fog茫o","fei莽茫o","furac茫o","gam茫o","lampi茫o","le茫o","macac茫o","na莽茫o","贸rf茫o","org茫o","patr茫o","port茫o","quinh茫o","rinc茫o","tra莽茫o","falc茫o","espi茫o","mam茫o","foli茫o","cord茫o","aptid茫o","campe茫o","colch茫o","lim茫o","leil茫o","mel茫o","bar茫o","milh茫o","bilh茫o","fus茫o","crist茫o","ilus茫o","capit茫o","esta莽茫o","sen茫o"}}}; + +# Step 5: Noun Suffix Reduction +{ "Noun", 0, 0, {}, + # existencialista -> exist + {"encialista",4}, + # minimalista -> minim + {"alista",5}, + # contagem -> cont + {"agem",3,"",{"coragem","chantagem","vantagem","carruagem"}}, + # gerenciamento -> gerenc + {"iamento",4}, + # monitoramento -> monitor + {"amento",3,"",{"firmamento","fundamento","departamento"}}, + # nascimento -> nasc + {"imento",3}, + {"mento",6,"",{"firmamento","elemento","complemento","instrumento","departamento"}}, + # comercializado -> comerci + {"alizado",4}, + # traumatizado -> traum + {"atizado",4}, + {"tizado",4,"",{"alfabetizado"}}, + # alfabetizado -> alfabet + {"izado",5,"",{"organizado","pulverizado"}}, + # associativo -> associ + {"ativo",4,"",{"pejorativo","relativo"}}, + # contraceptivo -> contracep + {"tivo",4,"",{"relativo"}}, + # esportivo -> esport + {"ivo",4,"",{"passivo","possessivo","pejorativo","positivo"}}, + # abalado -> abal + {"ado",2,"",{"grado"}}, + # impedido -> imped + {"ido",3,"",{"c芒ndido","consolido","r谩pido","decido","t铆mido","duvido","marido"}}, + # ralador -> ral + {"ador",3}, + # entendedor -> entend + {"edor",3}, + # cumpridor -> cumpr + {"idor",4,"",{"ouvidor"}}, + {"dor",4,"",{"ouvidor"}}, + {"sor",4,"",{"assessor"}}, + {"atoria",5}, + {"tor",3,"",{"benfeitor","leitor","editor","pastor","produtor","promotor","consultor"}}, + {"or",2,"",{"motor","melhor","redor","rigor","sensor","tambor","tumor","assessor","benfeitor","pastor","terior","favor","autor"}}, + # comparabilidade -> compar + {"abilidade",5}, + # abolicionista -> abol + {"icionista",4}, + # intervencionista -> interven + {"cionista",5}, + {"ionista",5}, + {"ionar",5}, + # profissional -> profiss + {"ional",4}, + # refer锚ncia -> refer + {"锚ncia",3}, + # repugn芒ncia -> repugn + {"芒ncia",4,"",{"ambul芒ncia"}}, + # abatedouro -> abat + {"edouro",3}, + # fofoqueiro -> fofoc + {"queiro",3,"c"}, + {"adeiro",4,"",{"desfiladeiro"}}, + # brasileiro -> brasil + {"eiro",3,"",{"desfiladeiro","pioneiro","mosteiro"}}, + {"uoso",3}, + # gostoso -> gost + {"oso",3,"",{"precioso"}}, + # comercializa莽 -> comerci + {"aliza莽",5}, + {"atiza莽",5}, + {"tiza莽",5}, + {"iza莽",5,"",{"organiza莽"}}, + # alega莽 -> aleg + {"a莽",3,"",{"equa莽","rela莽"}}, + # aboli莽 -> abol + {"i莽",3,"",{"elei莽"}}, + # anedot谩rio -> anedot + {"谩rio",3,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","lion谩rio","arm谩rio"}}, + {"at贸rio",3}, + {"rio",5,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","compuls贸rio","lion谩rio","pr贸prio","st茅rio","arm谩rio"}}, + # minist茅rio -> minist + {"茅rio",6}, + # chin锚s -> chin + {"锚s",4}, + # beleza -> bel + {"eza",3}, + # rigidez -> rigid + {"ez",4}, + # parentesco -> parent + {"esco",4}, + # ocupante -> ocup + {"ante",2,"",{"gigante","elefante","adiante","possante","instante","restaurante"}}, + # bomb谩stico -> bomb + {"谩stico",4,"",{"eclesi谩stico"}}, + {"al铆stico",3}, + {"谩utico",4}, + {"锚utico",4}, + {"tico",3,"",{"pol铆tico","eclesi谩stico","diagnostico","pr谩tico","dom茅stico","diagn贸stico","id锚ntico","alop谩tico","art铆stico","aut锚ntico","ecl茅tico","cr铆tico","critico"}}, + # pol锚mico -> pol锚m + {"ico",4,"",{"tico","p煤blico","explico"}}, + # produtividade -> produt + {"ividade",5}, + # profundidade -> profund + {"idade",4,"",{"autoridade","comunidade"}}, + # aposentadoria -> aposentad + {"oria",4,"",{"categoria"}}, + # existencial -> exist + {"encial",5}, + # artista -> art + {"ista",4}, + {"auta",5}, + # maluquice -> maluc + {"quice",4,"c"}, + # chatice -> chat + {"ice",4,"",{"c煤mplice"}}, + # demon铆aco -> demon + {"铆aco",3}, + # decorrente -> decorr + {"ente",4,"",{"freq眉ente","alimente","acrescente","permanente","oriente","aparente"}}, + {"ense",5}, + # criminal -> crim + {"inal",3}, + # americano -> americ + {"ano",4}, + # am谩vel -> am + {"谩vel",2,"",{"af谩vel","razo谩vel","pot谩vel","vulner谩vel"}}, + # combust铆vel -> combust + {"铆vel",3,"",{"poss铆vel"}}, + {"vel",5,"",{"poss铆vel","vulner谩vel","sol煤vel"}}, + {"bil",3,"vel"}, + # cobertura -> cobert + {"ura",4,"",{"imatura","acupuntura","costura"}}, + {"ural",4}, + # consensual -> consens + {"ual",3,"",{"bissexual","virtual","visual","pontual"}}, + # mundial -> mund + {"ial",3}, + # experimental -> experiment + {"al",4,"",{"afinal","animal","estatal","bissexual","desleal","fiscal","formal","pessoal","liberal","postal","virtual","visual","pontual","sideral","sucursal"}}, + {"alismo",4}, + {"ivismo",4}, + {"ismo",3,"",{"cinismo"}}}; + +# Step 6: Verb Suffix Reduction +{ "Verb", 0, 0, {}, + # cantar铆amo -> cant + {"ar铆amo",2}, + # cant谩ssemo -> cant + {"谩ssemo",2}, + # beber铆amo -> beb + {"er铆amo",2}, + # beb锚ssemo -> beb + {"锚ssemo",2}, + # partir铆amo -> part + {"ir铆amo",3}, + # part铆ssemo -> part + {"铆ssemo",3}, + # cant谩ramo -> cant + {"谩ramo",2}, + # cant谩rei -> cant + {"谩rei",2}, + # cantaremo -> cant + {"aremo",2}, + # cantariam -> cant + {"ariam",2}, + # cantar铆ei -> cant + {"ar铆ei",2}, + # cant谩ssei -> cant + {"谩ssei",2}, + # cantassem -> cant + {"assem",2}, + # cant谩vamo -> cant + {"谩vamo",2}, + # beb锚ramo -> beb + {"锚ramo",3}, + # beberemo -> beb + {"eremo",3}, + # beberiam -> beb + {"eriam",3}, + # beber铆ei -> beb + {"er铆ei",3}, + # beb锚ssei -> beb + {"锚ssei",3}, + # bebessem -> beb + {"essem",3}, + # partir铆amo -> part + {"铆ramo",3}, + # partiremo -> part + {"iremo",3}, + # partiriam -> part + {"iriam",3}, + # partir铆ei -> part + {"ir铆ei",3}, + # part铆ssei -> part + {"铆ssei",3}, + # partissem -> part + {"issem",3}, + # cantando -> cant + {"ando",2}, + # bebendo -> beb + {"endo",3}, + # partindo -> part + {"indo",3}, + # propondo -> prop + {"ondo",3}, + # cantaram -> cant + {"aram",2}, + {"ar茫o",2}, + # cantarde -> cant + {"arde",2}, + # cantarei -> cant + {"arei",2}, + # cantarem -> cant + {"arem",2}, + # cantaria -> cant + {"aria",2}, + # cantarmo -> cant + {"armo",2}, + # cantasse -> cant + {"asse",2}, + # cantaste -> cant + {"aste",2}, + # cantavam -> cant + {"avam",2,"",{"agravam"}}, + # cant谩vei -> cant + {"谩vei",2}, + # beberam -> beb + {"eram",3}, + {"er茫o",3}, + # beberde -> beb + {"erde",3}, + # beberei -> beb + {"erei",3}, + # beb锚rei -> beb + {"锚rei",3}, + # beberem -> beb + {"erem",3}, + # beberia -> beb + {"eria",3}, + # bebermo -> beb + {"ermo",3}, + # bebesse -> beb + {"esse",3}, + # bebeste -> beb + {"este",3,"",{"faroeste","agreste"}}, + # beb铆amo -> beb + {"铆amo",3}, + # partiram -> part + {"iram",3}, + # conclu铆ram -> conclu + {"铆ram",3}, + {"ir茫o",2}, + # partirde -> part + {"irde",2}, + # part铆rei -> part + {"irei",3,"",{"admirei"}}, + # partirem -> part + {"irem",3,"",{"adquirem"}}, + # partiria -> part + {"iria",3}, + # partirmo -> part + {"irmo",3}, + # partisse -> part + {"isse",3}, + # partiste -> part + {"iste",4}, + {"iava",4,"",{"ampliava"}}, + # cantamo -> cant + {"amo",2}, + {"iona",3}, + # cantara -> cant + {"ara",2,"",{"arara","prepara"}}, + # cantar谩 -> cant + {"ar谩",2,"",{"alvar谩"}}, + # cantare -> cant + {"are",2,"",{"prepare"}}, + # cantava -> cant + {"ava",2,"",{"agrava"}}, + # cantemo -> cant + {"emo",2}, + # bebera -> beb + {"era",3,"",{"acelera","espera"}}, + # beber谩 -> beb + {"er谩",3}, + # bebere -> beb + {"ere",3,"",{"espere"}}, + # bebiam -> beb + {"iam",3,"",{"enfiam","ampliam","elogiam","ensaiam"}}, + # beb铆ei -> beb + {"铆ei",3}, + # partimo -> part + {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, + # partira -> part + {"ira",3,"",{"fronteira","s谩tira"}}, + {"铆do",3}, + # partir谩 -> part + {"ir谩",3}, + {"tizar",4,"",{"alfabetizar"}}, + {"izar",5,"",{"organizar"}}, + {"itar",5,"",{"acreditar","explicitar","estreitar"}}, + # partire -> part + {"ire",3,"",{"adquire"}}, + # compomo -> comp + {"omo",3}, + # cantai -> cant + {"ai",2}, + # cantam -> cant + {"am",2}, + # barbear -> barb + {"ear",4,"",{"alardear","nuclear"}}, + # cantar -> cant + {"ar",2,"",{"azar","bazaar","patamar"}}, + # cheguei -> cheg + {"uei",3}, + {"u铆a",5,"u"}, + # cantei -> cant + {"ei",3}, + {"guem",3,"g"}, + # cantem -> cant + {"em",2,"",{"alem","virgem"}}, + # beber -> beb + {"er",2,"",{"茅ter","pier"}}, + # bebeu -> beb + {"eu",3,"",{"chapeu"}}, + # bebia -> beb + {"ia",3,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, + # partir -> part + {"ir",3,"",{"freir"}}, + # partiu -> part + {"iu",3}, + {"eou",5}, + # chegou -> cheg + {"ou",3}, + # bebi -> beb + {"i",3}}; + +# Step 7: Vowel Removal +{ "Vowel", 0, 0, {}, + {"bil",2,"vel"}, + {"gue",2,"g",{"gangue","jegue"}}, + {"谩",3}, + {"锚",3,"",{"beb锚"}}, + # menina -> menin + {"a",3,"",{"谩sia"}}, + # grande -> grand + {"e",3}, + # menino -> menin + {"o",3,"",{"茫o"}}}; diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianAnalyzer.java b/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianAnalyzer.java new file mode 100644 index 00000000000..b67bf087713 --- /dev/null +++ b/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianAnalyzer.java @@ -0,0 +1,53 @@ +package org.apache.lucene.analysis.gl; + +/** + * 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.HashSet; +import java.util.Set; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.BaseTokenStreamTestCase; + +public class TestGalicianAnalyzer extends BaseTokenStreamTestCase { + /** This test fails with NPE when the + * stopwords file is missing in classpath */ + public void testResourcesAvailable() { + new GalicianAnalyzer(TEST_VERSION_CURRENT); + } + + /** test stopwords and stemming */ + public void testBasics() throws IOException { + Analyzer a = new GalicianAnalyzer(TEST_VERSION_CURRENT); + // stemming + checkOneTermReuse(a, "correspondente", "correspond"); + checkOneTermReuse(a, "corresponder谩", "correspond"); + // stopword + assertAnalyzesTo(a, "e", new String[] {}); + } + + /** test use of exclusion set */ + public void testExclude() throws IOException { + Set exclusionSet = new HashSet(); + exclusionSet.add("correspondente"); + Analyzer a = new GalicianAnalyzer(TEST_VERSION_CURRENT, + GalicianAnalyzer.getDefaultStopSet(), exclusionSet); + checkOneTermReuse(a, "correspondente", "correspondente"); + checkOneTermReuse(a, "corresponder谩", "correspond"); + } +} diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilter.java b/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilter.java new file mode 100644 index 00000000000..85f0efbdf1d --- /dev/null +++ b/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilter.java @@ -0,0 +1,52 @@ +package org.apache.lucene.analysis.gl; + +/** + * 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 static org.apache.lucene.analysis.util.VocabularyAssert.assertVocabulary; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.BaseTokenStreamTestCase; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.core.LowerCaseFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; +import org.apache.lucene.analysis.util.ReusableAnalyzerBase; + +/** + * Simple tests for {@link GalicianStemFilter} + */ +public class TestGalicianStemFilter extends BaseTokenStreamTestCase { + private Analyzer analyzer = new ReusableAnalyzerBase() { + @Override + protected TokenStreamComponents createComponents(String fieldName, + Reader reader) { + Tokenizer source = new StandardTokenizer(TEST_VERSION_CURRENT, reader); + TokenStream result = new LowerCaseFilter(TEST_VERSION_CURRENT, source); + return new TokenStreamComponents(source, new GalicianStemFilter(result)); + } + }; + + + /** Test against a vocabulary from the reference impl */ + public void testVocabulary() throws IOException { + assertVocabulary(analyzer, getDataFile("gltestdata.zip"), "gl.txt"); + } +} diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/gltestdata.zip b/modules/analysis/common/src/test/org/apache/lucene/analysis/gl/gltestdata.zip new file mode 100644 index 0000000000000000000000000000000000000000..d6840d98ad055749f7f78a12d6776af1c6a27659 GIT binary patch literal 40515 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�Q8l86ZvbT>rzO@`nB9elnm#)z!$n17DO&Zy? zh&JkA?Gb&km$S>zk<_x#u(5%y%vT6Tw1dm7q*;MD79hsy-gW*u& z#;ItSnXW;5aR?M4HHxN&Ip3l$5)JcK>=SPOkj}h8-OAzzP8~i7lA-?-)`_nE4`+IF z-=6PoU^?X{xQ<@_q(ljLpJg!6m6;Nse4~ zPuNP7cjP;}$geCTzF%VHtXtr-epZEquEdtV{-!g(^~d)9iC<(ye5=Iwj6zUw&C%X_ z@)alFcn(gqco+pd+PY!k6H7F|zlalG)nFHY{7jsZA^=DIfz65Vb1!epLF`p|oOoi| z!9WpGqiknQ*GIf>j2oNuh+|Xus|MV;&1FTri_AY5Dhj`TUnV`}rLa`#cw=;8HF2)k z^hq^#Og-bP>@Qy&Vg%~aeLLygY}TRq(x57>ZKxKI`MD%FG(2x7^+RboO+61g+FHj6 zBnmS36&71Ov;-sX!nPJK@?gSzi3zDw{99y5Y#%qQkqrw=j^QdYJbRH7c9ocgVwN)? z&QlTQ8+Yv&0LM3Z`4^Bo2cJ3pC4wA7uSas3&o&rJjc!?X73$ zSeHT5YK4MLj@@OfZae;CL7Pk}LZ)~k#1Xb*!!O~lp{TzYW@4(S5fz1zz%#knObhgu z`J!57lMqThhSA(-!8+N*CWXeDQ9zo zKoml;%k_{ltd6lbbL)Qm3Z7b$Dh>_2Omc+D5*?yc?NWD93LR;z%Gap6DMNxUf`X+0 zxA%f!TS{f%`#Rx-MeP`6I24PUw$r#BwPD;rd-uHlx$C>B;m&WQa{Wg-UdVnPtng4n zz5cMT^!jtMPo97;njyqqmBvz~IVAqI&I;}yYXD=N;=z_rf^D`abfe2<^_g5SbZvcT z^7``}xv@%kqV3DA*_~hR;DgTm;FsZuuZpsHI_mQxA=`D$00idTY#zBCEIuE)FrOF- z1w?r|!x65u6T2^VME9kf+1)Bw#U>l4sd8A+kq)t-H##Ei+5hF}yJDH?ubQ^raMgwG=%pCv(qarzb+C}K-6{yL!i!VH^TI$8$ zw~*{^BO%qF!F)n~1sGu>!!J!!k*iVzG|Yaq($%m4`n$ z#`Y?Xmx?Z-;OaKo5oQIOni>~rl(p#CSRwi7vNZ>{Oj@Sj`!tHkbY7afaepYFKNw%^( z;K(IAC)pT}N+w3Rfa%QLC>R;M{=v-K>X#y;p~H<$I}AWjtep)aZ20t#zf(u#uAv@1 zjTSn(?0D>%KbGMl?=BjuE0?NLu41lgu2Rk_f?l1;jtY*?{==oz#;7KIaA=?i^*I|= zflNkO*Y-TM0;eJkLE#t5FrA#3?fIdwDQEX|uce)+bZLdKcM|v9quxoi2z#fB*hWeF zkggVKh8sB)xfRo19owi-wyxg$`vSX$uM2>&nS@NItH-ht=pmNe&84z1o%o{=7qQV& z5fup-8p;R_RpG`hRLLO6U6ipLvK(Xp8e9*>@piVNf_0_hv1bY?VV1sl7?n(?spX3b zGJx@MN8_Fk_`I_r#bVt1q!==2qAG{Rm8ya&B(qOWQ_q!!giH#tcM{Z!6eW5g|6(ii zH7%2unJ;DvD6wOfQw=tv7xA5qWhldq8mc-`j*4(4Pbh0mMO;%PRYA{Vd|S#Tc*P)N z=xJ!^>jzt?l*ha3Wg9`JcDw|D80`uP4Ou#-)SWE%Pu{Lf)~rlr8*DiWObpDw;#ct0 zlcixQA|GpiI)&%%v{ zSw4f3n1Q%XS;iKUxmY(!w~}v&p@rpYH_NC9tZ!N+ww&kr8py&8(-1Ibl7-&g6jwJp zuVOExy%OGpy%RnEPT4z(JKou+soXggA?$hMfOZ7us3VOIB1}m1F@6TqmZ>VCRif;p zk)>lQjzT7-*1_12WPw@yxsmTw_4D}_Y+^;jh*vmOx%3WHC@WWJgd}Zabr3KyRs00& z)$}Ioc01{Vv#^&~Xp3UC8|y`XbYW)0g_&^K_|_euFkOauAy?vFNZl2qStI4{rFV2^ z_u+1FeOGLgDoeV8T?o|C1B4QiSIvYj@$rhXF^Aj%Uw>dL%gR#`;PR+N#1~c-kq44r z426nPf$~181&C@PBiq2JQ=2==n^m4zts0NE)45=yq&F#a%FRwc62XK9cKWLs6vQft`n;6cYO(GUIP**kN0h$&CA5*%Rc|8;k;SBA3W-f&GFH0z!Ac!9 zOFwbK{5p9MWfO{CL~V6yGIl!!oP*j4*w!Io{X*M z+b8#Gy+6r~H&e0rF0LhElL{NnJEKJ^$(r)O;o7u~rpOLEUCJ%@p@sRt#?w#EOBDtS z9YZ2uT#bG*Q4L7qe(uz`r8`Y^eF=)7Cbrk&yHZ{0k+u8x&Y3b*G#b=0VX$B*~W09h^vAwV!Iit;&9BWwLsN`C&R>BQBrRnobR;wPm$2It?u? zMRQDbag@`lUxtrjDaJb+%aZTv{t`|j1FzGqy?Lfp_nWuk*h^2(8ROHqUF0;D=Tz3XqJU_l)F-;k% z6Vgsu-rU4JSD_LtB6~`$v*M}>yWs2`?5!sc$Rq))j0MP%!F9@QWwc0ZY52?DaKa{8 zHPZ;O;q$2bz!b;8HXIC6nwCp#>kE_Bw+bdcG;yw|5QK<@dMc(wRl4*djz%`^uK8U_ z@m(2;tBf02w-#|(lC#jWt@C@dsUIK{yrzX+k$eu1s?FhL{PfHsND=8XE87WE4U-hr zaQBFUh~p!IX|`;;@`XoQ%kT@ZC}FR}9oI>_ zPC7O1<AF zEtY^3sf2?Q`}{(wz2m0tnF=wE-qqb7%ERhUstv4t%ZE)dq=#5s%}+r3`udHt7{=N- z@Zd>4s!)}@x$ATnK-r&Pg>ITc7pl@p^G}6U8*ef8S6n`Mqnz}nhL7SWr*rjnXaeym z0Lw>jEh^sCPj`!-G{w5J#-h_xW5HH#=g)^wjBihot4JIFc{o#JllFe-KETt%KJ_?| zj5Z~^`g)oIDXJ5}0=K??9>FhTg}mwrCP~a`8>@;r7?1Eh1kKHSqkaA6+~9YvnkK}T_Fv4#5xbM1wt+#y%!^6eiLZTx zP|0(i7Vy%O)Uwbr^iyd%O&wnvr?JID=vXpuq6uSnVX;jnATJhcvn6R^;|019hB*q= z6KgRY1I)#Al6YC}MoeG6JuhJ+luFN(#!5l0tg%YHKYo4Xor9?oBwM*5L!N)}>FLE3 zEWT^R^g)g9T7NN?R?`qshO3-uZVU(9&Ib!v5&X84t^?$mi{L_R!*{2lz+ldO z$C?YhoXd=^QO}8dgE7rM2`5yQ^d<#YkjV3R<3*Upo@TtWQHsy#Ru>`dmGMv@L_IyT z(7gHTi43)Lf`d7X<4`Gj)ZRu}O^a7E#H%!X=_Vm_*db=hM=FG?6c*c-dRA$)u%l7j zX=<$VJr6XD#D+b2D@H@)i>^whj$DQvO+61g+FQq-CA$$B~Qm=51MxY4GUK!sN&#cBKx0vcWvno_eRb5V~Zj-dv*FG&Y!e$tDS|dm}_aV4DasyP>h_Q4r7LM;D-?e zqUEcBUQ31F(2YaZHB_b4Ym2Ri(Q9%1UUe0QTcWAs=ILUWb4Ptgl5!#qreQRIyv2k< zLn{ypNQQDrX1KXrO9)*qz7wLOY@q1jRa($mqykgH(a@&10ogPX3W4JdfPE-~%&%N_ zLXuj>{((Rdrt~JoDc!=MWwHvbU!nSps-DFwOj-;bhbwbu#N0hzXan8^SL`h=1c7H* zTKa=!Ef3MPkVL#3jtL~n;0ZuTcKDIQtetrH2Td~j@XBB#rAA{bfHj9(4m)yyz60Qr zfBOQ!a58&tlzo8d#L6X!Ye=$I@W(L;DTV|spW8UIXff8}YL0c1ccAT7`%IAUz-5#?=n(H7iC7FQR|8T_!_rsw14Ay!m zw3)MM$p!iKSNRU;#F2)woLDkC9>(K%4u|{?bK&7>N?lP?apOjK{einTCA=%CNWL2^ zKO!AD+mH@4!7w5g2RdRw?cnZn#^(ZB^eYV%A?+1q;hh*H9BqAWOH#`=B$QAU(q0K~ z!rlodY8)4_(NYm}UhS_fu1v_aMawY-T{w#Mh?`G1w^e)^$i==}J8fh#DuNlAh@tr~ z&PPno<$svf z@;hXsr@i1Y-)g8YdnLBqW}&OXnFE-a1RR@0Ba`hi9q^lBu86QX+)$(Y^%rk3%>FiD zCX@yUK6*y96JywJQf(pi&mNbUZXPcYPB%00g|a1&>bn zAV4lyxvQkJNS|y}D;h2$<{EaQui!G732={E1S{l1+;hJL&u&MeT@4?_4^CCpRYHq6+-)QK!laiKVl9)^wYtB$5_`Ul9bfz@BOjZS8A@7` zkT@g~=-2SpWo&Nc88xuN4eJ(yKcFu#GEQQL75OHZcJ@3Arg8$~8y4FZ5lo ziA}+fx#44H%gAx27GYtFuzZcDa$jMJ@g^bOj9Oo{lfJ{jkx3MQd3Z8RdKaS8NRFN6 z$?-T>d3+U|4m6A~r!|xna3gFDn{Y6s+-F!M?($PeBd5-(C3yx$W6Q>+Wv#%~uoy3TR_wo$eA7N?zCx>krZdcYJ*%Z@NWNBEgn@^Bc3LEwpVI0}*RZW6rSL(>qk&f7I z@NI9I8WIXtUA3xGTJ>FG$HyI2EVoMBb2WFBREtJ0;<&rvw7-EmOs%3$pDZP*Fo$wu zs{?fF7?q%0XKTV`FT|aIkHlx!#@kVozZPv?Vk;?DVW{X-@vIwWlQb?&dT#SNqNr|P)Fx5;>*)J3*!t$oXcg4MF#Ie6{thX5lZ5UK>E2lU8 zYEG|CFYc%+VXwqJS0)g2v1le}tG0?w-t1X$qyxR3-hQdZj?%!$;8 z-S9z**D>d26WF4aePBm#dUc}>TddwZ0>q%>1<#n;a;o+Var(f3m(#`-L!MM6KZF%y z1V=6xXOeMckF6f(>lRyMZj!EPgl*3k^99hvT1d6{M@9635t#y{R_yWmAw%iTmppmS zwl}L1g7g1uRvQ1ak<8OcWyWwLhIetQ+C=d#;ZCB>vJM4SF}O(SG0duNg`r{X7UwY_ zp{YjMjKh(i;Gp_LZx^q#M)Y<;SY9JC9vNauK*H8oZf?2BvP7%-V=9WOt_g`7Tp<>P zs}@=fEd#2+43^Q`5E5#s*lvz;UK@wvCOgRY#_%c)M~#;R_zDcB6Cd4@9r1-n?txpK zOM*HVU+D~A%+7))MR7895CM#`g=%>0nAW`%Of^@gI4H`XN%zruGR~x9CC$N+q&u@4 zkp%V$3CNRdlabUgn{WaWw=2o8!kmVP9lBnWX~6A& zp3gCF7^c;@!smRhPG@0EK+6~{46djHu<~v}Jpco_7*usMuYnguzp$y3;u<@Yx)6Fn zJBgU3v?tyUIHH8%D-|Xg_sUf+3(*ud3mY(&dcz0M7cDt5WK zS-BO9b-7dSm`-+Y_EDw8J;&&TB4!d;mpQAt zBD7KGGd;|vQ@^q(c8&2{P-)s&Of5VHQ^nRK07?iQNtI!eiC;6I*a05dvL#ezTHV%Q zj5`x&kdvL_+f%DBT}yWDSFS*=xs$<1aUwm}ELH`GG-~KXA6Eg9$8S}9KqiD8O+7Dj z)Vf-;)ae?0+t-REqmu&@EcaR_x&VN%@dPRWGQNv4hLvyl6z|-7Z zr{Z5oXs?MC+xIN9T{;=dcDF$j&j3c5i3(M3$q=OJI#|*PLJOrby#*IKra@NWR?QMf z2v&37*aj^_?k0R&@7mZAhq2}VBfl(R?87AG0+2-ILV@$!s`u`k+^(v61}3v_kg-lZ z5voFJmAJ}56vaDjnNCy7IiR3vG)&0^#(}`QvcF34=*sAY?#_54pLf*9Uq-9`?Nd2L zXziGh-YmQX*Bcm{jDFQOqvDOOdf1rsHF|j0DCPC@#TPE^)zZ=jF?`Z`hbo76W$(NC zS@$s-Iqm7v@#VX>k1boqXSp6nW)g(f#airF7nU85J!e5GJZ%;c@So3(F zz%l=0?Y^dhq{NM}B$6*AB_j#o^N6 zRPn4@NvKNR8Z>lgnf}do`QV*mXs^aknkq17)gpZerjq$xOrO*bA+W|{r>X+(#c!8P zc>O->t!{b3)Y$C9s(Tx(k^fb?PAi8sQhM$&CqCQB+Z9V@7Ugtc{=GG~uqM_>6OLHX zI5oItlNfDZX(x>ucH&wFN+MF(;anXrEitD?e}=~HM_CoSL+Rs4x6*SHuAAk~bu;1h zqXk(cQ|i_9Q4XD2JRj-FC|HZoSWD0-59Ne&uBNNO7haS%RRj4XY0oWA8cBV9gC=@@ zuFm`oSn_GqWHX{gWYmo%>i8;)AI6KEdg@JNRW7{)rFWsT*($$fGq%=aM>>CP;3PyT zdZuJ;idW%V%RF3sPoMbZobLT7R1O}B27OxBxv)D{>K7;gkCI{)Y!#{ZsB;^#87*d_ z$W>1s*>7CSvzYAwEZK? znY?Y=E-qMssY2Y*&|eV5CZ}o7L+_t2BPqT?ua%uIHXME9Y||ENfrh0h-cSr`K3@Oi zUaSfb`m;A_OZ7O_YX0>H!xLssjawdrRUZTt^fo}i1m*vSbLREJYRKW#!u}W%hYbgZ zS<{C-KC~J&u38W1wISE7LpIOZ%+14^`;DFnR?gw%Tjn7m$Ky!E4DQ2$hRA4aBu#Rq z6SHWDY#bC2xiIg!-PT2xhzGJNAiB&nMOk)>Wo$8GRe-`+?GTxcnJWf!d2GIhwU1%P z$LnWRlJkDal;r+B59nV%?S#Gq&`OSAH^iQ*DpSsfCQQtwPkdymSL6A|7MBsZfQL8a z5+k5<6!#o?yj8}f=UUL>u!`YLv~?~Xx<*Z7k&DW$8%r>YY{Oa$9EY{fGZy925E&I{ z=XXEwt&m2ZKdTZn3c2X-@D0wO>$=Vt;@cREQS3Vw$wz9(QLsTWM~*!S~hm1x6;6?752`RtBZiC z%a#p2?Y-Aze&rlN8NJu_^}wds{kh*yRZ=g-?h@U@d7S*2fLkf`nm+L=swM}j&GIjL zeA79{@YFof^R5`V8?>;o0%*Qz5$UwF6JyUO3lX7dtO$#nU^8ZfQc}4Yb5{K>R(Nf- z)QPYEDyjG#YBsbE^{Mrwq84?n5_W>ut*y4~`P)@-&(+rYf>#5I*y>D9ob2wRdPk^A z>0R4}#Ura%cF)~jgYz6L_5EvFM4}b#mFt!36kio+xiF4b&e71Y+ZQEHSl##Jigu$c z8bx3aM!nZ(`Dm7Km2xfZqCSr`Q;A)qI4}a&Xk=@M_H`~kn;<)!|H&`p50&n0JWG7G z4*zbG-mLC1b0eZx}l&OC`T~h)*pmWC%%Y2Na#sz zvbdwnQxf1Gl6e^&ToIB5X^Agll}muCkgB2=@o=bckV(2MK@OHhocV*p zmM`v|^u;8N%4mcaRRuh6*=TCHECI*KuNfz1U6`adU2@b*dJ(*>&ju&3U>?6LlB3X4 zp@KXc8I_p!joFtb#@($lBC}yq5#W;~f@El&Sa!0J$%EAZcE#c^M<_d<4i2S_XLG_l zM^l-wl~VELnb9+we3PnbFb~Df3?R0#_{zSG`ImPdag$N+Qk<}uWP^CDaGD)oZ0ACv z%2N?ok>X|Dm*zMN=E>KEwXku-G!mI7W+9kl-^Aa*_#T4Bk;k?icw~y7pyK592cL$4 z;scK(wy5HhVna%7PsQt^Aa5kRIpVSwuKyPaEm1guAZW4%fD98P(ni$TIP!fr-iUJn z8%hH)4ol6yGa(aZ8iD7cChiX)kolDnf$U9~4CgvWJ*O|!ITIG5;g>KpFcrK;O+gW2 z2I_0V)eFp_0K~FEh7{9f{B7}sLL*>;D&EG0mM63d&ys}>Ln6>SVJOi*pj4}shAe__2+{vq&`5W7?hk5(}yjc{~S ztj9PsklvvjaL$@L=Wte1$4>6 zj9pA%5O1T!mM}CFP<9gmlVi4~AwOJTEsOP>gck9Ir;0~*-kgO7R!6#a6-8I&5 zwS1dpz0FQ*V5@f7JMt%Jl&}+)Hzn@5x?`0Ti*X+Swe7tW-W)Z)6~BsR!j7WTTzMXI zv|&<+f+xRj7#8B>>dNl{fePa;?ht>GGn zFZK!zXORs;$XCRH>&#^uMd&LJB!E}CyAp;}Np1)ZG>p*3aMJa~ZmW!okq!i)2znIY z{dsr1qoN_Q%{HtkB-Wmlb5+7ajR5J) z`=Z}Ul3ErzQmv*zN4yh}KSiD(_A2j-ue$RuCu(74!d3R!5TuvH3NYY?&d))nQRHIh zuYaECC&%H5s$Nv_Z36ElkR0JTCZQyVw;SjwZ~1XH$0rKM1li zj#k2(PJqJZgQ22W@1kMFiXHl$a~1qnWXx@TnFiZNFTDFjuqUA-sbS5YWQ8|2{F1ey zjn$MsUNL`EKl>g(spCht;iLE#gxEY9D?|YbW3{t;5Ob$b16kn8&}tP_!OIZj-0x4e@XOzdqs)R{3^CuYyv?fXguJ&~Nr|S0~E%3=~!aOc;hW!#RwQ5TZ-;;aqBTJrZ_A7NryQRBVP}}$arF9mJQ$r zF$fbv%1i^%dD3U<0_3?bIGsNz=}ihn3Ay0qAA;m4*An~!(jX)x z!A(jASy`~rBgSNe5Rm)wZ-zty$L4St4d-YdV2U6voCJqY zh&gGtGfH#*&G4rD3KML+@GMh9uGkq9#(2y`##W|t%>*(#LwNA(lVl>tU%6VFX0HNB z##HEE_$I%I1Mzg2j=IZq$zU9^ITB zh8@{9BCchmQ!NdqQNKm8%Q6Hwl7HrAR7_ zYq)tP;87<7HdxV6xk~K8ur$?5=79Vcy^h*T6z6^918yy*aI0pq^n zSWGL9CoE#MJv0nUV|rm(tFu%o3${S!I1FZGc#yE7q0&Fx>14vuz|#%0OZXK`6>E{V zkPDV+I_)y+-Cz2 zABC5QC!?y5=7d~`9mmVChAS5|N{D`opo0P&Nm>U9tJ4yOMtkFy!mYH9?@H>W&PA&4 zoeFh}xoBgfB^O<*LB%pjn(JV$#5sTzFg~^%%M_BXAe4qpPA(n@qdS{)=(yQ>aIp5U zDyf%3#{)h!@aQCKWJOq`-hI8En2W*qB!P#Zw~kGb#L{%@GBw>9Z(Nu`B%Xqp zS@X2g##*1Jbb`gy%%QJo(UeHRw&iX@i4RhWC!s!ts3j~3H+rtw!nj+lma{}UH60pe zHsjiQH2MYexVk2n*lM+eiA+uxcI5y>uW_p$f=N!czq}Kvk8x>aFzWGMcA0ltb*`4{ zWz1d)7$0{uHeCDlF?@n1qO)sB(&!$UQSH@o-fkyen@yu*NAGcp2SZu8j3<=>9QNSU zD*8@KJr6Da^7ZLXiW+v(wD{e=n5{13Z7B>MxsDxlRHV>LJY~+}UWd@NYC1GbHasM*TyVFnfp(3fDT74|AEeZ4obI+X2o7*S zh~I{Xg}}te+I%FwjxNgFO88EA(Q{{zm3ml5!Bp+I3PD%C4-TNrr5)wL1XW3gf}v`& z#ZvBk^F<==$f%oF8Ak-#(-A|%q_0U2Hm>bAeGQ{c`QFP&6%~S_Y0+&7nRvF*!d>&* z33Pp#LLj;XF~sE;W?c_5MW?kq_7{|S&;lhvDy72yV&g+W7dW>jui;UYty#0oNyIf> z)C$Z2G`bRSsx*Ac6O@;5A`xpuU{1?Z(F5d)Rmi;- zI|cg>1Xjqx5VaJ6S8hy@tBn!}GOtsg2N7s?uq{#LsS0^K;}}3!+qom2Ig4WTu)#)5dv$DY5-Pdj z^jn!uQ^UD+bHE6luAFA8+jyzZcEiX_602#UDtW+nde~jcTf3kJ`=&bi7F3(SbebBz zEj|><5W?$^5-K|=)UU|Gf*p}GAtu~v9@;mH^g#@r=KX<;D%WLJCoSPoqAlZANu8v< zjf#@T5V3e>1p4dGLz!9ba>J>qdqGn|OD8Ov7sxze2cNH|$h&}Kvdt_B3Qd(;6P(ll zC!GS-aI7(3z6WWUxaf&hM4Zmd?cW&jPH7X_6G+6hp-5^IlD_<{99trrC)h_BM)E#E z3UYJDxk`bfm_wzsnQC8}JCvEGdZ|-bY6z%j#REr432c`h+rcFh-41FN8684Heo8<#a zX)Gf1%XYFnz;?o^+e}y*V42;xdUa{jsb!vdNE=;EW+TsfUVKm}!*&r78Q4ItM(f?G^rfDM zu*7xfeBpceUWmgI4iy(!xwdo3HF-`ZlNkud-6j65yWy&Z57N6c^JQkw_uv9Who-fqEIvx6bv=Es@aZjMy`J7JHj|u} zXaj7-<&!$TtDdzVg%?MrynfdQf;8PqMKNJGg8k=k6ar(`Fl9Pno{!-W|BCaRs2RG;PZO6T>PnRoPj+-j*2A2|Go1yG1m zt^(@Yn8IO&Zy@NPo6-L{HsbWGD_!vvAY!KSW3LF#3 zz;gqqZ^gF}syQe6EL~-^;c=j=oa0zgnD-$TFEVbmbf|P5C7HXfF;^_;I;T;MBNyh!4-4HHH&i(WxgY%(%&gvY`p8L{FE=Sk-O zBNikbILg_u&T&F#eoK0zQMP1-UNkv=BGCEwI6V$%bDoFX4f+fy;y1a?C|?cNOW+}##;a8=faIaT`=%QM9B29ogWq-2%xtwU zM2Vc!yUO7QB4VBR@GDdJp@2OI6?oz3D0i|8ni-)4S@_=>|L<&K9Zmkt=$k2tP;z*a z6DKF}m~SxVAajQT{2tjmN2WlPIdi)$5WHT%w-m@qBR+TFZ;Mq@8^I#YgefB!xPGFL zOALMmljGZoU+xeXMTf_cODK{Ck2;D4exlFMuk8pu0LHaw$`K@6!kkfN$kJoZ#p4~z zhz~F`iS!q9Q8dFs(^f?tgeag*$|f*wdc=E2<`kNsQCA>OjLIOw58U`caBAUFFw@>~ zsJOad1UO!GBOn)+y@H(6bLO9di=3*OOthUW&Fd4@SZ*JO2AVTHCN~&K2ZyHBhluW4 zH$qihtWaAU84K_P7Aqd<*@Wz={E_%+h)koQp|;DZhxj=qUn42v8s?XJg>$_Xw{rTd zhayv~TU8q?>cxEMwD7KZWOQmLyneV@_M4L4Bn57*JQV@`c>Dq~w8;P1BxlYQ|8(L? z<$PD5%2O30Ee%?j3r`gX!XTUq(b^EX#LAGe7}D25&J)L4*)W(Y4vudM@Xa876F~)1 zpd|?RDr=O~NxWG@!;bc@d+$_01SO5t{!WkYf~S_GibDgp7Bk};GHD5>AjNLJVXuWN zmpQ%^KfnO~;u|U63$N{}6dL8aAzau2PUJZj%5&>H20^lx;2L*IItU3Mv)t69ErDrF zO^_g@Nr$HsRh~K_HVj8$rJzNfE$=NuXE(K$b~9(aRr+98mmw5Ni>KY?IXO*xu1lVU zhdob4c-Es&=PIOzgciF63oSmP!QK=z`Y6a9Xpqq*7swaR;mEHK2{Oko&f~<#YIDGz zB>WY&_Fm8=^wk;{zFxyvQCTR8hDI`X;b(mF4-^Gw5qfsTY<;mpP474~aC59E$p$b= zG|qD)JhcQvE@R6T7RyyIRU8UL*3Q32Y%qeZ3ydRU3(>TpSma+qW?mzSzM<_5&+@Ga z);rG|R=&;XH*VTP4tr{6!koNah3JGh7(fpSGZ*ugdq1Tdh(H`c2$CZ-yTd`Ny^V$) zO@*V{*>WwyFY;x_8;I=?e-5L!cQ?Gf<8-!c=i+ zV3l*fBmWBVCWaAx1V^47ZqDZeCIEP(g@eo7LNZ*m(JX2&QqFrB2rM%m!15V`}lN_oE6QiUH1~$GLkt;lsI( z`N&Lb83Du^%n}+6vgAfqs8Q>)Te|ExI*Scw(Qr1gqO*I10!Q9p1hi<1j#ER}WfC+c zG`68Q#d}LjWMXJff7U12SfJ`-T$cb6L2`87=E;`CID@P{tN=L!hPL-MFrTdimLwvq zMpss!E2qlbB35LfUI%$pF3!ClM>p^5lb9H%;vMiL+vt4WQS200agn|HXq=W1Ojd!f zjDS^#77~C4cNVU8^Kdmfw`{X&6R=TIBgF|{ewr^NjXHPYwsMz1Lq~i)2G5^Fw^AEs zOeJYr$6zC+R(t&{2YrWj8(#lqBf{(koJf#_+25S4#`91=O3us_oT%rhN~zT@2Kan6nu2r;;8PWHicvN)Txg@XYI zPgbkhbdsFS)7QMgPXY+o4p4@%VMq7YspsR4b0Vxjh=Ct$5EPmUzhMT0hLKd6ZC6Vq z&V&_zgyV3p`auPtv%+$$*Mt-`7h=l9N47s5 zi9Mrd&T&rop&-{Vl<7r$7BonUgOuOJ8|*7g!^qMzJxdWd#34et(S{KWBKM0hlQG{Z z{*6z$1TV^NBQqHzh6w?K2C`mgNVx{F!|Y%P z61N?sw~Vw2mo6|dJ4nL_i>!037v+%2p^4EYJQwPi0}T-D-9keINngRxM(L~YL-58giCENh`BV!dL+f7yUf+eIW8#z-OL>MxvT zJ}Z`Y+hT9S+;yIYk<_qqRGx@yspnxwTWhWIBPi6`FtJ`uZ}KI)Yjf3xxv1}6Mkr)# z423I5hHyk1elyJ7`RN-j2(ply;s68L81s&Vsp8PUBIiOM5UyDxbm%jyTpCj+a2p7i zMnWaZbplziF=M@<#`B>F;vjTkGV|=%cPZQj;fS8EzEdp#3})VkFkU`)C`ar zG?jLmMz>(gI}3#cE4RRqWz1|VP=wSeV|8t*WlVWRC$m!=gMQt#?CF596BGIscldg?b?XlZ9h8-vL)QwnI) zjBMC|*?SM@QG|^dijdwt2t2nxYyu_&R_L^QjfPg_WOTxx@EHD+E{kqE)P*%`CVkp#6+TzVSjD)Vpzebsy zPbQ#gEe>c&kPM{}TFUj+wr-x~GR$1l{MkI-UjJN!O~SwaDO2Vejl(pj!_!Ep_%`_X zpDYyi`$Bi9`*W9wjl;O2QOLu8y2GbiU`gHeDWSve=XI-1e*KC3&N>(36Bx==EnSE> zoG6qNN9ha%3A0FiY;3sTJhcK_&YWd)E3gdt_so@r*(8obfjKu;xEyF2OO+vv<_t5E z6&63W=Fk>_b3~he2$1NG7hViJDO?jg$Z3%;zHZAeT$Mqt*J(zE0f7AVcQKAz{0CiU z8OG?^c%06pXo~q;aMGQ%=^jln3|XB%kb4g@LC32FJ)_M3Pxfj(n0Z{rQ($*AgJb=g zO<$tzzGT~pX(xm|?;NPO?uFjTI_&7l1O`-6+$-vZmMbLNfxgx06+T@FX2RToT0CaV zA{NA1AOkK0383N3hlS}hH9Yd#D3~e^4XpAu+HG@!BK1dxParuO9o! zT!tGyp+Aqy1TQB{3FcoR^PM#NI>EtWg^UOK{Z|5B9uSOjkxQ94D25OC&G3QP#qSXl zL@ePLKp^5m{ymSZ@CA$qau9ag8|)T#hK}!TV}c#Fw*AEL4gug+ZO0za*aYBg=tj-A3`H<`VFrIqrDW27U$S z2B!wAoEWN7>NGw`gy%`Ijf|Fi9}BlbH53Y{(#9zbLs`*ET=d5cdn|DW02oMDvyK&& zseLljLSxUnh!n)dq%_Iu_{~_arZ-tZ>80={Eg!TJ@~PyfL(8gF?xVk5Z0DDy<`PSE zP;8IUU&0+S96}4Vz6Z$?itb^tL_nf+Bo)TI@E}NzG`nm7g0%y(^)|p52S-Li0VZvy zeA#v)NQPKwbFU%)o4+KOb!GDoB(A*H^4320f>{!b=LkUsvMtn>GazanRy!LKo7QV& ze}WI6OLQ32h~}OU^ZDy9Cq2zmF~4Uxgkv~yhs=XaQhm8ZlzEQz{6ml&;d2%mMovAw z>}l$G=qLwstdgZBZZ$F;D$iC4-*YjbKvh_F%EI8aO5AhQZjOtXi^0wr zhb>M#2)Q%fIpZ`#fmICYO;sPm0}e6F+&h{GTpv&ah*_Y-a!rdqFD=l?4JW!?3GCGd zp_FKL561pO$YWd-o;~njPwnG!a8xDtcBhZ;(qu`tlY>bn>}e`I4?oa@MhXiSX?{~; zuP}%>7ROm~%3auLh>RWK>cv*rIgYFX3wD+Hy*fkjZD?o9t25v+N`a|{V^NWbcsy$U zy~Fu-7d-W3X&CQPNorW@Z0X!FwOiI)*4Svu))6K9!rJ_-QW{+gh~U@X`;goxyekc; zbS{YKOC(4_?EU4a_~O2HG>oLeY{wA*V{=C=_Z9^ukEYYq@gQa-6~-4>G>j}Aiyc$U zIFyLD+XTE5hfUcqD64O=P|54}cR2r&UqHw3>k#rUzre!MP0oj+Zx^(sI_8xGmx3=< zMyo}WjLB{`v7%5eE!H6wv>6Jx;uxB>I~8a7qyy#v$Xb{jPdq+crYK7#=H#8FLRTIH z190Twa5&mcN5L5y3(%8^Y_l>nPmbWPze|%PU!?^($v)fn!P#`2jIf~J1>6zZ)523D zFaXX*zYdWnaazm=ImD9Vv>@JTz;|QtZBB!FdgpypZY=fNqdF|+TozPxSbl>q* zg*-S_7FSS{YpHsVap!@CkyO~#m(4gd?Yl%YSy34idnvWr#=1oB>WwD3FeNt==muw0 zSTHu#%}_*K<851EZuk>VIz0tb#jO8nI=$?LDeZ)L$CdQ0Qv0QyoOS{VLgD^xdI>Yr z1F`X4^5VDUxE!LKhRK!_2^{spf-f0@KBhFhG4`{OG56ogUL|h7hX8E(m&aQkWFGlC z0B-}Z4xbGNO6SIXI0V;`7p{Ov)q_l@mp38o1bd!J++x`|T;48K|D%)Qo(~=XEIbiX zfUBczYY2z}c}?$W$| zaI`@RnKb-l1NfH{E3bwWVxa6zwP&hh%_!UeQ zqsSY%;_@rOC7@&Bh|KZKEUhE8I82 ztWJtdEwO+pf_&~QnUjR|0x&_I>`(w?mU}4?SHpCgT8@6JOwdWkUl@Wi^J;`=z7gI8 zFPt2#JXOr4Gsf^j0|chi)Nm&5f;%k;2l5cAV|xTHUAyCL+(lP?XLcX?-1l)NnF~g8 z;h}hUflGLLKi(+inM)^##Jzzsar!PYV|y>{oQ1|KC6Df20~DF7qL_vqJoCU0MrcV1 zE)_j^Zp^ip^FdoUi^Ps?JyUk_fdtWHp1Gq*VRfqP+EUh3aypnN7x{WIk{UK!q>^Ci zzD&@$6f}bn!>n45kizDdv$rP`RPnJ2ri%Fz)Vv_6s+#?s&T+BBMl(Nms=APs@2%3C z9V;{s+l4(ZL08(aEAk6ztzwJ$BC+9NX<62#cy8(HBu7UHx?(0*KY`^Oi=xPJ zJg{;#4+^eY+KF7kM~$oap#46N7m+4k7ta8+a!Wh3zvc!Ee>PBOQTmc4h^Iq zb{EBx*)Wa@t`^K=gcUTw8kdSt+j+sv6e0$oG(kyV!bUG1q>$ElFGuxjE?A@_EbzmrCtKZv1d zQzNFGs&dNALz0~F{5TjHKbRE|pHKgAgiu20NVWPt;M9Zrp!~;0Q5`n)RId_LPt`=md-A=7&+6~SRwL6#Yr}-|3;jfpos?y(Bdjbh4L24#+?EP zNOQWd4g#!#0!rmFd?TC}#1anL!EreNs10C{=vibDD?;&b%qoUQ@95wivxroqV5%6e z5si=6qJ&n^dzErUaH#hKce=V-qzhyEVU?XQRGUO(VbGg%_PBE&f+G`{B%wg`r0~@P zVXD|NooLSOC_F4j2Dn5<06f>T8)I=+t1{YbfI#L8EEfWls1awO@VCLqoty=cITvQZ zt%~IqpgkS^-g$mkp9(0ZappD zde7Ivw6zGHy*o9$38_=mF2HnZ$=fJ#&y_f?ynbd6qLfM1Q#PH=E#2nrc5uY!!KUpr zjHI3oJ#F3M`3xjOuRoVbm1|Bern4S#7EBete!j+N0wy2Eh_A=btRe-g7C&j>qf5ok zyZYI&^5ah4-nEYotT|#iKGPN$`5|j@_3u+7p48M()+CK!8ZZvaN$5SG-Q`v`f9V zQ{OaC7ur*tuBIsCa-;X{V2DcKmNy&eTLM|Gm%k4VOz|!ZaFO&hy^>mKizlB25GyLjmG9bc zD8%Klb@%!SdS=xW)@ws9DlhI3AV&*Ttdhyb>yL)t5KwKfzku1Ai9Kr}_G>2g zsVSglK^DVNc(Vcq1cB4M*#HjaD)-AE{wEjrN%;gr&q@22J7&FUI99|!u+z$~&rDzG z#|o%r6STpyiMwsM00Hqk4_^oT0A;Ucns6=@V7U+$ZB@?T;iKZIWw{K9PT=dn({v66 zQuHIbfwRCKFZO^Ww6ak+dr5_*iuGB9BT9|SP+V@Dd&W*o`3J9nVHmawjTlmD^0BcT z!t8CX1H%dCiNNa(QM_cpN;bme7#^b@$bb`chL?(vriNoh8pj(l$rVv;nIkBr@l_!( z%-&ADkiDHs(bBq0wy~9@-klAQEi5Pr)PIKN8a7fu6NM6rsXk@_&6R%LWJHe&rq=`^ z4~qiJ9bP~YDmtAl1ye=X&_xRZ$&t+qWFQs`p48$1fCj%JlxttVZ_2P?9&Z%*c^$7= zD^EKi?0I!?JCWRwfA9bcOvEmNwJ7G5KTv8l^5CEY%Sj%ZIB}RoyjTl&0L@^-JYww! zPBz3@hrto5B$PKplxTStOa*JJ0ReEVvUR)vY_H!3nqZot2wvY$J;4zVLQSSiF4hjp<{Qnupcbkim6v;b2S!j z4#d4WNKD*Rn!X~ak0jticoR~qFe1}>v;&I^9ve8zjY4I|O$b#%A?>8{*rL_KD&NL= zbK}s!M&8(T5P)wgOlfmMOY~bwRaGVIS(goL@MdmTeqM{417%@j0o%@ksp8PUD*tEG zGzbv54)(Znf)q@p$ysE9BA|dCfLr>yLch#an*iWdDvO)u%&~mo9-cr?f@BE&8}!Qp z`!_`F-LP+?b217ZRaZHSEgm|;KmeIgc%oo?9B8@KB}n`6t8zNr5BFSEz|%OuNy1P+qK~Kr<-E$qE-qS64;NT2&^FCkVi=^x!I(DpmvvZ_~N%h-*S)5e^kg=4*d} zBCu-SY4J@-d&R=hDf2uY8sZkEO0RchQsdLQ6zT3w5hWEI6(g>FFL{s4-a9qD$%^Y%Qark%Cz~vm!^(-Dv((^ ztww4ZbxP_ai+86tuNi?&i=7LL9iyWS`6KYpEBXt6lkI z#26z)KilHOJ${fq1Z%Q9Eca>Clg5Rve%RgM%sO!OirBbMt@qENlBvTbT1;r~=^aU9 zvYAAZ_Xi$os2;Vy)hnr&f@+K^tZi_TwcLf;J(bfaq+Z#obIdYS?2#$@)7<6t!*La^ z#yBaC&+Vdt3{Vv=E~%GdV)!Vg4{H3NDOGw=i=cKYCr}(V;<8sUJEbZU*fqb}mDkU= z1$_FhN@^uJFqj-qwg4BO+Bow((@3eKp=XUHz6`+}j3A^1g9=6fVUgy&!u%&xrPOI0 z<#2#gzW%KIGIXRoL{U=9LPv@f-ju}v!0`^IbOD=*Afu+Uj1*V?y}mK2yp=oAt(+~L zU2JgcYE?)$IEA6PD}z-FMVlHi?bIAZUChZ#6VhJs9f;k5Zq2@-LUkS)-9cke(xvB& zg|icGTgF^aXlFJ5n@#vvi;te|17UrzPErE(O4>Ia61zk(!Cc!p%yR zR(0zYETAc2M^n$Y5~Y|mGiiQTZuOx}p1Fa)Au4=1<|$^IK?%CTH;;S8Vy@Ht!NlBR z@114-M%jC>US*>w16IzFocl6xeyi%1V6sq*z5bSTlphzK2xEYPAG0mInl>6YI_;>+ zLLTr)jZ-FRLl3;PWjezII)|e9SL7L zhfNt$q><-$)nfTex%mq-@q0d|R@v0aBq&13+MSyAN-2V^7O;W|u z5LCLeO#fo5hjQQUil)2al6PE44e>eLz^(@b?Wtq9)lx5p_A0j|3)O!mkYlS2?y4>C zJPykz3Z0rwahXg|ZBQ;vHA~tXCjv#gjp>5FMrsvxn)OAt3rnYL*Ts~KTv44|m1pyi zuRlrCXSj_icJ_t&tI)E_ zExiIp9`-yHA%z?;EQQ=obJ;abq|?$)w6xzaG?cmd z2=%ImlaKcL#&Kw1k+lqQdlE)RdK!ng%af1tv?q}bpMx+sz{voMbX!P8Efg(u8f#aR zxzuFiH}Mt)+FTJPNig{OXVw>;v*A$ieYDT20iZ1UEPVmaUCW@)9W&;E2>SXG+u7n} z4-cxjqa=?o;`ps~$T>qx`nlNR=jp=0;&r79{Os@bhYMwLt~ZCl9A?3nm*M%rldV%D zzR51#z3tuzs%g0(~YH$hMrZ+c-OkjE#5(&!O|R%2^xfzbm&%y zS)%ESEo9035A%dK{MLi)XthM^)euXM|3Az$1*Egy#L9C-BKuH%QfR5sP8+;W`uV>a%hfWIRN((5Fk&*<~dS-g78~8vv3bd z^e})p$q~PT$?+W=F3 z;3RV41M|tXx<+Ko!59aa)>#Ew!M`SKmtugz>jyjab{g{Th`cc(*E!;@%>v@=VO49* z>sO9Fqz#y`4vqD9Pf9ph45VF#HzDnn@Fwh?#64#hrXj^*+y@{w4&7O?(GpDJAB+w(Qea*ii@>yXT9eWyDs#>22e48hFwb83Bo#k@|N34>APv=1p z4`^y^V5@Hhq9Qbi+FB+lyK!bWDlEc8qhP8|uteVR-BX&2Urq7J#FQ=6VdR{k>=8wH6=}_uf(IRh*A zW$3^-(}q(~^=igszM27k{TKTcIjWL6?j5a`@xujC_0>+c!uBSnH}%^cR$*~Rs5{S5 zwMArg!3_sxlHM^!B`CDy05Gai)yl@YnKZRr`Dk-eukV!9NlN#I_STl_g~y&HvmHDH zjcar|BdSZ1pL@jI6e<@WYJV1d(*wQMP;zzZ77#qYhJ_%L;0E?uSxYJaK8|i8LZx>Q!)^R&kDGk^tsh4z9 zlFi6QJA4jxkSWRrlwT|wO&$L>>u;x*cOmT*uh$B3i`Y2iU=}9Gc9q?BC7Yj0oeYdy zoVl=Et-A&2O6<9!&UrG*#NF^_T&C01aD2R@?4Trn{qgR&#S2cMvAX!m*6OO(%So;@ zo{SYiYK)O9;kVp=lW^ch(`o9teUGEA0v-6=UF2ak_!UeQ>ziyL7u5JQ3Zuk1_GzJE z#A}qDk~-!X>FQBkWNcGu?(3zHCA5JV6H3`$`4}<6v4gh)wEZ_o3L}j zR!8@FGMmhpXAn!e0Vl=cXj>PW>+vyI#hsxG3Q@~bD}+jX*)O3976sz-sEV1nUn~_G zSkq+#WIKCQuxZP`Ru>m;y_}&2UBrfmo-4j8k3Aa{SB{IkwE9vl z8o7$8Xvrlt49$)F`&jqWDnF3qkK|AP`r(Fv!=XHayEU8fUu;riQT&SCjs3pi^7?J% zUx&`Z|{IMptW>WHzMwJ4nomr;X3h~ZIg zfWvmA$OBQ8I62;|fG%5MDk#K7i>A2Hxp;DTvLH*=?`HJLOZjT1qhm`MQH5EziEoBn zVD-~0X{VHg6IyEJ92-*RU#mXuh9{1wg{tKBZKM0X3c{;t zEK1l6guhDZmb!ZgWu1#K9pTg6gG|t<#r}*G%Nlq8x~9NJEdIUOTs~i*JoiBlALZrW zbj8jm{j>k^v+6PAd}=Jcg==`V_1jYk*fUZ&23T4%db-TZ#$#!lO;&e&85faZ!uLcZdCs7({Dd?mVi;aOQOKx0R3I4cAxaGNp# z@_6=>*TqH~AT&0rY>K6Np|n>m1vp76E9D|Pe_7!R2biE(-&YDZnN+JLg(ywS*;0s@ zS{O=wAbCMczOIFtQ_FgII9*J_M`nkwgy;dmfsX_02DepxrOkpBy22Z`g5thaaD+~QMP!f~XFHFB-qaa1(ar!YccSd?$ZeUQfGeU(I6lRM z(~NxXjjX8CyHxxxtXj1eMGku}!keee6vZ8K1Z|X}4C5A`>^}k=afBZ-*0<1L@bz~Y zJoEAWGhY01p$E!07NhR1bSOqXu%)Ub!->cS1+J_6kZb(OPNG1sNurQEr>nbQa?BS8n8FNt#ADn}Y|-HLhAqhr(Yn9|I7ilYVHU+}v<)i@ z@tdKJ8HjklvQ3K-3_fxjn;#KP?1tFEU|?G(o%cwTIS)_BXg(x9<2)2F(Kef8(P3^6avEtCc)ZndRj=P=7*N31wJC!rpVLDA6 zkB!sFgeQ>j92?uG9#AY)n0sdIQ0q!`s7*CTL!>(oamEPV0#l#x!5LvAF;^KWa@;%I zU8x6WR4--k{?cDsAq&rRF`OC_Dn{Gj7ep_;JRY&ZOGCz%1QDhz&L9Fy#3&}yCW!F@*o>5Y z{blsC#>qGs&RVW}ut8z|A;8B%4NiqP$_+;TAyB*QEIG22!ZeMuRA_Klp}5E36F534 z{uYI)M%XB6FEK$nDYd?|Uf}ht-JVNyY>g$xYzABiov>K6FhyX5mNJ2^20gnt#~A=b;#T$Sgw!gb zBdwJ`gA)t&;9QSCISo6SI&N=IJ*DQ^bZbNuy%y0d<|R!~)EV(GaMYI&teGG3AW5$( z9A=IA1(tIylCw%78b(^(2ByQ!U~Qp-X|TC3RN)(4e}!kD)D zc1&B-;q6DUx9PURr}mChcSkGUg(-=JBsD>rx=^t26};GW+hT$RF#`&raUI+;n5D1L z^|zL;aw?WH&`nM~2$d@*;F6>)vM3WH(1?fJ@7ETT*)Zt&{LV1g zYxJIaZfdl!qp9OcKig)KpvJ&`h#m#_)(ZFf59*4@9H)gG@J*{Yl8=ap5Y9+s3UY-^ z3nK|`gKo;`8wWd8^hEi4({o3Z5q!6dkYKhV|K92BE@)*?l;MpG!$ZM&7-kF^o6c+; z35t+{Dxgq497$ADDWQF#5=@L*(uZ!D_l(P29Y>?NVYb_^~0oJyz)Czqyk73tAl zjMOUEE3r!5hCStaHD6TWExBN$Shm{9p;1s7kpmPVxzs4Bkv4YVvgsr_yPaNtX2rto z6lN$q){CYyG^(kL*gZhZYSmP9aaHaVM*p;HkkBtAd7gfWxMEgm|;hO6aaM|*4QKo)Fr z>>Nd%+gyq3D4(r6meWRH92MG=&L!HK!dCX|06?`0RiJQ%rd2#fJ28)oFb7>#PN5$R zxDZ<5IVwV*MlcO1WI||d6`N!@q~<0bGRl%Q2AJkf6P8op_lU&_BLfA~Y3g~&H?&+^ zHGEc6E3YiSXhs23!5h595F5}leaBNHT!xNxR-q%+>h;%3M%GyJorOroVg>Lj>!n8J0de_36WFhFZ_^z-Pb5iA2O;tvfxc9*q-nL#c z>O|99Fy4h_ub{^4mF-e4+b)fmc53PUDy1fy_y8hbdBihO<*5obZVI!Q0wU}$u-z5o zg-7gA(_uSxF_l(LH4CX+-~qTajHH&SyHYupt@N~WuCiowjM`5@kjgrUu3`x3&7hZd z$0jT7g(R^PSpCq5&AD(!xDTEmvm64+03$J=km-Ow=yz5nJQj&nBTqb%G45z;cr@3M zBsh#*-)adjQdL!gg%k@t*3LC{%4yxZ?|6A600AF{CDkLqjAH^3t>ls$y{#E1p^l?g!B^-e6T7oUo_&LEee} zJc8V_HkXh_Q!qjdt2zxZ$#Rv;k+{PwZYRs4+ewVm7zE_Ot#WXf)(i~E(l9-tu@)x7 z=nZTG%*P1y5VYFCIkyE6$eg#p%{P9W?vVE~91GeU`S%urPy)_E*82$(^m4ZocG4f} z(3e81r+3X7v%+PSe1b)!iYzOQh~wL2lCDF!Y;A2JIl7FO=zG6kf5*n_v5`Gqi{l*ITG!kq#CGFm`hrlng6u#5 z`m`0b1wv$9sS>975G-9F(MLrrjjT5}ZUmSOz_UJxH6%sJgL&ai8+FqZOs7lFryY$A_YRyVllh$?TtP}a8%`AxajT_6CDb`4 z!d)uQmCy=X)aZf8gs`KU04UgG z_93dxU~e|D@-0j7T#JLVX*jev6@tFCo(%YyUcb-VtoQP>vsCGI8xd8Vj7dTSI1lIH`nbX-ywEPEL{>{IxDJ*UK5=>N*sjl}t0+s9;tsVZ-}Vfy}Y$ z6u*FzH&PjsV`w2fXA_stdVMQEp4^6e1jx+vrejS3z%UA-??;rZ{10=5dwRpoR0|Fb zEb_giU&fYrD_(<~=wZBw;iYDFq`9K zw!HQC5fM1%U-&i-0GPm~kqM^?U}Sto>C8rk$Zhx~+-{?jdDQ;>jwqE0RgyvOe2u-~ zqlR%9#O43j?=Ot$VVA*?)4Q0gwP3UQj1W04aHZv2STH+ zX^e(+7U|t4v9DPmMR_2|#qUBc%pFg~F*~L!jy6Ocj)C%uPqY0I@RjzePqTR_md*gH zkgJa>U0Qr*ytTA-8e2LRhg^PBD@pO=e^hbIBpu7)VTFYT zrh-@AVii2~WNDakk+axhb2sq*YvT;%v*JZIm~6=A#&B+c-@GfzSo47mOIy(PvH(ZS zmcT2tbND6H<8p`!BbW=RfIRjS&57%JSw0osTzVcPl1n;TGHF=@rpY zFjYMAR&gX@_pVq?>`u=I$F1o3U~dzOHc@2tBmb1{%nNuLnTrDkX<&*lSq<p};@<97n~DnVdD%l?b z0UlBq8ZN&RBtyt8Q#{%yehzh+;ZPuRg5g+^QV(c4@*6<6!sI4BVr@esRJ!urE=^}h zeB)S-!q#Vca4&b7Vxig~s}(3m>Bw0qllf%~pOzP9i5t*nJCtk! z<7tHOBIiKc%uw3Hg&;W!1-OLvKX)lty%K{uQy%f)vKY0z$dM#faB>g|aOtKRDcpz~ z#1IHaM<-r(I|1`qsInMlXYdXlEHIIwd6>l-?sS?nh`!|HcbxdV((Zx&EkC*}&=!Bu zO_cIy(~B>%A6X}>CZntQ761Y8$phmEHuRR zD64|cLeCAcS5~-@pL-M>3dDv-AU7xFPS`+5#@JImne)3Yzk}E(wM69q;lgD{MY8nU z%b}OjP#+s)?bNiB&(=+J+^Xy_ezMS`bvm=@q2Q`c_GIsJdega$XMqyGrt79EwJ@{5 zu7S;ya+AEBP5NYIp9WVey(%E(Oo|~_IB`~RtKMoSGm|DSFKM(p@T#PdHb9}4v}sm3OtU3l zb>a@lSp%w~Nva*=pod)rPc4yGg`|erxXq!&rE#!y7snPWKX7dVP2(gD#PtGO75#;f z--BN8%Ws$9kpe3FN}u zaV=R8JnEZ%#_`1Zhp!80fZTOMbbUw|WU<`6Q&zy+LGjeF@6K{--EPa50+j*y>u(lz zJX9Xe*6yHVk$*ygdCbjrkYD!Z-#b6(764Z|2i!F1yc+^hdLzgKZB$6)ZebaD{evTu za_nPz0E|g73MX$)UjKZtlYr%-JK5-{%E0aqDb!TL_*UyTnP3!K8mEP~`&qZx@z*l*o z*8RJH-1(^JoneY{-3Ee0ln3;ranfOP!}8MD7tmBa^2>5TA~d2)_x&?~(g^=RyY)19OK+b-?Ub3NVuaeW005 z$4O-MUL3!1C(V^)OVpzgaSds)6VgtJd(JLSLyAQsLkxF51q#RG@HjpOU*4S&n0=H_ zWIPsj9Zvkp%n>D6Ux|{VO%Dx}>68JC!A;z30y0;`ylKu&53S0^7swA=k!^S^Kp_;4 z6(y?3Fpr@wXa5s!J$WO8G$ZpR0u1twFym z$~9$>P2j2A(rB!(IvOo{;zY_j3S%eqi0A~8V3cHH{E;NZd4iA#xJd^|_Iu2~jBNu+ z2w&Mha(kK)$Nf3a3YtQ9#t}psiRQ0d=dhyAaKc+C9-NDPd;qXB-$7uaV3cHB5D@GZ zCX$Ap?reFF!e2jMBcBXp`huwY&Vs4p(7-AOtBwgNBoFq+7y`^m#v3kvtU`ejBL&0b zRN17s6}uo{C_R8TSr}{Z*udE05fiWlny9B0GKt$kn7f;_)OgBV;v{#6ietK66%;<# zs!D*MaCs$YqN2wgg?jz#AIE&yaKt`-$SrXwu^v(XjJb-Q;3S?z<_0%zQi4n}0RLlzU zl^t#P){dq<%34@z=w>${I%y!s!FZbQyr@!d39h*SZBtTm~tNXdY6DZxBKaV3-@88i85CndXBUx{9$J zPly`amI)-VI2sEIL;?4Yx$kX#AtMr<C|(Q|F%*y-=|LPK zsLWwckMySq)4bs1WK#Y&Y_51cdT-_fBjTwW!R0p_(A;AbOomxt*^+C9zu@uwi+3cF z5*yn%bVL`T8m18%kAgvd!t@9Ni_jVK{5WeFFyAeF1HJw^sSAN=02B+nOvpbOOq}|l zd3(s}x)cRdath5hhi~ z0(-bk{b~KTBM^9F&b&OrZBn9P%7nj63NdUe0N0Fk1OoR@%0kS_ymeaH8Ks$NX|Tdt zS#la2;Vv7@8?N1QV-~)Z5x1Fxn`{6tOs;Gi84E#8f}KSPli}At6IP&bOoQH+9d68F z1r{W+ADN>Hn~Ac)Mkj)iM1vL8aP-PKBnz$1iie!0Qzs-%%tR zPS9V!!86KZ;rw%aZg{E4)B$on@2KTsV@0;4GpE`k4yKXNk=U`+FbymVlvtdj8-`!O z*kV=?1)4ZwVyr+Db7Rt6SFZAF{DVyMi!Y|1I&{8VHa1>_1{No=JV^BC$W@ANjf4Z+ zDpvIb5p+s968&9p%X`cDf3oxB_~?Lz!q_VPj$JL;dn$BiF&|nE%hwN%WTt$nJne+A z=hZ=Ca-y_t$ydM@uKgH;zUFF*9^?T;9 z7`qx|f@a6t2EH~*s-SZj`yTE*13H_>Z+39M13;9yfG-3|DEBf{{}CPYC}+q&C!E_n zR*p$NYOlT%nsb;;kt5XUz{X=HDYa z1-Wy>BA@#+8Q_qiLmq(3N&0Soyz<2&DEg}X3{nsB`0Z9#zHEESqjf&nRI@Bhwc&O2`N8DzzV z8XF8}siSz!v^q{k_-2l;frL{-f@93D=`FzV{{c`-0RkQa6aWAK2mp?1B0lQ#K5(I( z000O<0ssa87ytkO000310RRAi00000XKXHXcyv`%1pou=!5~d_cnbgl1n2_*00aR7 b002-+1qJ{B000310RT(@007~g00000z)Aaz literal 0 HcmV?d00001 diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilter.java b/modules/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilter.java new file mode 100644 index 00000000000..ee7c6eee4db --- /dev/null +++ b/modules/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilter.java @@ -0,0 +1,69 @@ +package org.apache.lucene.analysis.pt; + +/** + * 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 static org.apache.lucene.analysis.util.VocabularyAssert.assertVocabulary; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.BaseTokenStreamTestCase; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.analysis.core.LowerCaseFilter; +import org.apache.lucene.analysis.standard.StandardTokenizer; +import org.apache.lucene.analysis.util.ReusableAnalyzerBase; + +/** + * Simple tests for {@link PortugueseStemFilter} + */ +public class TestPortugueseStemFilter extends BaseTokenStreamTestCase { + private Analyzer analyzer = new ReusableAnalyzerBase() { + @Override + protected TokenStreamComponents createComponents(String fieldName, + Reader reader) { + Tokenizer source = new StandardTokenizer(TEST_VERSION_CURRENT, reader); + TokenStream result = new LowerCaseFilter(TEST_VERSION_CURRENT, source); + return new TokenStreamComponents(source, new PortugueseStemFilter(result)); + } + }; + + /** + * Test the example from the paper "Assessing the impact of stemming accuracy + * on information retrieval" + */ + public void testExamples() throws IOException { + assertAnalyzesTo( + analyzer, + "O debate pol铆tico, pelo menos o que vem a p煤blico, parece, de modo nada " + + "surpreendente, restrito a temas menores. Mas h谩, evidentemente, " + + "grandes quest玫es em jogo nas elei莽玫es que se aproximam.", + new String[] { + "o", "debat", "politic", "pel", "menos", "o", "que", "vem", "a", + "public", "parec", "de", "mod", "nad", "surpreend", "restrit", + "a", "tem", "men", "mas", "ha", "evid", "grand", "quest", + "em", "jog", "na", "eleic", "que", "se", "aproxim" + }); + } + + /** Test against a vocabulary from the reference impl */ + public void testVocabulary() throws IOException { + assertVocabulary(analyzer, getDataFile("ptrslptestdata.zip"), "ptrslp.txt"); + } +} diff --git a/modules/analysis/common/src/test/org/apache/lucene/analysis/pt/ptrslptestdata.zip b/modules/analysis/common/src/test/org/apache/lucene/analysis/pt/ptrslptestdata.zip new file mode 100644 index 0000000000000000000000000000000000000000..7bcd3367327df9e5fda994806b4a2a3f3d719f1c GIT binary patch literal 132599 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

    #XV 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 literal 0 HcmV?d00001 diff --git a/solr/src/java/org/apache/solr/analysis/GalicianStemFilterFactory.java b/solr/src/java/org/apache/solr/analysis/GalicianStemFilterFactory.java new file mode 100644 index 00000000000..4cd0ec58c07 --- /dev/null +++ b/solr/src/java/org/apache/solr/analysis/GalicianStemFilterFactory.java @@ -0,0 +1,28 @@ +package org.apache.solr.analysis; + +/** + * 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 org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.gl.GalicianStemFilter; + +/** Factory for {@link GalicianStemFilter} */ +public class GalicianStemFilterFactory extends BaseTokenFilterFactory { + public TokenStream create(TokenStream input) { + return new GalicianStemFilter(input); + } +} diff --git a/solr/src/java/org/apache/solr/analysis/PortugueseStemFilterFactory.java b/solr/src/java/org/apache/solr/analysis/PortugueseStemFilterFactory.java new file mode 100644 index 00000000000..be397e33623 --- /dev/null +++ b/solr/src/java/org/apache/solr/analysis/PortugueseStemFilterFactory.java @@ -0,0 +1,28 @@ +package org.apache.solr.analysis; + +/** + * 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 org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.pt.PortugueseStemFilter; + +/** Factory for {@link PortugueseStemFilter} */ +public class PortugueseStemFilterFactory extends BaseTokenFilterFactory { + public TokenStream create(TokenStream input) { + return new PortugueseStemFilter(input); + } +} diff --git a/solr/src/test/org/apache/solr/analysis/TestGalicianStemFilterFactory.java b/solr/src/test/org/apache/solr/analysis/TestGalicianStemFilterFactory.java new file mode 100644 index 00000000000..7d35701d4c0 --- /dev/null +++ b/solr/src/test/org/apache/solr/analysis/TestGalicianStemFilterFactory.java @@ -0,0 +1,36 @@ +package org.apache.solr.analysis; + +/** + * 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.Reader; +import java.io.StringReader; + +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.core.WhitespaceTokenizer; + +/** + * Simple tests to ensure the Galician stem factory is working. + */ +public class TestGalicianStemFilterFactory extends BaseTokenTestCase { + public void testStemming() throws Exception { + Reader reader = new StringReader("cari帽osa"); + GalicianStemFilterFactory factory = new GalicianStemFilterFactory(); + TokenStream stream = factory.create(new WhitespaceTokenizer(DEFAULT_VERSION, reader)); + assertTokenStreamContents(stream, new String[] { "cari帽" }); + } +} diff --git a/solr/src/test/org/apache/solr/analysis/TestPortugueseStemFilterFactory.java b/solr/src/test/org/apache/solr/analysis/TestPortugueseStemFilterFactory.java new file mode 100644 index 00000000000..a8e309a9823 --- /dev/null +++ b/solr/src/test/org/apache/solr/analysis/TestPortugueseStemFilterFactory.java @@ -0,0 +1,36 @@ +package org.apache.solr.analysis; + +/** + * 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.Reader; +import java.io.StringReader; + +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.core.WhitespaceTokenizer; + +/** + * Simple tests to ensure the Portuguese stem factory is working. + */ +public class TestPortugueseStemFilterFactory extends BaseTokenTestCase { + public void testStemming() throws Exception { + Reader reader = new StringReader("maluquice"); + PortugueseStemFilterFactory factory = new PortugueseStemFilterFactory(); + TokenStream stream = factory.create(new WhitespaceTokenizer(DEFAULT_VERSION, reader)); + assertTokenStreamContents(stream, new String[] { "maluc" }); + } +} From 66d3f38d52ec2b0cc08935c42795be8f5b97def9 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 6 Jan 2011 14:33:35 +0000 Subject: [PATCH 012/252] LUCENE-2842: missing eol-style git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055893 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/analysis/gl/galician.rslp | 1294 ++++++++--------- .../apache/lucene/analysis/pt/portuguese.rslp | 912 ++++++------ 2 files changed, 1103 insertions(+), 1103 deletions(-) diff --git a/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp index 8be8478fd73..33fe8fb1109 100644 --- a/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp +++ b/modules/analysis/common/src/resources/org/apache/lucene/analysis/gl/galician.rslp @@ -1,647 +1,647 @@ -# Steps file for the RSLP stemmer. - -# Step 1: Plural Reduction -{ "Plural", 3, 1, {"s"}, - # bons -> bon - {"ns",1,"n",{"luns","furatap贸ns","furatapons"}}, - # xam贸s -> xam贸n - {"贸s",3,"贸n"}, - # bal玫es -> bal贸n - {"玫es",3,"贸n"}, - # capit茫es -> capit茫o - {"茫es",1,"茫o",{"m茫es","magalh茫es"}}, - # normais -> normal - {"ais",2,"al",{"cais","tais","mais","pais","ademais"}}, - {"谩is",2,"al",{"c谩is","t谩is", "m谩is", "p谩is", "adem谩is"}}, - # pap茅is -> papel - {"茅is",2,"el"}, - # pos铆beis -> pos铆bel - {"eis",2,"el"}, - # espanh贸is -> espanhol - {"贸is",2,"ol",{"escornab贸is"}}, - # caracois -> caracol - {"ois",2,"ol",{"escornabois"}}, - # cadr铆s -> cadril - {"铆s",2,"il",{"pa铆s"}}, - # cadris -> cadril - {"is",2,"il",{"menfis","pais","kinguis"}}, - # males -> mal - {"les",2,"l",{"ingles","marselles","montreales","senegales","manizales","m贸stoles","n谩poles"}}, - # mares -> mar - {"res",3,"r",{"petres","henares","c谩ceres","baleares","linares","londres","mieres","miraflores","m茅rcores","venres", "pires"}}, - # luces -> luz - {"ces",2,"z"}, - # luzes -> luz - {"zes",2,"z"}, - # leises -> lei - {"ises",3,"z"}, - # anim谩s -> animal - {"谩s",1,"al",{"m谩s"}}, - # gases -> gas - {"ses",2,"s"}, - # casas -> casa - {"s",2,"",{"barbad茅s","barcelon茅s","canton茅s","gabon茅s","llan茅s","medin茅s","escoc茅s","escoc锚s","franc锚s","barcelon锚s","canton锚s","macram茅s","reves","barcelones","cantones","gabones","llanes","magallanes","medines","escoces","frances","xoves","martes","ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","p锚sames","cr煤cis","pa铆s","cangas","atenas","asturias","canarias","filipinas","honduras","molucas","caldas","mascare帽as","micenas","covarrubias","psoas","贸culos","nupcias","xoves","martes","llanes"}}}; - -{ "Unification", 0, 0, {}, - # cansad铆simo -> cansad铆simo - {"铆ssimo",5,"铆simo"}, - # cansad铆sima -> cansad铆sima - {"铆ssima",5,"铆sima"}, - # homa莽o -> homazo - {"a莽o",4,"azo"}, - # mulhera莽a -> mulheraza - {"a莽a",4,"aza"}, - # xentu莽a -> xentuza - {"u莽a",4,"uza"}, - # manilhar -> manillar - {"lhar",2,"llar"}, - # colher -> coller - {"lher",2,"ller"}, - # melhor -> mellor - {"lhor",2,"llor"}, - # alho -> allo - {"lho",1,"llo"}, - # linhar -> li帽ar - {"nhar",2,"帽ar"}, - # penhor -> pe帽or - {"nhor",2,"帽or"}, - # anho -> a帽o - {"nho",1,"帽o"}, - # cunha -> cu帽a - {"nha",1,"帽a"}, - # hospital谩rio -> hospitalario - {"谩rio",3,"ario"}, - # bibliotec谩ria -> bibliotecaria - {"谩ria",3,"aria"}, - # agradable -> agrad谩bel - {"able",2,"谩bel"}, - # agrad谩vele -> agrad谩bel - {"谩vel",2,"谩bel"}, - # imposible -> impos铆bel - {"ible",2,"铆bel"}, - # impos铆vel -> impos铆bel - {"铆vel",2,"铆bel"}, - # imposi莽om -> imposici贸n - {"莽om",2,"ci贸n"}, - # garagem -> garaxe - {"agem",2,"axe"}, - # garage -> garaxe - {"age",2,"axe"}, - # impress茫o -> impress贸n - {"茫o",3,"贸n"}, - # irmao -> irm谩n - {"ao",1,"谩n"}, - # irmau -> irm谩n - {"au",1,"谩n"}, - # garrafom -> garraf贸n - {"om",3,"贸n"}, - # cantem -> canten - {"m",2,"n"}}; - -{ "Adverb", 0, 0, {}, - # felizmente -> feliz - {"mente",4,"",{"experimente","vehemente","sedimente"}}}; - -{ "Augmentative", 0, 1, {}, - # cansad铆simo -> cansad - {"d铆simo",5}, - # cansad铆sima -> cansad - {"d铆sima",5}, - # amabil铆simo -> ama - {"bil铆simo",3}, - # amabil铆sima -> ama - {"bil铆sima",3}, - # fort铆simo -> fort - {"铆simo",3}, - # fort铆sima -> fort - {"铆sima",3}, - # cent茅simo -> cent - {"茅simo",3}, - # cent茅sima -> cent - {"茅sima",3}, - # paup茅rrimo -> paup - {"茅rrimo",4}, - # paup茅rrima -> paup - {"茅rrima",4}, - # charlatana -> charlat - {"ana",2,"",{"argana","banana","choupana","espadana","faciana","iguana","lantana","macana","membrana","mesana","nirvana","obsidiana","palangana","pavana","persiana","pestana","porcelana","pseudomembrana","roldana","s谩bana","salangana","saragana","ventana"}}, - # charlat谩n -> charlat - {"谩n",3,"",{"adem谩n","bard谩n","barreg谩n","corric谩n","curric谩n","fais谩n","furac谩n","fust谩n","gab谩n","gabi谩n","gal谩n","ga帽谩n","lavac谩n","maz谩n","mour谩n","rabad谩n","ser谩n","serr谩n","tab谩n","tit谩n","tobog谩n","ver谩n","volc谩n","volov谩n"}}, - # homazo -> hom - {"azo",4,"",{"abrazo","espazo","andazo","bagazo","balazo","bandazo","cachazo","carazo","denazo","engazo","famazo","lampreazo","pantocazo","pedazo","pre帽azo","regazo","ribazo","sobrazo","terrazo","trompazo"}}, - # mulleraza -> muller - {"aza",3,"",{"alcarraza","ameaza","baraza","broucaza","burgaza","cabaza","cachaza","calaza","carpaza","carraza","coiraza","colmaza","fogaza","famaza","labaza","li帽aza","melaza","mordaza","paraza","pinaza","rabaza","rapaza","trancaza"}}, - # cascallo -> casc - {"allo",4,"",{"traballo"}}, - # xentalla -> xent - {"alla",4}, - # bocarra -> boc - {"arra",3,"",{"cigarra","cinzarra"}}, - # medicastro -> medic - {"astro",3,"",{"balastro","bimbastro","canastro","retropilastro"}}, - # poetastra -> poet - {"astra",3,"",{"banastra","canastra","contrapilastra","piastra","pilastra"}}, - # corp谩zio -> corp - {"谩zio",3,"",{"top谩zio"}}, - # soutelo -> sout - {"elo",4,"",{"bacelo","barrelo","bicarelo","biquelo","boquelo","botelo","bouquelo","cacarelo","cachelo","cadrelo","campelo","candelo","cantelo","carabelo","carambelo","caramelo","cercelo","cerebelo","chocarelo","coitelo","conchelo","corbelo","cotobelo","couselo","destelo","desvelo","esf谩celo","fandelo","fardelo","farelo","farnelo","flabelo","ganchelo","garfelo","involucelo","mantelo","montelo","outerelo","padicelo","pesadelo","pinguelo","piquelo","rampelo","rastrelo","restelo","tornecelo","trabelo","restrelo","portelo","ourelo","zarapelo"}}, - # avioneta -> avion - {"eta",3,"",{"arqueta","atleta","avoceta","baioneta","baldeta","banqueta","barraganeta","barreta","borleta","buceta","caceta","calceta","caldeta","cambeta","canaleta","caneta","carreta","cerceta","chaparreta","chapeta","chareta","chincheta","colcheta","cometa","corbeta","corveta","cuneta","desteta","espeta","espoleta","estafeta","esteta","faceta","falanxeta","frasqueta","gaceta","gabeta","galleta","garabeta","gaveta","glorieta","lagareta","lambeta","lanceta","libreta","maceta","macheta","maleta","malleta","mareta","marreta","meseta","mofeta","muleta","peseta","planeta","raqueta","regreta","saqueta","veleta","vendeta","vi帽eta"}}, - # guapete -> guap - {"ete",3,"",{"alfinete","ariete","bacinete","banquete","barallete","barrete","billete","binguelete","birrete","bonete","bosquete","bufete","burlete","cabalete","cacahuete","cavinete","capacete","carrete","casarete","casete","chupete","clarinete","colchete","colete","capete","curupete","disquete","estilete","falsete","ferrete","filete","gallardete","gobelete","inglete","machete","miquelete","molete","mosquete","piquete","ribete","rodete","rolete","roquete","sorvete","vedete","vendete"}}, - # pr谩ctica -> pr谩ct - {"ica",3,"",{"andarica","bot谩nica","botica","dial茅ctica","din谩mica","f铆sica","formica","gr谩fica","marica","t煤nica"}}, - # pr谩ctico -> pr谩ct - {"ico",3,"",{"conico","acetifico","acidifico"}}, - # trapexo -> trap - {"exo",3,"",{"arpexo","arquexo","asexo","axexo","azulexo","badexo","bafexo","bocexo","bosquexo","boubexo","cacarexo","carrexo","cascarexo","castrexo","convexo","cotexo","desexo","despexo","forcexo","gabexo","gargarexo","gorgolexo","inconexo","manexo","merexo","narnexo","padexo","patexo","sopexo","varexo"}}, - {"exa",3,"",{"airexa","bandexa","carrexa","envexa","igrexa","larexa","patexa","presexa","sobexa"}}, - # multid茫o -> mult - {"id茫o",3}, - # pequeni帽o -> pequeno - {"i帽o",3,"o",{"cami帽o","cari帽o","comi帽o","golfi帽o","padri帽o","sobri帽o","vici帽o","veci帽o"}}, - # pequeni帽a -> pequena - {"i帽a",3,"a",{"camari帽a","campi帽a","entreli帽a","espi帽a","fari帽a","mori帽a","vali帽a"}}, - # grandito -> grand - {"ito",3,""}, - # grandita -> grand - {"ita",3,""}, - # anomaloide -> animal - {"oide",3,"",{"anaroide","aneroide","asteroide","axoide","cardioide","celuloide","coronoide","discoide","espermatozoide","espiroide","esquizoide","esteroide","glenoide","linfoide","hemorroide","melaloide","sacaroide","tetraploide","varioloide"}}, - # cazola -> caz - {"ola",3,"",{"aixola","ampola","argola","arola","arter铆ola","bandola","b铆tola","bract茅ola","cachola","carambola","carapola","carola","carrandiola","catrapola","cebola","centola","champola","chatola","cirola","c铆tola","consola","corola","empola","escarola","esmola","estola","fitola","flor铆cola","gara帽ola","g谩rgola","garxola","glicocola","g贸ndola","mariola","marola","michola","pirola","rebola","rup铆cola","sax铆cola","s茅mola","tachola","t贸mbola"}}, - # pedrolo -> pedr - {"olo",3,"",{"arrolo","babiolo","cacharolo","caixarolo","carolo","carramolo","cascarolo","cirolo","codrolo","correolo","cotrolo","desconsolo","rebolo","repolo","subsolo","tixolo","t贸mbolo","torolo","tr茅molo","vac煤olo","xermolo","z贸colo"}}, - # vellote -> vell - {"ote",3,"",{"aigote","alcaiote","barbarote","balote","billote","cachote","camarote","capote","cebote","chichote","citote","cocorote","escote","ga帽ote","garrote","gavote","lamote","lapote","larapote","lingote","l铆tote","magote","marrote","matalote","pandote","paparote","rebote","tagarote","zarrote"}}, - # mozota -> moz - {"ota",3,"",{"as铆ntota","caiota","cambota","chacota","compota","creosota","curota","derrota","d铆spota","gamota","maniota","pelota","picota","pillota","pixota","queirota","remota"}}, - # gordocho -> gord - {"cho",3,"",{"abrocho","arrocho","carocho","falucho","bombacho","borracho","mostacho"}}, - # gordecha -> gord - {"cha",3,"",{"borracha","carracha","estacha","garnacha","limacha","remolacha","abrocha"}}, - # baratuco -> barat - {"uco",4,"",{"caduco","estuco","fachuco","malluco","saluco","trabuco"}}, - # borrachuzo -> borrach - {"uzo",3,"",{"carri帽ouzo","fachuzo","ma帽uzo","mestruzo","tapuzo"}}, - # xentuza -> xent - {"uza",3,"",{"barruza","chamuza","chapuza","charamuza","conduza","deduza","desluza","entreluza","induza","reluza","seduza","traduza","trasluza"}}, - # babuxa -> bab - {"uxa",3,"",{"caramuxa","carrabouxa","cartuxa","coruxa","curuxa","gaturuxa","maruxa","meruxa","miruxa","moruxa","muruxa","papuxa","rabuxa","trouxa"}}, - {"uxo",3,"",{"caramuxo","carouxo","carrabouxo","curuxo","debuxo","ganduxo","influxo","negouxo","pertuxo","refluxo"}}, - # grupello -> grup - {"ello",3,"",{"alborello","artello","botello","cachafello","calello","casarello","cazabello","cercello","cocerello","concello","consello","desparello","escaravello","espello","fedello","fervello","gagafello","gorrobello","nortello","pendello","troupello","trebello"}}, - # pontella -> pont - {"ella",3,"",{"alborella","bertorella","bocatella","botella","calella","cercella","gadella","grosella","lentella","movella","nocella","noitevella","parella","pelella","percebella","segorella","sabella"}}}; - -{ "Noun", 0, 0, {}, - # lealdade -> leal - {"dade",3,"",{"acridade","calidade"}}, - # clarificar -> clar - {"ificar",2}, - # brasileiro->brasil - {"eiro",3,"",{"agoireiro","bardalleiro","braseiro","barreiro","canteiro","capoeiro","carneiro","carteiro","cinceiro","faroleiro","mareiro","preguiceiro","quinteiro","raposeiro","retranqueiro","regueiro","sineiro","troleiro","ventureiro"}}, - # marisqueira -> marisqu - {"eira",3,"",{"cabeleira","canteira","cocheira","folleira","milleira"}}, - # hospitalario -> hospital - {"ario",3,"",{"armario","calcario","lionario","salario"}}, - # bibliotecaria -> bibliotec - {"aria",3,"",{"cetaria","coronaria","fumaria","linaria","lunaria","parietaria","saponaria","serpentaria"}}, - # humor铆stico -> humor - {"铆stico",3,"",{"bal铆stico", "ensa铆stico"}}, - # castrista -> castr - {"ista",3,"",{"batista","ciclista","fadista","operista","tenista","verista"}}, - # lavado -> lav - {"ado",2,"",{"grado","agrado"}}, - # decanato -> decan - {"ato",2,"",{"agnato"}}, - # xemido -> xem - {"ido",3,"",{"c谩ndido","c芒ndido","consolido","decidido","duvido","marido","r谩pido"}}, - # mantida -> mant - {"ida",3,"",{"bastida","d煤bida","dubida","duvida","ermida","茅xida","guarida","lapicida","medida","morida"}}, - {"铆da",3}, - # mant铆do -> mant - {"ido",3}, - # orelludo -> orell - {"udo",3,"",{"estudo","escudo"}}, - # orelluda -> orell - {"uda",3}, - {"ada",3,"",{"abada","alhada","allada","pitada"}}, - # comedela -> come - {"dela",3,"",{"cambadela","cavadela","forcadela","erisipidela","mortadela","espadela","fondedela","picadela","arandela","candela","cordela","escudela","pardela"}}, - # fontela -> font - {"ela",3,"",{"canela","capela","cotela","cubela","curupela","escarapela","esparrela","estela","fardela","flanela","fornela","franela","gabela","gamela","gavela","glumela","granicela","lamela","lapela","malvela","manela","manganela","mexarela","micela","mistela","novela","ourela","panela","parcela","pasarela","patamela","patela","paxarela","pipela","pitela","postela","pubela","restela","sabela","salmonela","secuela","sentinela","soldanela","subela","temoncela","tesela","tixela","tramela","trapela","varela","vitela","xanela","xestela"}}, - # agrad谩bel -> agrad - {"谩bel",2,"",{"af谩bel","fi谩bel"}}, - # combust铆bel -> combust - {"铆bel",2,"",{"cr铆bel","impos铆bel","pos铆bel","fis铆bel","fal铆bel"}}, - # fabricante -> frabrica - {"nte",3,"",{"alimente","adiante","acrescente","elefante","frequente","freq眉ente","gigante","instante","oriente","permanente","posante","possante","restaurante"}}, - # ignorancia -> ignora - {"ncia",3}, - # temperanza -> tempera - {"nza",3}, - {"acia",3,"",{"acracia","audacia","falacia","farmacia"}}, - # inmundicia -> inmund - {"icia",3,"",{"caricia","delicia","ledicia","malicia","milicia","noticia","pericia","presbicia","primicia","regalicia","sevicia","tiricia"}}, - # xustiza -> xust - {"iza",3,"",{"alvariza","baliza","cachiza","caniza","ca帽iza","carbaliza","carriza","chamariza","chapiza","fraguiza","latiza","longaniza","ma帽iza","nabiza","peliza","preguiza","rabiza"}}, - # clarexar -> clar - {"exar",3,"",{"palmexar"}}, - # administraci贸n -> administr - {"aci贸n",2,"",{"aeraci贸n"}}, - # expedici贸n -> exped - {"ici贸n",3,"",{"condici贸n","gornici贸n","monici贸n","nutrici贸n","petici贸n","posici贸n","sedici贸n","volici贸n"}}, - # excepci贸n -> except - {"ci贸n",3,"t"}, - # comprensi贸n -> comprens - {"si贸n",3,"s",{"abrasi贸n", "alusi贸n"}}, - # doaz贸n -> do - {"az贸n",2,"",{"armaz贸n"}}, - # garraf贸n -> garraf - {"贸n",3,"",{"abal贸n","acorde贸n","alci贸n","aldrab贸n","aler贸n","ali帽贸n","amb贸n","bomb贸n","calz贸n","camp贸n","canal贸n","cant贸n","capit贸n","ca帽贸n","cent贸n","cicl贸n","coll贸n","colof贸n","cop贸n","cot贸n","cup贸n","pet贸n","tir贸n","tour贸n","tur贸n","unci贸n","versi贸n","zub贸n","zurr贸n"}}, - # lambona -> lamb - {"ona",3,"",{"abandona","acetona","aleurona","amazona","an茅mona","bombona","cambona","carona","chacona","charamona","cincona","condona","cortisona","cretona","cretona","detona","estona","fitohormona","fregona","gerona","hidroquinona","hormona","lesiona","madona","maratona","matrona","metadona","mon贸tona","neurona","pamplona","peptona","poltrona","proxesterona","quinona","quinona","silicona","sulfona"}}, - # bretoa -> bret贸n - {"oa",3,"",{"abandoa","madroa","barbacoa","estoa","airoa","eiroa","amalloa","谩mboa","am茅ndoa","anchoa","antin茅boa","av茅ntoa","avoa","b谩goa","balboa","bisavoa","boroa","canoa","caroa","comadroa","coroa","茅ngoa","esp谩coa","filloa","f铆rgoa","gra帽oa","lagoa","lanzoa","magoa","m谩moa","morzoa","noiteboa","noraboa","para帽oa","persoa","queiroa","ra帽oa","t谩boa","tataravoa","teiroa"}}, - # demon铆aco -> demon铆 - {"aco",3}, - # demon铆aca -> demon铆 - {"aca",3,"",{"alpaca","barraca","bullaca","buraca","carraca","casaca","cavaca","cloaca","entresaca","ervellaca","espinaca","estaca","farraca","millaca","pastinaca","pataca","resaca","urraca","purraca"}}, - # carballal -> carball - {"al",4,"",{"afinal","animal","estatal","bisexual","bissexual","desleal","fiscal","formal","pessoal","persoal","liberal","postal","virtual","visual","pontual","puntual","homosexual","heterosexual"}}, - # nadador -> nada - {"dor",2,"",{"abaixador"}}, - # benfeitor -> benfei - {"tor",3,"",{"autor","motor","pastor","pintor"}}, - # produtor -> produt - {"or",2,"",{"asesor","assessor","favor","mellor","melhor","redor","rigor","sensor","tambor","tumor"}}, - # profesora -> profes - {"ora",3,"",{"albacora","an谩fora","谩ncora","apisoadora","ardora","ascospora","aurora","av茅spora","bit谩cora","can茅fora","cantimplora","cat谩fora","cepilladora","demora","descalcificadora","di谩spora","empacadora","ep铆fora","ecavadora","escora","eslora","espora","fotocompo帽edora","fotocopiadora","grampadora","is铆cora","lavadora","lixadora","macrospora","madr茅pora","madr谩gora","masora","mellora","met谩fora","microspora","mil茅pora","milp茅ndora","n茅cora","oospora","padeadora","pasiflora","p茅cora","p铆ldora","p贸lvora","ratinadora","r茅mora","retroescavadora","s贸fora","torradora","tr茅mbora","uredospora","v铆bora","v铆ncora","zoospora"}}, - # zapatar铆a -> zapat - {"ar铆a",3,"",{"librar铆a"}}, - # etiquetaxe -> etiquet - {"axe",3,"",{"aluaxe","amaraxe","amperaxe","bagaxe","balaxe","barcaxe","borraxe","bescaxe","cabotaxe","carraxe","cartilaxe","chantaxe","colaxe","coraxe","carruaxe","dragaxe","embalaxe","ensilaxe","epistaxe","fagundaxe","fichaxe","fogaxe","forraxe","fretaxe","friaxe","garaxe","homenaxe","leitaxe","li帽axe","listaxe","maraxe","marcaxe","maridaxe","masaxe","miraxe","montaxe","pasaxe","peaxe","portaxe","ramaxe","rebelaxe","rodaxe","romaxe","sintaxe","sondaxe","tiraxe","vantaxe","vendaxe","viraxe"}}, - # movedizo -> move - {"dizo",3}, - # limpeza -> limp - {"eza",3,"",{"alteza","beleza","fereza","fineza","vasteza","vileza"}}, - # rixidez -> rixid - {"ez",3,"",{"acidez","adultez","adustez","avidez","candidez","mudez","nenez","nudez","pomez"}}, - # mullerengo -> muller - {"engo",3}, - # chairego -> chair - {"ego",3,"",{"corego","derrego","entrego","lamego","sarego","sartego"}}, - # cari帽oso -> cari帽 - {"oso",3,"",{"afanoso","algoso","caldoso","caloso","cocoso","ditoso","favoso","fogoso","lamoso","mecoso","mocoso","precioso","rixoso","venoso","viroso","xesoso"}}, - # cari帽osa -> cari帽 - {"osa",3,"",{"mucosa","glicosa","baldosa","celulosa","isoglosa","nitrocelulosa","levulosa","ortosa","pectosa","preciosa","sacarosa","serosa","ventosa"}}, - # negrume -> negr - {"ume",3,"",{"agrume","albume","alcume","batume","cacume","cerrume","chorume","churume","costume","curtume","estrume","gafume","legume","perfume","queixume","zarrume"}}, - # altura -> alt - {"ura",3,"",{"albura","armadura","imatura","costura"}}, - # cuspi帽ar -> cusp - {"i帽ar",3}, - # febril -> febr - {"il",3,"",{"abril","alfil","anil","atril","badil","baril","barril","brasil","cadril","candil","cantil","carril","chamil","chancil","civil","cubil","d谩til","dif铆cil","d贸cil","edil","est茅ril","f谩cil","fr谩xil","funil","fusil","gr谩cil","gradil","h谩bil","hostil","marfil"}}, - # principesco -> princip - {"esco",4}, - # mourisco -> mour - {"isco",4}, - # esportivo -> esport - {"ivo",3,"",{"pasivo","positivo","passivo","possessivo","posesivo","pexotarivo","relativo"}}}; - -{ "Verb", 0, 0, {}, - # amaba -> am - {"aba",2}, - # andabade -> and - {"abade",2}, - # and谩bade -> and - {"谩bade",2}, - # chorabamo -> chor - {"abamo",2}, - # chor谩bamo -> chor - {"谩bamo",2}, - # moraban -> morab - {"aban",2}, - # andache -> and - {"ache",2}, - # andade -> and - {"ade",2}, - {"an",2}, - # cantando -> cant - {"ando",2}, - # cantar -> cant - {"ar",2,"",{"azar","bazar","patamar"}}, - # lembrarade -> lembra - {"arade",2}, - {"aramo",2}, - {"ar谩n",2}, - # cantaran -> cant - {"aran",2}, - # convid谩rade -> convid - {"谩rade",2}, - # convidar铆a -> convid - {"ar铆a",2}, - # cantariade -> cant - {"ariade",2}, - # cantar铆ade -> cant - {"ar铆ade",2}, - # cantarian -> cant - {"arian",2}, - # cantariamo -> cant - {"ariamo",2}, - # pescaron -> pesc - {"aron",2}, - # cantase -> cant - {"ase",2}, - # cantasede -> cant - {"asede",2}, - # cant谩sede -> cant - {"谩sede",2}, - # cantasemo -> cant - {"asemo",2}, - # cant谩semo -> cant - {"谩semo",2}, - # cantasen -> cant - {"asen",2}, - # loitavan -> loitav - {"avan",2}, - # cantar铆amo -> cant - {"ar铆amo",2}, - # cantassen -> cant - {"assen",2}, - # cant谩ssemo -> cant - {"谩ssemo",2}, - # beber铆amo -> beb - {"er铆amo",2}, - # beb锚ssemo -> beb - {"锚ssemo",2}, - # partir铆amo -> part - {"ir铆amo",3}, - # part铆ssemo -> part - {"铆ssemo",3}, - # cant谩ramo -> cant - {"谩ramo",2}, - # cant谩rei -> cant - {"谩rei",2}, - # cantaren -> cant - {"aren",2}, - # cantaremo -> cant - {"aremo",2}, - # cantar铆ei -> cant - {"ar铆ei",2}, - {"谩ssei",2}, - # cant谩vamo-> cant - {"谩vamo",2}, - # beb锚ramo -> beb - {"锚ramo",1}, - # beberemo -> beb - {"eremo",1}, - # beber铆ei -> beb - {"er铆ei",1}, - # beb锚ssei -> beb - {"锚ssei",1}, - # partir铆amo -> part - {"铆ramo",3}, - # partiremo -> part - {"iremo",3}, - # partir铆ei -> part - {"ir铆ei",3}, - # part铆ssei -> part - {"铆ssei",3}, - # partissen -> part - {"issen",3}, - # bebendo -> beb - {"endo",1}, - # partindo -> part - {"indo",3}, - # propondo -> prop - {"ondo",3}, - # cantarde -> cant - {"arde",2}, - # cantarei -> cant - {"arei",2}, - # cantaria -> cant - {"aria",2}, - # cantarmo -> cant - {"armo",2}, - # cantasse -> cant - {"asse",2}, - {"aste",2}, - # cant谩vei -> cant - {"谩vei",2}, - # perder茫o -> perd - {"er茫o",1}, - # beberde -> beb - {"erde",1}, - # beberei -> beb - {"erei",1}, - # beb锚rei -> beb - {"锚rei",1}, - # beberen -> beb - {"eren",2}, - # beberia -> beb - {"eria",1}, - # bebermo -> beb - {"ermo",1}, - # bebeste -> beb - {"este",1,"",{"faroeste","agreste"}}, - # beb铆amo -> beb - {"铆amo",1}, - # fuxian -> fux - {"ian",2,"",{"enfian","eloxian","ensaian"}}, - # partirde -> part - {"irde",2}, - # part铆rei -> part - {"irei",3,"",{"admirei"}}, - # partiren -> part - {"iren",3}, - # partiria -> part - {"iria",3}, - # partirmo -> part - {"irmo",3}, - # partisse -> part - {"isse",3}, - # partiste -> part - {"iste",4}, - {"iava",1,"",{"ampliava"}}, - # cantamo -> cant - {"amo",2}, - # funciona -> func - {"iona",3}, - # cantara -> cant - {"ara",2,"",{"arara","prepara"}}, - # enviar谩 -> envi - {"ar谩",2,"",{"alvar谩","bacar谩"}}, - # cantare -> cant - {"are",2,"",{"prepare"}}, - # cantava -> cant - {"ava",2,"",{"agrava"}}, - # cantemo -> cant - {"emo",2}, - # bebera -> beb - {"era",1,"",{"acelera","espera"}}, - # beber谩 -> beb - {"er谩",1}, - # bebere -> beb - {"ere",1,"",{"espere"}}, - # beb铆ei -> beb - {"铆ei",1}, - # metin -> met - {"in",3}, - # partimo -> part - {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, - # partira -> part - {"ira",3,"",{"fronteira","s谩tira"}}, - {"铆do",3}, - # partir谩 -> part - {"ir谩",3}, - # concretizar -> concret - {"tizar",4,"",{"alfabetizar"}}, - {"izar",3,"",{"organizar"}}, - # saltitar -> salt - {"itar",5,"",{"acreditar","explicitar","estreitar"}}, - # partire -> part - {"ire",3,"",{"adquire"}}, - # compomo -> comp - {"omo",3}, - {"ai",2}, - # barbear -> barb - {"ear",4,"",{"alardear","nuclear"}}, - # cheguei -> cheg - {"uei",3}, - {"u铆a",5,"u"}, - # cantei -> cant - {"ei",3}, - # beber -> beb - {"er",1,"",{"茅ter","pier"}}, - # bebeu -> beb - {"eu",1,"",{"chapeu"}}, - # bebia -> beb - {"ia",1,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, - # partir -> part - {"ir",3}, - # partiu -> part - {"iu",3}, - # fraqueou -> fraqu - {"eou",5}, - # chegou -> cheg - {"ou",3}, - # bebi -> beb - {"i",1}, - # varrede -> varr - {"ede",1,"",{"rede","b铆pede","c茅spede","parede","palm铆pede","vostede","h贸spede","adrede"}}, - # cantei -> cant - {"ei",3}, - # anden -> and - {"en",2}, - # descerade -> desc - {"erade",1}, - # viv茅rade -> viv - {"茅rade",1}, - # beberan -> beb - {"eran",2}, - # colleramo -> coller - {"eramo",1}, - # beb茅ramo -> beb - {"茅ramo",1}, - # perder谩n -> perd - {"er谩n",1}, - # varrer铆a -> varr - {"er铆a",1}, - # beberiade -> beb - {"eriade",1}, - # beber铆ade -> beb - {"er铆ade",1}, - # beberiamo -> beb - {"eriamo",1}, - # beberian -> beb - {"erian",1}, - # beber铆an -> beb - {"er铆an",1}, - # perderon -> perd - {"eron",1}, - # bebese -> beb - {"ese",1}, - # bebesedes -> beb - {"esedes",1}, - # beb茅sedes -> beb - {"茅sedes",1}, - # bebesemo -> beb - {"esemo",1}, - # beb茅semo -> beb - {"茅semo",1}, - # bebesen -> beb - {"esen",1}, - # beb锚ssede -> beb - {"锚ssede",1}, - # chov铆a -> chov - {"铆a",1}, - # faciade -> fac - {"iade",1}, - # fac铆ade -> fac - {"铆ade",1}, - # perdiamo -> perd - {"iamo",1}, - # fux铆an -> fux - {"铆an",1}, - # corriche -> corr - {"iche",1}, - # partide -> part - {"ide",1}, - # escribirade -> escrib - {"irade",3}, - # par铆rade -> par - {"铆rade",3}, - # partiramo -> part - {"iramo",3}, - # fugir谩n -> fug - {"ir谩n",3}, - # vivir铆a -> viv - {"ir铆a",3}, - # partiriade -> part - {"iriade",3}, - # partir铆ade -> part - {"ir铆ade",3}, - # partiriamo -> part - {"iriamo",3}, - # partirian -> part - {"irian",3}, - # partir铆an -> part - {"ir铆an",3}, - # reflectiron -> reflect - {"iron",3}, - # partise -> part - {"ise",3}, - # partisede -> part - {"isede",3}, - # part铆sede -> part - {"铆sede",3}, - # partisemo -> part - {"isemo",3}, - # part铆semo -> part - {"铆semo",3}, - # partisen -> part - {"isen",3}, - # part铆ssede -> part - {"铆ssede",3}, - {"tizar",3,"",{"alfabetizar"}}, - {"ondo",3}}; - -{ "Vowel", 0, 0, {}, - # segue -> seg - {"gue",2,"g",{"azougue","dengue","merengue","nurague","merengue","rengue"}}, - {"que",2,"c",{"alambique","albaricoque","abaroque","alcrique","almadraque","almanaque","arenque","arinque","baduloque","ballestrinque","betoque","bivaque","bloque","bodaque","bosque","breque","buque","cacique","cheque","claque","contradique","coque","croque","dique","duque","enroque","espeque","estoque","estoraque","estraloque","estrinque","milicroque","monicreque","orinque","arinque","palenque","parque","penique","picabeque","pique","psique","raque","remolque","xeque","repenique","roque","sotobosque","tabique","tanque","toque","traque","truque","vivaque","xaque"}}, - {"a",3,"",{"amasadela","cerva"}}, - {"e",3,"",{"marte"}}, - {"o",3,"",{"barro","fado","cabo","libro","cervo"}}, - {"芒",3}, - {"茫",3,"",{"amanh茫","arapu茫","f茫","div茫","manh茫"}}, - {"锚",3}, - {"么",3}, - {"谩",3}, - {"茅",3}, - {"贸",3}, - # munxi -> munx - {"i",3}}; +# Steps file for the RSLP stemmer. + +# Step 1: Plural Reduction +{ "Plural", 3, 1, {"s"}, + # bons -> bon + {"ns",1,"n",{"luns","furatap贸ns","furatapons"}}, + # xam贸s -> xam贸n + {"贸s",3,"贸n"}, + # bal玫es -> bal贸n + {"玫es",3,"贸n"}, + # capit茫es -> capit茫o + {"茫es",1,"茫o",{"m茫es","magalh茫es"}}, + # normais -> normal + {"ais",2,"al",{"cais","tais","mais","pais","ademais"}}, + {"谩is",2,"al",{"c谩is","t谩is", "m谩is", "p谩is", "adem谩is"}}, + # pap茅is -> papel + {"茅is",2,"el"}, + # pos铆beis -> pos铆bel + {"eis",2,"el"}, + # espanh贸is -> espanhol + {"贸is",2,"ol",{"escornab贸is"}}, + # caracois -> caracol + {"ois",2,"ol",{"escornabois"}}, + # cadr铆s -> cadril + {"铆s",2,"il",{"pa铆s"}}, + # cadris -> cadril + {"is",2,"il",{"menfis","pais","kinguis"}}, + # males -> mal + {"les",2,"l",{"ingles","marselles","montreales","senegales","manizales","m贸stoles","n谩poles"}}, + # mares -> mar + {"res",3,"r",{"petres","henares","c谩ceres","baleares","linares","londres","mieres","miraflores","m茅rcores","venres", "pires"}}, + # luces -> luz + {"ces",2,"z"}, + # luzes -> luz + {"zes",2,"z"}, + # leises -> lei + {"ises",3,"z"}, + # anim谩s -> animal + {"谩s",1,"al",{"m谩s"}}, + # gases -> gas + {"ses",2,"s"}, + # casas -> casa + {"s",2,"",{"barbad茅s","barcelon茅s","canton茅s","gabon茅s","llan茅s","medin茅s","escoc茅s","escoc锚s","franc锚s","barcelon锚s","canton锚s","macram茅s","reves","barcelones","cantones","gabones","llanes","magallanes","medines","escoces","frances","xoves","martes","ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","p锚sames","cr煤cis","pa铆s","cangas","atenas","asturias","canarias","filipinas","honduras","molucas","caldas","mascare帽as","micenas","covarrubias","psoas","贸culos","nupcias","xoves","martes","llanes"}}}; + +{ "Unification", 0, 0, {}, + # cansad铆simo -> cansad铆simo + {"铆ssimo",5,"铆simo"}, + # cansad铆sima -> cansad铆sima + {"铆ssima",5,"铆sima"}, + # homa莽o -> homazo + {"a莽o",4,"azo"}, + # mulhera莽a -> mulheraza + {"a莽a",4,"aza"}, + # xentu莽a -> xentuza + {"u莽a",4,"uza"}, + # manilhar -> manillar + {"lhar",2,"llar"}, + # colher -> coller + {"lher",2,"ller"}, + # melhor -> mellor + {"lhor",2,"llor"}, + # alho -> allo + {"lho",1,"llo"}, + # linhar -> li帽ar + {"nhar",2,"帽ar"}, + # penhor -> pe帽or + {"nhor",2,"帽or"}, + # anho -> a帽o + {"nho",1,"帽o"}, + # cunha -> cu帽a + {"nha",1,"帽a"}, + # hospital谩rio -> hospitalario + {"谩rio",3,"ario"}, + # bibliotec谩ria -> bibliotecaria + {"谩ria",3,"aria"}, + # agradable -> agrad谩bel + {"able",2,"谩bel"}, + # agrad谩vele -> agrad谩bel + {"谩vel",2,"谩bel"}, + # imposible -> impos铆bel + {"ible",2,"铆bel"}, + # impos铆vel -> impos铆bel + {"铆vel",2,"铆bel"}, + # imposi莽om -> imposici贸n + {"莽om",2,"ci贸n"}, + # garagem -> garaxe + {"agem",2,"axe"}, + # garage -> garaxe + {"age",2,"axe"}, + # impress茫o -> impress贸n + {"茫o",3,"贸n"}, + # irmao -> irm谩n + {"ao",1,"谩n"}, + # irmau -> irm谩n + {"au",1,"谩n"}, + # garrafom -> garraf贸n + {"om",3,"贸n"}, + # cantem -> canten + {"m",2,"n"}}; + +{ "Adverb", 0, 0, {}, + # felizmente -> feliz + {"mente",4,"",{"experimente","vehemente","sedimente"}}}; + +{ "Augmentative", 0, 1, {}, + # cansad铆simo -> cansad + {"d铆simo",5}, + # cansad铆sima -> cansad + {"d铆sima",5}, + # amabil铆simo -> ama + {"bil铆simo",3}, + # amabil铆sima -> ama + {"bil铆sima",3}, + # fort铆simo -> fort + {"铆simo",3}, + # fort铆sima -> fort + {"铆sima",3}, + # cent茅simo -> cent + {"茅simo",3}, + # cent茅sima -> cent + {"茅sima",3}, + # paup茅rrimo -> paup + {"茅rrimo",4}, + # paup茅rrima -> paup + {"茅rrima",4}, + # charlatana -> charlat + {"ana",2,"",{"argana","banana","choupana","espadana","faciana","iguana","lantana","macana","membrana","mesana","nirvana","obsidiana","palangana","pavana","persiana","pestana","porcelana","pseudomembrana","roldana","s谩bana","salangana","saragana","ventana"}}, + # charlat谩n -> charlat + {"谩n",3,"",{"adem谩n","bard谩n","barreg谩n","corric谩n","curric谩n","fais谩n","furac谩n","fust谩n","gab谩n","gabi谩n","gal谩n","ga帽谩n","lavac谩n","maz谩n","mour谩n","rabad谩n","ser谩n","serr谩n","tab谩n","tit谩n","tobog谩n","ver谩n","volc谩n","volov谩n"}}, + # homazo -> hom + {"azo",4,"",{"abrazo","espazo","andazo","bagazo","balazo","bandazo","cachazo","carazo","denazo","engazo","famazo","lampreazo","pantocazo","pedazo","pre帽azo","regazo","ribazo","sobrazo","terrazo","trompazo"}}, + # mulleraza -> muller + {"aza",3,"",{"alcarraza","ameaza","baraza","broucaza","burgaza","cabaza","cachaza","calaza","carpaza","carraza","coiraza","colmaza","fogaza","famaza","labaza","li帽aza","melaza","mordaza","paraza","pinaza","rabaza","rapaza","trancaza"}}, + # cascallo -> casc + {"allo",4,"",{"traballo"}}, + # xentalla -> xent + {"alla",4}, + # bocarra -> boc + {"arra",3,"",{"cigarra","cinzarra"}}, + # medicastro -> medic + {"astro",3,"",{"balastro","bimbastro","canastro","retropilastro"}}, + # poetastra -> poet + {"astra",3,"",{"banastra","canastra","contrapilastra","piastra","pilastra"}}, + # corp谩zio -> corp + {"谩zio",3,"",{"top谩zio"}}, + # soutelo -> sout + {"elo",4,"",{"bacelo","barrelo","bicarelo","biquelo","boquelo","botelo","bouquelo","cacarelo","cachelo","cadrelo","campelo","candelo","cantelo","carabelo","carambelo","caramelo","cercelo","cerebelo","chocarelo","coitelo","conchelo","corbelo","cotobelo","couselo","destelo","desvelo","esf谩celo","fandelo","fardelo","farelo","farnelo","flabelo","ganchelo","garfelo","involucelo","mantelo","montelo","outerelo","padicelo","pesadelo","pinguelo","piquelo","rampelo","rastrelo","restelo","tornecelo","trabelo","restrelo","portelo","ourelo","zarapelo"}}, + # avioneta -> avion + {"eta",3,"",{"arqueta","atleta","avoceta","baioneta","baldeta","banqueta","barraganeta","barreta","borleta","buceta","caceta","calceta","caldeta","cambeta","canaleta","caneta","carreta","cerceta","chaparreta","chapeta","chareta","chincheta","colcheta","cometa","corbeta","corveta","cuneta","desteta","espeta","espoleta","estafeta","esteta","faceta","falanxeta","frasqueta","gaceta","gabeta","galleta","garabeta","gaveta","glorieta","lagareta","lambeta","lanceta","libreta","maceta","macheta","maleta","malleta","mareta","marreta","meseta","mofeta","muleta","peseta","planeta","raqueta","regreta","saqueta","veleta","vendeta","vi帽eta"}}, + # guapete -> guap + {"ete",3,"",{"alfinete","ariete","bacinete","banquete","barallete","barrete","billete","binguelete","birrete","bonete","bosquete","bufete","burlete","cabalete","cacahuete","cavinete","capacete","carrete","casarete","casete","chupete","clarinete","colchete","colete","capete","curupete","disquete","estilete","falsete","ferrete","filete","gallardete","gobelete","inglete","machete","miquelete","molete","mosquete","piquete","ribete","rodete","rolete","roquete","sorvete","vedete","vendete"}}, + # pr谩ctica -> pr谩ct + {"ica",3,"",{"andarica","bot谩nica","botica","dial茅ctica","din谩mica","f铆sica","formica","gr谩fica","marica","t煤nica"}}, + # pr谩ctico -> pr谩ct + {"ico",3,"",{"conico","acetifico","acidifico"}}, + # trapexo -> trap + {"exo",3,"",{"arpexo","arquexo","asexo","axexo","azulexo","badexo","bafexo","bocexo","bosquexo","boubexo","cacarexo","carrexo","cascarexo","castrexo","convexo","cotexo","desexo","despexo","forcexo","gabexo","gargarexo","gorgolexo","inconexo","manexo","merexo","narnexo","padexo","patexo","sopexo","varexo"}}, + {"exa",3,"",{"airexa","bandexa","carrexa","envexa","igrexa","larexa","patexa","presexa","sobexa"}}, + # multid茫o -> mult + {"id茫o",3}, + # pequeni帽o -> pequeno + {"i帽o",3,"o",{"cami帽o","cari帽o","comi帽o","golfi帽o","padri帽o","sobri帽o","vici帽o","veci帽o"}}, + # pequeni帽a -> pequena + {"i帽a",3,"a",{"camari帽a","campi帽a","entreli帽a","espi帽a","fari帽a","mori帽a","vali帽a"}}, + # grandito -> grand + {"ito",3,""}, + # grandita -> grand + {"ita",3,""}, + # anomaloide -> animal + {"oide",3,"",{"anaroide","aneroide","asteroide","axoide","cardioide","celuloide","coronoide","discoide","espermatozoide","espiroide","esquizoide","esteroide","glenoide","linfoide","hemorroide","melaloide","sacaroide","tetraploide","varioloide"}}, + # cazola -> caz + {"ola",3,"",{"aixola","ampola","argola","arola","arter铆ola","bandola","b铆tola","bract茅ola","cachola","carambola","carapola","carola","carrandiola","catrapola","cebola","centola","champola","chatola","cirola","c铆tola","consola","corola","empola","escarola","esmola","estola","fitola","flor铆cola","gara帽ola","g谩rgola","garxola","glicocola","g贸ndola","mariola","marola","michola","pirola","rebola","rup铆cola","sax铆cola","s茅mola","tachola","t贸mbola"}}, + # pedrolo -> pedr + {"olo",3,"",{"arrolo","babiolo","cacharolo","caixarolo","carolo","carramolo","cascarolo","cirolo","codrolo","correolo","cotrolo","desconsolo","rebolo","repolo","subsolo","tixolo","t贸mbolo","torolo","tr茅molo","vac煤olo","xermolo","z贸colo"}}, + # vellote -> vell + {"ote",3,"",{"aigote","alcaiote","barbarote","balote","billote","cachote","camarote","capote","cebote","chichote","citote","cocorote","escote","ga帽ote","garrote","gavote","lamote","lapote","larapote","lingote","l铆tote","magote","marrote","matalote","pandote","paparote","rebote","tagarote","zarrote"}}, + # mozota -> moz + {"ota",3,"",{"as铆ntota","caiota","cambota","chacota","compota","creosota","curota","derrota","d铆spota","gamota","maniota","pelota","picota","pillota","pixota","queirota","remota"}}, + # gordocho -> gord + {"cho",3,"",{"abrocho","arrocho","carocho","falucho","bombacho","borracho","mostacho"}}, + # gordecha -> gord + {"cha",3,"",{"borracha","carracha","estacha","garnacha","limacha","remolacha","abrocha"}}, + # baratuco -> barat + {"uco",4,"",{"caduco","estuco","fachuco","malluco","saluco","trabuco"}}, + # borrachuzo -> borrach + {"uzo",3,"",{"carri帽ouzo","fachuzo","ma帽uzo","mestruzo","tapuzo"}}, + # xentuza -> xent + {"uza",3,"",{"barruza","chamuza","chapuza","charamuza","conduza","deduza","desluza","entreluza","induza","reluza","seduza","traduza","trasluza"}}, + # babuxa -> bab + {"uxa",3,"",{"caramuxa","carrabouxa","cartuxa","coruxa","curuxa","gaturuxa","maruxa","meruxa","miruxa","moruxa","muruxa","papuxa","rabuxa","trouxa"}}, + {"uxo",3,"",{"caramuxo","carouxo","carrabouxo","curuxo","debuxo","ganduxo","influxo","negouxo","pertuxo","refluxo"}}, + # grupello -> grup + {"ello",3,"",{"alborello","artello","botello","cachafello","calello","casarello","cazabello","cercello","cocerello","concello","consello","desparello","escaravello","espello","fedello","fervello","gagafello","gorrobello","nortello","pendello","troupello","trebello"}}, + # pontella -> pont + {"ella",3,"",{"alborella","bertorella","bocatella","botella","calella","cercella","gadella","grosella","lentella","movella","nocella","noitevella","parella","pelella","percebella","segorella","sabella"}}}; + +{ "Noun", 0, 0, {}, + # lealdade -> leal + {"dade",3,"",{"acridade","calidade"}}, + # clarificar -> clar + {"ificar",2}, + # brasileiro->brasil + {"eiro",3,"",{"agoireiro","bardalleiro","braseiro","barreiro","canteiro","capoeiro","carneiro","carteiro","cinceiro","faroleiro","mareiro","preguiceiro","quinteiro","raposeiro","retranqueiro","regueiro","sineiro","troleiro","ventureiro"}}, + # marisqueira -> marisqu + {"eira",3,"",{"cabeleira","canteira","cocheira","folleira","milleira"}}, + # hospitalario -> hospital + {"ario",3,"",{"armario","calcario","lionario","salario"}}, + # bibliotecaria -> bibliotec + {"aria",3,"",{"cetaria","coronaria","fumaria","linaria","lunaria","parietaria","saponaria","serpentaria"}}, + # humor铆stico -> humor + {"铆stico",3,"",{"bal铆stico", "ensa铆stico"}}, + # castrista -> castr + {"ista",3,"",{"batista","ciclista","fadista","operista","tenista","verista"}}, + # lavado -> lav + {"ado",2,"",{"grado","agrado"}}, + # decanato -> decan + {"ato",2,"",{"agnato"}}, + # xemido -> xem + {"ido",3,"",{"c谩ndido","c芒ndido","consolido","decidido","duvido","marido","r谩pido"}}, + # mantida -> mant + {"ida",3,"",{"bastida","d煤bida","dubida","duvida","ermida","茅xida","guarida","lapicida","medida","morida"}}, + {"铆da",3}, + # mant铆do -> mant + {"ido",3}, + # orelludo -> orell + {"udo",3,"",{"estudo","escudo"}}, + # orelluda -> orell + {"uda",3}, + {"ada",3,"",{"abada","alhada","allada","pitada"}}, + # comedela -> come + {"dela",3,"",{"cambadela","cavadela","forcadela","erisipidela","mortadela","espadela","fondedela","picadela","arandela","candela","cordela","escudela","pardela"}}, + # fontela -> font + {"ela",3,"",{"canela","capela","cotela","cubela","curupela","escarapela","esparrela","estela","fardela","flanela","fornela","franela","gabela","gamela","gavela","glumela","granicela","lamela","lapela","malvela","manela","manganela","mexarela","micela","mistela","novela","ourela","panela","parcela","pasarela","patamela","patela","paxarela","pipela","pitela","postela","pubela","restela","sabela","salmonela","secuela","sentinela","soldanela","subela","temoncela","tesela","tixela","tramela","trapela","varela","vitela","xanela","xestela"}}, + # agrad谩bel -> agrad + {"谩bel",2,"",{"af谩bel","fi谩bel"}}, + # combust铆bel -> combust + {"铆bel",2,"",{"cr铆bel","impos铆bel","pos铆bel","fis铆bel","fal铆bel"}}, + # fabricante -> frabrica + {"nte",3,"",{"alimente","adiante","acrescente","elefante","frequente","freq眉ente","gigante","instante","oriente","permanente","posante","possante","restaurante"}}, + # ignorancia -> ignora + {"ncia",3}, + # temperanza -> tempera + {"nza",3}, + {"acia",3,"",{"acracia","audacia","falacia","farmacia"}}, + # inmundicia -> inmund + {"icia",3,"",{"caricia","delicia","ledicia","malicia","milicia","noticia","pericia","presbicia","primicia","regalicia","sevicia","tiricia"}}, + # xustiza -> xust + {"iza",3,"",{"alvariza","baliza","cachiza","caniza","ca帽iza","carbaliza","carriza","chamariza","chapiza","fraguiza","latiza","longaniza","ma帽iza","nabiza","peliza","preguiza","rabiza"}}, + # clarexar -> clar + {"exar",3,"",{"palmexar"}}, + # administraci贸n -> administr + {"aci贸n",2,"",{"aeraci贸n"}}, + # expedici贸n -> exped + {"ici贸n",3,"",{"condici贸n","gornici贸n","monici贸n","nutrici贸n","petici贸n","posici贸n","sedici贸n","volici贸n"}}, + # excepci贸n -> except + {"ci贸n",3,"t"}, + # comprensi贸n -> comprens + {"si贸n",3,"s",{"abrasi贸n", "alusi贸n"}}, + # doaz贸n -> do + {"az贸n",2,"",{"armaz贸n"}}, + # garraf贸n -> garraf + {"贸n",3,"",{"abal贸n","acorde贸n","alci贸n","aldrab贸n","aler贸n","ali帽贸n","amb贸n","bomb贸n","calz贸n","camp贸n","canal贸n","cant贸n","capit贸n","ca帽贸n","cent贸n","cicl贸n","coll贸n","colof贸n","cop贸n","cot贸n","cup贸n","pet贸n","tir贸n","tour贸n","tur贸n","unci贸n","versi贸n","zub贸n","zurr贸n"}}, + # lambona -> lamb + {"ona",3,"",{"abandona","acetona","aleurona","amazona","an茅mona","bombona","cambona","carona","chacona","charamona","cincona","condona","cortisona","cretona","cretona","detona","estona","fitohormona","fregona","gerona","hidroquinona","hormona","lesiona","madona","maratona","matrona","metadona","mon贸tona","neurona","pamplona","peptona","poltrona","proxesterona","quinona","quinona","silicona","sulfona"}}, + # bretoa -> bret贸n + {"oa",3,"",{"abandoa","madroa","barbacoa","estoa","airoa","eiroa","amalloa","谩mboa","am茅ndoa","anchoa","antin茅boa","av茅ntoa","avoa","b谩goa","balboa","bisavoa","boroa","canoa","caroa","comadroa","coroa","茅ngoa","esp谩coa","filloa","f铆rgoa","gra帽oa","lagoa","lanzoa","magoa","m谩moa","morzoa","noiteboa","noraboa","para帽oa","persoa","queiroa","ra帽oa","t谩boa","tataravoa","teiroa"}}, + # demon铆aco -> demon铆 + {"aco",3}, + # demon铆aca -> demon铆 + {"aca",3,"",{"alpaca","barraca","bullaca","buraca","carraca","casaca","cavaca","cloaca","entresaca","ervellaca","espinaca","estaca","farraca","millaca","pastinaca","pataca","resaca","urraca","purraca"}}, + # carballal -> carball + {"al",4,"",{"afinal","animal","estatal","bisexual","bissexual","desleal","fiscal","formal","pessoal","persoal","liberal","postal","virtual","visual","pontual","puntual","homosexual","heterosexual"}}, + # nadador -> nada + {"dor",2,"",{"abaixador"}}, + # benfeitor -> benfei + {"tor",3,"",{"autor","motor","pastor","pintor"}}, + # produtor -> produt + {"or",2,"",{"asesor","assessor","favor","mellor","melhor","redor","rigor","sensor","tambor","tumor"}}, + # profesora -> profes + {"ora",3,"",{"albacora","an谩fora","谩ncora","apisoadora","ardora","ascospora","aurora","av茅spora","bit谩cora","can茅fora","cantimplora","cat谩fora","cepilladora","demora","descalcificadora","di谩spora","empacadora","ep铆fora","ecavadora","escora","eslora","espora","fotocompo帽edora","fotocopiadora","grampadora","is铆cora","lavadora","lixadora","macrospora","madr茅pora","madr谩gora","masora","mellora","met谩fora","microspora","mil茅pora","milp茅ndora","n茅cora","oospora","padeadora","pasiflora","p茅cora","p铆ldora","p贸lvora","ratinadora","r茅mora","retroescavadora","s贸fora","torradora","tr茅mbora","uredospora","v铆bora","v铆ncora","zoospora"}}, + # zapatar铆a -> zapat + {"ar铆a",3,"",{"librar铆a"}}, + # etiquetaxe -> etiquet + {"axe",3,"",{"aluaxe","amaraxe","amperaxe","bagaxe","balaxe","barcaxe","borraxe","bescaxe","cabotaxe","carraxe","cartilaxe","chantaxe","colaxe","coraxe","carruaxe","dragaxe","embalaxe","ensilaxe","epistaxe","fagundaxe","fichaxe","fogaxe","forraxe","fretaxe","friaxe","garaxe","homenaxe","leitaxe","li帽axe","listaxe","maraxe","marcaxe","maridaxe","masaxe","miraxe","montaxe","pasaxe","peaxe","portaxe","ramaxe","rebelaxe","rodaxe","romaxe","sintaxe","sondaxe","tiraxe","vantaxe","vendaxe","viraxe"}}, + # movedizo -> move + {"dizo",3}, + # limpeza -> limp + {"eza",3,"",{"alteza","beleza","fereza","fineza","vasteza","vileza"}}, + # rixidez -> rixid + {"ez",3,"",{"acidez","adultez","adustez","avidez","candidez","mudez","nenez","nudez","pomez"}}, + # mullerengo -> muller + {"engo",3}, + # chairego -> chair + {"ego",3,"",{"corego","derrego","entrego","lamego","sarego","sartego"}}, + # cari帽oso -> cari帽 + {"oso",3,"",{"afanoso","algoso","caldoso","caloso","cocoso","ditoso","favoso","fogoso","lamoso","mecoso","mocoso","precioso","rixoso","venoso","viroso","xesoso"}}, + # cari帽osa -> cari帽 + {"osa",3,"",{"mucosa","glicosa","baldosa","celulosa","isoglosa","nitrocelulosa","levulosa","ortosa","pectosa","preciosa","sacarosa","serosa","ventosa"}}, + # negrume -> negr + {"ume",3,"",{"agrume","albume","alcume","batume","cacume","cerrume","chorume","churume","costume","curtume","estrume","gafume","legume","perfume","queixume","zarrume"}}, + # altura -> alt + {"ura",3,"",{"albura","armadura","imatura","costura"}}, + # cuspi帽ar -> cusp + {"i帽ar",3}, + # febril -> febr + {"il",3,"",{"abril","alfil","anil","atril","badil","baril","barril","brasil","cadril","candil","cantil","carril","chamil","chancil","civil","cubil","d谩til","dif铆cil","d贸cil","edil","est茅ril","f谩cil","fr谩xil","funil","fusil","gr谩cil","gradil","h谩bil","hostil","marfil"}}, + # principesco -> princip + {"esco",4}, + # mourisco -> mour + {"isco",4}, + # esportivo -> esport + {"ivo",3,"",{"pasivo","positivo","passivo","possessivo","posesivo","pexotarivo","relativo"}}}; + +{ "Verb", 0, 0, {}, + # amaba -> am + {"aba",2}, + # andabade -> and + {"abade",2}, + # and谩bade -> and + {"谩bade",2}, + # chorabamo -> chor + {"abamo",2}, + # chor谩bamo -> chor + {"谩bamo",2}, + # moraban -> morab + {"aban",2}, + # andache -> and + {"ache",2}, + # andade -> and + {"ade",2}, + {"an",2}, + # cantando -> cant + {"ando",2}, + # cantar -> cant + {"ar",2,"",{"azar","bazar","patamar"}}, + # lembrarade -> lembra + {"arade",2}, + {"aramo",2}, + {"ar谩n",2}, + # cantaran -> cant + {"aran",2}, + # convid谩rade -> convid + {"谩rade",2}, + # convidar铆a -> convid + {"ar铆a",2}, + # cantariade -> cant + {"ariade",2}, + # cantar铆ade -> cant + {"ar铆ade",2}, + # cantarian -> cant + {"arian",2}, + # cantariamo -> cant + {"ariamo",2}, + # pescaron -> pesc + {"aron",2}, + # cantase -> cant + {"ase",2}, + # cantasede -> cant + {"asede",2}, + # cant谩sede -> cant + {"谩sede",2}, + # cantasemo -> cant + {"asemo",2}, + # cant谩semo -> cant + {"谩semo",2}, + # cantasen -> cant + {"asen",2}, + # loitavan -> loitav + {"avan",2}, + # cantar铆amo -> cant + {"ar铆amo",2}, + # cantassen -> cant + {"assen",2}, + # cant谩ssemo -> cant + {"谩ssemo",2}, + # beber铆amo -> beb + {"er铆amo",2}, + # beb锚ssemo -> beb + {"锚ssemo",2}, + # partir铆amo -> part + {"ir铆amo",3}, + # part铆ssemo -> part + {"铆ssemo",3}, + # cant谩ramo -> cant + {"谩ramo",2}, + # cant谩rei -> cant + {"谩rei",2}, + # cantaren -> cant + {"aren",2}, + # cantaremo -> cant + {"aremo",2}, + # cantar铆ei -> cant + {"ar铆ei",2}, + {"谩ssei",2}, + # cant谩vamo-> cant + {"谩vamo",2}, + # beb锚ramo -> beb + {"锚ramo",1}, + # beberemo -> beb + {"eremo",1}, + # beber铆ei -> beb + {"er铆ei",1}, + # beb锚ssei -> beb + {"锚ssei",1}, + # partir铆amo -> part + {"铆ramo",3}, + # partiremo -> part + {"iremo",3}, + # partir铆ei -> part + {"ir铆ei",3}, + # part铆ssei -> part + {"铆ssei",3}, + # partissen -> part + {"issen",3}, + # bebendo -> beb + {"endo",1}, + # partindo -> part + {"indo",3}, + # propondo -> prop + {"ondo",3}, + # cantarde -> cant + {"arde",2}, + # cantarei -> cant + {"arei",2}, + # cantaria -> cant + {"aria",2}, + # cantarmo -> cant + {"armo",2}, + # cantasse -> cant + {"asse",2}, + {"aste",2}, + # cant谩vei -> cant + {"谩vei",2}, + # perder茫o -> perd + {"er茫o",1}, + # beberde -> beb + {"erde",1}, + # beberei -> beb + {"erei",1}, + # beb锚rei -> beb + {"锚rei",1}, + # beberen -> beb + {"eren",2}, + # beberia -> beb + {"eria",1}, + # bebermo -> beb + {"ermo",1}, + # bebeste -> beb + {"este",1,"",{"faroeste","agreste"}}, + # beb铆amo -> beb + {"铆amo",1}, + # fuxian -> fux + {"ian",2,"",{"enfian","eloxian","ensaian"}}, + # partirde -> part + {"irde",2}, + # part铆rei -> part + {"irei",3,"",{"admirei"}}, + # partiren -> part + {"iren",3}, + # partiria -> part + {"iria",3}, + # partirmo -> part + {"irmo",3}, + # partisse -> part + {"isse",3}, + # partiste -> part + {"iste",4}, + {"iava",1,"",{"ampliava"}}, + # cantamo -> cant + {"amo",2}, + # funciona -> func + {"iona",3}, + # cantara -> cant + {"ara",2,"",{"arara","prepara"}}, + # enviar谩 -> envi + {"ar谩",2,"",{"alvar谩","bacar谩"}}, + # cantare -> cant + {"are",2,"",{"prepare"}}, + # cantava -> cant + {"ava",2,"",{"agrava"}}, + # cantemo -> cant + {"emo",2}, + # bebera -> beb + {"era",1,"",{"acelera","espera"}}, + # beber谩 -> beb + {"er谩",1}, + # bebere -> beb + {"ere",1,"",{"espere"}}, + # beb铆ei -> beb + {"铆ei",1}, + # metin -> met + {"in",3}, + # partimo -> part + {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, + # partira -> part + {"ira",3,"",{"fronteira","s谩tira"}}, + {"铆do",3}, + # partir谩 -> part + {"ir谩",3}, + # concretizar -> concret + {"tizar",4,"",{"alfabetizar"}}, + {"izar",3,"",{"organizar"}}, + # saltitar -> salt + {"itar",5,"",{"acreditar","explicitar","estreitar"}}, + # partire -> part + {"ire",3,"",{"adquire"}}, + # compomo -> comp + {"omo",3}, + {"ai",2}, + # barbear -> barb + {"ear",4,"",{"alardear","nuclear"}}, + # cheguei -> cheg + {"uei",3}, + {"u铆a",5,"u"}, + # cantei -> cant + {"ei",3}, + # beber -> beb + {"er",1,"",{"茅ter","pier"}}, + # bebeu -> beb + {"eu",1,"",{"chapeu"}}, + # bebia -> beb + {"ia",1,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, + # partir -> part + {"ir",3}, + # partiu -> part + {"iu",3}, + # fraqueou -> fraqu + {"eou",5}, + # chegou -> cheg + {"ou",3}, + # bebi -> beb + {"i",1}, + # varrede -> varr + {"ede",1,"",{"rede","b铆pede","c茅spede","parede","palm铆pede","vostede","h贸spede","adrede"}}, + # cantei -> cant + {"ei",3}, + # anden -> and + {"en",2}, + # descerade -> desc + {"erade",1}, + # viv茅rade -> viv + {"茅rade",1}, + # beberan -> beb + {"eran",2}, + # colleramo -> coller + {"eramo",1}, + # beb茅ramo -> beb + {"茅ramo",1}, + # perder谩n -> perd + {"er谩n",1}, + # varrer铆a -> varr + {"er铆a",1}, + # beberiade -> beb + {"eriade",1}, + # beber铆ade -> beb + {"er铆ade",1}, + # beberiamo -> beb + {"eriamo",1}, + # beberian -> beb + {"erian",1}, + # beber铆an -> beb + {"er铆an",1}, + # perderon -> perd + {"eron",1}, + # bebese -> beb + {"ese",1}, + # bebesedes -> beb + {"esedes",1}, + # beb茅sedes -> beb + {"茅sedes",1}, + # bebesemo -> beb + {"esemo",1}, + # beb茅semo -> beb + {"茅semo",1}, + # bebesen -> beb + {"esen",1}, + # beb锚ssede -> beb + {"锚ssede",1}, + # chov铆a -> chov + {"铆a",1}, + # faciade -> fac + {"iade",1}, + # fac铆ade -> fac + {"铆ade",1}, + # perdiamo -> perd + {"iamo",1}, + # fux铆an -> fux + {"铆an",1}, + # corriche -> corr + {"iche",1}, + # partide -> part + {"ide",1}, + # escribirade -> escrib + {"irade",3}, + # par铆rade -> par + {"铆rade",3}, + # partiramo -> part + {"iramo",3}, + # fugir谩n -> fug + {"ir谩n",3}, + # vivir铆a -> viv + {"ir铆a",3}, + # partiriade -> part + {"iriade",3}, + # partir铆ade -> part + {"ir铆ade",3}, + # partiriamo -> part + {"iriamo",3}, + # partirian -> part + {"irian",3}, + # partir铆an -> part + {"ir铆an",3}, + # reflectiron -> reflect + {"iron",3}, + # partise -> part + {"ise",3}, + # partisede -> part + {"isede",3}, + # part铆sede -> part + {"铆sede",3}, + # partisemo -> part + {"isemo",3}, + # part铆semo -> part + {"铆semo",3}, + # partisen -> part + {"isen",3}, + # part铆ssede -> part + {"铆ssede",3}, + {"tizar",3,"",{"alfabetizar"}}, + {"ondo",3}}; + +{ "Vowel", 0, 0, {}, + # segue -> seg + {"gue",2,"g",{"azougue","dengue","merengue","nurague","merengue","rengue"}}, + {"que",2,"c",{"alambique","albaricoque","abaroque","alcrique","almadraque","almanaque","arenque","arinque","baduloque","ballestrinque","betoque","bivaque","bloque","bodaque","bosque","breque","buque","cacique","cheque","claque","contradique","coque","croque","dique","duque","enroque","espeque","estoque","estoraque","estraloque","estrinque","milicroque","monicreque","orinque","arinque","palenque","parque","penique","picabeque","pique","psique","raque","remolque","xeque","repenique","roque","sotobosque","tabique","tanque","toque","traque","truque","vivaque","xaque"}}, + {"a",3,"",{"amasadela","cerva"}}, + {"e",3,"",{"marte"}}, + {"o",3,"",{"barro","fado","cabo","libro","cervo"}}, + {"芒",3}, + {"茫",3,"",{"amanh茫","arapu茫","f茫","div茫","manh茫"}}, + {"锚",3}, + {"么",3}, + {"谩",3}, + {"茅",3}, + {"贸",3}, + # munxi -> munx + {"i",3}}; diff --git a/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp b/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp index 1cca5f5c1d3..24de0653803 100644 --- a/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp +++ b/modules/analysis/common/src/resources/org/apache/lucene/analysis/pt/portuguese.rslp @@ -1,456 +1,456 @@ -# Steps file for the RSLP stemmer. - -# Step 1: Plural Reduction -{ "Plural", 3, 1, {"s"}, - # bons -> bom - {"ns",1,"m"}, - # bal玫es -> bal茫o - {"玫es",3,"茫o"}, - # capit茫es -> capit茫o - {"茫es",1,"茫o",{"m茫es"}}, - # normais -> normal - {"ais",1,"al",{"cais","mais"}}, - # pap茅is -> papel - {"茅is",2,"el"}, - # am谩veis -> am谩vel - {"eis",2,"el"}, - # len莽贸is -> len莽ol - {"贸is",2,"ol"}, - # barris -> barril - {"is",2,"il",{"l谩pis","cais","mais","cr煤cis","biqu铆nis","pois","depois","dois","leis"}}, - # males -> mal - {"les",3,"l"}, - # mares -> mar - {"res",3,"r", {"谩rvores"}}, - # casas -> casa - {"s",2,"",{"ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","fezes","p锚sames","cr煤cis","g谩s","atr谩s","mois茅s","atrav茅s","conv茅s","锚s","pa铆s","ap贸s","ambas","ambos","messias", "depois"}}}; - -# Step 2: Adverb Reduction -{ "Adverb", 0, 0, {}, - # felizmente -> feliz - {"mente",4,"",{"experimente"}}}; - -# Step 3: Feminine Reduction -{ "Feminine", 3, 1, {"a","茫"}, - # chefona -> chef茫o - {"ona",3,"茫o",{"abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","carona"}}, - # vil茫 -> vil茫o - {"茫",2,"茫o",{"amanh茫","arapu茫","f茫","div茫"}}, - # professora -> professor - {"ora",3,"or"}, - # americana -> americano - {"na",4,"no",{"carona","abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","guiana","campana","grana","caravana","banana","paisana"}}, - # sozinha -> sozinho - {"inha",3,"inho",{"rainha","linha","minha"}}, - # inglesa -> ingl锚s - {"esa",3,"锚s",{"mesa","obesa","princesa","turquesa","ilesa","pesa","presa"}}, - # famosa -> famoso - {"osa",3,"oso",{"mucosa","prosa"}}, - # man铆aca -> man铆aco - {"铆aca",3,"铆aco"}, - # pr谩tica -> pr谩tico - {"ica",3,"ico",{"dica"}}, - # cansada -> cansado - {"ada",2,"ado",{"pitada"}}, - # mantida -> mantido - {"ida",3,"ido",{"vida","d煤vida"}}, - {"铆da",3,"ido",{"reca铆da","sa铆da"}}, - # prima -> primo - {"ima",3,"imo",{"v铆tima"}}, - # passiva -> passivo - {"iva",3,"ivo",{"saliva","oliva"}}, - # primeira -> primeiro - {"eira",3,"eiro",{"beira","cadeira","frigideira","bandeira","feira","capoeira","barreira","fronteira","besteira","poeira"}}}; - -# Step 4: Augmentative/Diminutive Reduction -{ "Augmentative", 0, 1, {}, - # cansad铆ssimo -> cansad - {"d铆ssimo",5}, - # amabil铆ssimo -> ama - {"abil铆ssimo",5}, - # fort铆ssimo -> fort - {"铆ssimo",3}, - {"茅simo",3}, - # chiqu茅rrimo -> chiqu - {"茅rrimo",4}, - # pezinho -> pe - {"zinho",2}, - # maluquinho -> maluc - {"quinho",4,"c"}, - # amiguinho -> amig - {"uinho",4}, - # cansadinho -> cansad - {"adinho",3}, - # carrinho -> carr - {"inho",3,"",{"caminho","cominho"}}, - # grandalh茫o -> grand - {"alh茫o",4}, - # dentu莽a -> dent - {"u莽a",4}, - # rica莽o -> ric - {"a莽o",4,"",{"antebra莽o"}}, - {"a莽a",4}, - # casad茫o -> cans - {"ad茫o",4}, - {"id茫o",4}, - # corp谩zio -> corp - {"谩zio",3,"",{"top谩zio"}}, - # pratarraz -> prat - {"arraz",4}, - {"zarr茫o",3}, - {"arr茫o",4}, - # bocarra -> boc - {"arra",3}, - # calorz茫o -> calor - {"z茫o",2,"",{"coaliz茫o"}}, - # menin茫o -> menin - {"茫o",3,"",{"camar茫o","chimarr茫o","can莽茫o","cora莽茫o","embri茫o","grot茫o","glut茫o","fic莽茫o","fog茫o","fei莽茫o","furac茫o","gam茫o","lampi茫o","le茫o","macac茫o","na莽茫o","贸rf茫o","org茫o","patr茫o","port茫o","quinh茫o","rinc茫o","tra莽茫o","falc茫o","espi茫o","mam茫o","foli茫o","cord茫o","aptid茫o","campe茫o","colch茫o","lim茫o","leil茫o","mel茫o","bar茫o","milh茫o","bilh茫o","fus茫o","crist茫o","ilus茫o","capit茫o","esta莽茫o","sen茫o"}}}; - -# Step 5: Noun Suffix Reduction -{ "Noun", 0, 0, {}, - # existencialista -> exist - {"encialista",4}, - # minimalista -> minim - {"alista",5}, - # contagem -> cont - {"agem",3,"",{"coragem","chantagem","vantagem","carruagem"}}, - # gerenciamento -> gerenc - {"iamento",4}, - # monitoramento -> monitor - {"amento",3,"",{"firmamento","fundamento","departamento"}}, - # nascimento -> nasc - {"imento",3}, - {"mento",6,"",{"firmamento","elemento","complemento","instrumento","departamento"}}, - # comercializado -> comerci - {"alizado",4}, - # traumatizado -> traum - {"atizado",4}, - {"tizado",4,"",{"alfabetizado"}}, - # alfabetizado -> alfabet - {"izado",5,"",{"organizado","pulverizado"}}, - # associativo -> associ - {"ativo",4,"",{"pejorativo","relativo"}}, - # contraceptivo -> contracep - {"tivo",4,"",{"relativo"}}, - # esportivo -> esport - {"ivo",4,"",{"passivo","possessivo","pejorativo","positivo"}}, - # abalado -> abal - {"ado",2,"",{"grado"}}, - # impedido -> imped - {"ido",3,"",{"c芒ndido","consolido","r谩pido","decido","t铆mido","duvido","marido"}}, - # ralador -> ral - {"ador",3}, - # entendedor -> entend - {"edor",3}, - # cumpridor -> cumpr - {"idor",4,"",{"ouvidor"}}, - {"dor",4,"",{"ouvidor"}}, - {"sor",4,"",{"assessor"}}, - {"atoria",5}, - {"tor",3,"",{"benfeitor","leitor","editor","pastor","produtor","promotor","consultor"}}, - {"or",2,"",{"motor","melhor","redor","rigor","sensor","tambor","tumor","assessor","benfeitor","pastor","terior","favor","autor"}}, - # comparabilidade -> compar - {"abilidade",5}, - # abolicionista -> abol - {"icionista",4}, - # intervencionista -> interven - {"cionista",5}, - {"ionista",5}, - {"ionar",5}, - # profissional -> profiss - {"ional",4}, - # refer锚ncia -> refer - {"锚ncia",3}, - # repugn芒ncia -> repugn - {"芒ncia",4,"",{"ambul芒ncia"}}, - # abatedouro -> abat - {"edouro",3}, - # fofoqueiro -> fofoc - {"queiro",3,"c"}, - {"adeiro",4,"",{"desfiladeiro"}}, - # brasileiro -> brasil - {"eiro",3,"",{"desfiladeiro","pioneiro","mosteiro"}}, - {"uoso",3}, - # gostoso -> gost - {"oso",3,"",{"precioso"}}, - # comercializa莽 -> comerci - {"aliza莽",5}, - {"atiza莽",5}, - {"tiza莽",5}, - {"iza莽",5,"",{"organiza莽"}}, - # alega莽 -> aleg - {"a莽",3,"",{"equa莽","rela莽"}}, - # aboli莽 -> abol - {"i莽",3,"",{"elei莽"}}, - # anedot谩rio -> anedot - {"谩rio",3,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","lion谩rio","arm谩rio"}}, - {"at贸rio",3}, - {"rio",5,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","compuls贸rio","lion谩rio","pr贸prio","st茅rio","arm谩rio"}}, - # minist茅rio -> minist - {"茅rio",6}, - # chin锚s -> chin - {"锚s",4}, - # beleza -> bel - {"eza",3}, - # rigidez -> rigid - {"ez",4}, - # parentesco -> parent - {"esco",4}, - # ocupante -> ocup - {"ante",2,"",{"gigante","elefante","adiante","possante","instante","restaurante"}}, - # bomb谩stico -> bomb - {"谩stico",4,"",{"eclesi谩stico"}}, - {"al铆stico",3}, - {"谩utico",4}, - {"锚utico",4}, - {"tico",3,"",{"pol铆tico","eclesi谩stico","diagnostico","pr谩tico","dom茅stico","diagn贸stico","id锚ntico","alop谩tico","art铆stico","aut锚ntico","ecl茅tico","cr铆tico","critico"}}, - # pol锚mico -> pol锚m - {"ico",4,"",{"tico","p煤blico","explico"}}, - # produtividade -> produt - {"ividade",5}, - # profundidade -> profund - {"idade",4,"",{"autoridade","comunidade"}}, - # aposentadoria -> aposentad - {"oria",4,"",{"categoria"}}, - # existencial -> exist - {"encial",5}, - # artista -> art - {"ista",4}, - {"auta",5}, - # maluquice -> maluc - {"quice",4,"c"}, - # chatice -> chat - {"ice",4,"",{"c煤mplice"}}, - # demon铆aco -> demon - {"铆aco",3}, - # decorrente -> decorr - {"ente",4,"",{"freq眉ente","alimente","acrescente","permanente","oriente","aparente"}}, - {"ense",5}, - # criminal -> crim - {"inal",3}, - # americano -> americ - {"ano",4}, - # am谩vel -> am - {"谩vel",2,"",{"af谩vel","razo谩vel","pot谩vel","vulner谩vel"}}, - # combust铆vel -> combust - {"铆vel",3,"",{"poss铆vel"}}, - {"vel",5,"",{"poss铆vel","vulner谩vel","sol煤vel"}}, - {"bil",3,"vel"}, - # cobertura -> cobert - {"ura",4,"",{"imatura","acupuntura","costura"}}, - {"ural",4}, - # consensual -> consens - {"ual",3,"",{"bissexual","virtual","visual","pontual"}}, - # mundial -> mund - {"ial",3}, - # experimental -> experiment - {"al",4,"",{"afinal","animal","estatal","bissexual","desleal","fiscal","formal","pessoal","liberal","postal","virtual","visual","pontual","sideral","sucursal"}}, - {"alismo",4}, - {"ivismo",4}, - {"ismo",3,"",{"cinismo"}}}; - -# Step 6: Verb Suffix Reduction -{ "Verb", 0, 0, {}, - # cantar铆amo -> cant - {"ar铆amo",2}, - # cant谩ssemo -> cant - {"谩ssemo",2}, - # beber铆amo -> beb - {"er铆amo",2}, - # beb锚ssemo -> beb - {"锚ssemo",2}, - # partir铆amo -> part - {"ir铆amo",3}, - # part铆ssemo -> part - {"铆ssemo",3}, - # cant谩ramo -> cant - {"谩ramo",2}, - # cant谩rei -> cant - {"谩rei",2}, - # cantaremo -> cant - {"aremo",2}, - # cantariam -> cant - {"ariam",2}, - # cantar铆ei -> cant - {"ar铆ei",2}, - # cant谩ssei -> cant - {"谩ssei",2}, - # cantassem -> cant - {"assem",2}, - # cant谩vamo -> cant - {"谩vamo",2}, - # beb锚ramo -> beb - {"锚ramo",3}, - # beberemo -> beb - {"eremo",3}, - # beberiam -> beb - {"eriam",3}, - # beber铆ei -> beb - {"er铆ei",3}, - # beb锚ssei -> beb - {"锚ssei",3}, - # bebessem -> beb - {"essem",3}, - # partir铆amo -> part - {"铆ramo",3}, - # partiremo -> part - {"iremo",3}, - # partiriam -> part - {"iriam",3}, - # partir铆ei -> part - {"ir铆ei",3}, - # part铆ssei -> part - {"铆ssei",3}, - # partissem -> part - {"issem",3}, - # cantando -> cant - {"ando",2}, - # bebendo -> beb - {"endo",3}, - # partindo -> part - {"indo",3}, - # propondo -> prop - {"ondo",3}, - # cantaram -> cant - {"aram",2}, - {"ar茫o",2}, - # cantarde -> cant - {"arde",2}, - # cantarei -> cant - {"arei",2}, - # cantarem -> cant - {"arem",2}, - # cantaria -> cant - {"aria",2}, - # cantarmo -> cant - {"armo",2}, - # cantasse -> cant - {"asse",2}, - # cantaste -> cant - {"aste",2}, - # cantavam -> cant - {"avam",2,"",{"agravam"}}, - # cant谩vei -> cant - {"谩vei",2}, - # beberam -> beb - {"eram",3}, - {"er茫o",3}, - # beberde -> beb - {"erde",3}, - # beberei -> beb - {"erei",3}, - # beb锚rei -> beb - {"锚rei",3}, - # beberem -> beb - {"erem",3}, - # beberia -> beb - {"eria",3}, - # bebermo -> beb - {"ermo",3}, - # bebesse -> beb - {"esse",3}, - # bebeste -> beb - {"este",3,"",{"faroeste","agreste"}}, - # beb铆amo -> beb - {"铆amo",3}, - # partiram -> part - {"iram",3}, - # conclu铆ram -> conclu - {"铆ram",3}, - {"ir茫o",2}, - # partirde -> part - {"irde",2}, - # part铆rei -> part - {"irei",3,"",{"admirei"}}, - # partirem -> part - {"irem",3,"",{"adquirem"}}, - # partiria -> part - {"iria",3}, - # partirmo -> part - {"irmo",3}, - # partisse -> part - {"isse",3}, - # partiste -> part - {"iste",4}, - {"iava",4,"",{"ampliava"}}, - # cantamo -> cant - {"amo",2}, - {"iona",3}, - # cantara -> cant - {"ara",2,"",{"arara","prepara"}}, - # cantar谩 -> cant - {"ar谩",2,"",{"alvar谩"}}, - # cantare -> cant - {"are",2,"",{"prepare"}}, - # cantava -> cant - {"ava",2,"",{"agrava"}}, - # cantemo -> cant - {"emo",2}, - # bebera -> beb - {"era",3,"",{"acelera","espera"}}, - # beber谩 -> beb - {"er谩",3}, - # bebere -> beb - {"ere",3,"",{"espere"}}, - # bebiam -> beb - {"iam",3,"",{"enfiam","ampliam","elogiam","ensaiam"}}, - # beb铆ei -> beb - {"铆ei",3}, - # partimo -> part - {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, - # partira -> part - {"ira",3,"",{"fronteira","s谩tira"}}, - {"铆do",3}, - # partir谩 -> part - {"ir谩",3}, - {"tizar",4,"",{"alfabetizar"}}, - {"izar",5,"",{"organizar"}}, - {"itar",5,"",{"acreditar","explicitar","estreitar"}}, - # partire -> part - {"ire",3,"",{"adquire"}}, - # compomo -> comp - {"omo",3}, - # cantai -> cant - {"ai",2}, - # cantam -> cant - {"am",2}, - # barbear -> barb - {"ear",4,"",{"alardear","nuclear"}}, - # cantar -> cant - {"ar",2,"",{"azar","bazaar","patamar"}}, - # cheguei -> cheg - {"uei",3}, - {"u铆a",5,"u"}, - # cantei -> cant - {"ei",3}, - {"guem",3,"g"}, - # cantem -> cant - {"em",2,"",{"alem","virgem"}}, - # beber -> beb - {"er",2,"",{"茅ter","pier"}}, - # bebeu -> beb - {"eu",3,"",{"chapeu"}}, - # bebia -> beb - {"ia",3,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, - # partir -> part - {"ir",3,"",{"freir"}}, - # partiu -> part - {"iu",3}, - {"eou",5}, - # chegou -> cheg - {"ou",3}, - # bebi -> beb - {"i",3}}; - -# Step 7: Vowel Removal -{ "Vowel", 0, 0, {}, - {"bil",2,"vel"}, - {"gue",2,"g",{"gangue","jegue"}}, - {"谩",3}, - {"锚",3,"",{"beb锚"}}, - # menina -> menin - {"a",3,"",{"谩sia"}}, - # grande -> grand - {"e",3}, - # menino -> menin - {"o",3,"",{"茫o"}}}; +# Steps file for the RSLP stemmer. + +# Step 1: Plural Reduction +{ "Plural", 3, 1, {"s"}, + # bons -> bom + {"ns",1,"m"}, + # bal玫es -> bal茫o + {"玫es",3,"茫o"}, + # capit茫es -> capit茫o + {"茫es",1,"茫o",{"m茫es"}}, + # normais -> normal + {"ais",1,"al",{"cais","mais"}}, + # pap茅is -> papel + {"茅is",2,"el"}, + # am谩veis -> am谩vel + {"eis",2,"el"}, + # len莽贸is -> len莽ol + {"贸is",2,"ol"}, + # barris -> barril + {"is",2,"il",{"l谩pis","cais","mais","cr煤cis","biqu铆nis","pois","depois","dois","leis"}}, + # males -> mal + {"les",3,"l"}, + # mares -> mar + {"res",3,"r", {"谩rvores"}}, + # casas -> casa + {"s",2,"",{"ali谩s","pires","l谩pis","cais","mais","mas","menos","f茅rias","fezes","p锚sames","cr煤cis","g谩s","atr谩s","mois茅s","atrav茅s","conv茅s","锚s","pa铆s","ap贸s","ambas","ambos","messias", "depois"}}}; + +# Step 2: Adverb Reduction +{ "Adverb", 0, 0, {}, + # felizmente -> feliz + {"mente",4,"",{"experimente"}}}; + +# Step 3: Feminine Reduction +{ "Feminine", 3, 1, {"a","茫"}, + # chefona -> chef茫o + {"ona",3,"茫o",{"abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","carona"}}, + # vil茫 -> vil茫o + {"茫",2,"茫o",{"amanh茫","arapu茫","f茫","div茫"}}, + # professora -> professor + {"ora",3,"or"}, + # americana -> americano + {"na",4,"no",{"carona","abandona","lona","iona","cortisona","mon贸tona","maratona","acetona","detona","guiana","campana","grana","caravana","banana","paisana"}}, + # sozinha -> sozinho + {"inha",3,"inho",{"rainha","linha","minha"}}, + # inglesa -> ingl锚s + {"esa",3,"锚s",{"mesa","obesa","princesa","turquesa","ilesa","pesa","presa"}}, + # famosa -> famoso + {"osa",3,"oso",{"mucosa","prosa"}}, + # man铆aca -> man铆aco + {"铆aca",3,"铆aco"}, + # pr谩tica -> pr谩tico + {"ica",3,"ico",{"dica"}}, + # cansada -> cansado + {"ada",2,"ado",{"pitada"}}, + # mantida -> mantido + {"ida",3,"ido",{"vida","d煤vida"}}, + {"铆da",3,"ido",{"reca铆da","sa铆da"}}, + # prima -> primo + {"ima",3,"imo",{"v铆tima"}}, + # passiva -> passivo + {"iva",3,"ivo",{"saliva","oliva"}}, + # primeira -> primeiro + {"eira",3,"eiro",{"beira","cadeira","frigideira","bandeira","feira","capoeira","barreira","fronteira","besteira","poeira"}}}; + +# Step 4: Augmentative/Diminutive Reduction +{ "Augmentative", 0, 1, {}, + # cansad铆ssimo -> cansad + {"d铆ssimo",5}, + # amabil铆ssimo -> ama + {"abil铆ssimo",5}, + # fort铆ssimo -> fort + {"铆ssimo",3}, + {"茅simo",3}, + # chiqu茅rrimo -> chiqu + {"茅rrimo",4}, + # pezinho -> pe + {"zinho",2}, + # maluquinho -> maluc + {"quinho",4,"c"}, + # amiguinho -> amig + {"uinho",4}, + # cansadinho -> cansad + {"adinho",3}, + # carrinho -> carr + {"inho",3,"",{"caminho","cominho"}}, + # grandalh茫o -> grand + {"alh茫o",4}, + # dentu莽a -> dent + {"u莽a",4}, + # rica莽o -> ric + {"a莽o",4,"",{"antebra莽o"}}, + {"a莽a",4}, + # casad茫o -> cans + {"ad茫o",4}, + {"id茫o",4}, + # corp谩zio -> corp + {"谩zio",3,"",{"top谩zio"}}, + # pratarraz -> prat + {"arraz",4}, + {"zarr茫o",3}, + {"arr茫o",4}, + # bocarra -> boc + {"arra",3}, + # calorz茫o -> calor + {"z茫o",2,"",{"coaliz茫o"}}, + # menin茫o -> menin + {"茫o",3,"",{"camar茫o","chimarr茫o","can莽茫o","cora莽茫o","embri茫o","grot茫o","glut茫o","fic莽茫o","fog茫o","fei莽茫o","furac茫o","gam茫o","lampi茫o","le茫o","macac茫o","na莽茫o","贸rf茫o","org茫o","patr茫o","port茫o","quinh茫o","rinc茫o","tra莽茫o","falc茫o","espi茫o","mam茫o","foli茫o","cord茫o","aptid茫o","campe茫o","colch茫o","lim茫o","leil茫o","mel茫o","bar茫o","milh茫o","bilh茫o","fus茫o","crist茫o","ilus茫o","capit茫o","esta莽茫o","sen茫o"}}}; + +# Step 5: Noun Suffix Reduction +{ "Noun", 0, 0, {}, + # existencialista -> exist + {"encialista",4}, + # minimalista -> minim + {"alista",5}, + # contagem -> cont + {"agem",3,"",{"coragem","chantagem","vantagem","carruagem"}}, + # gerenciamento -> gerenc + {"iamento",4}, + # monitoramento -> monitor + {"amento",3,"",{"firmamento","fundamento","departamento"}}, + # nascimento -> nasc + {"imento",3}, + {"mento",6,"",{"firmamento","elemento","complemento","instrumento","departamento"}}, + # comercializado -> comerci + {"alizado",4}, + # traumatizado -> traum + {"atizado",4}, + {"tizado",4,"",{"alfabetizado"}}, + # alfabetizado -> alfabet + {"izado",5,"",{"organizado","pulverizado"}}, + # associativo -> associ + {"ativo",4,"",{"pejorativo","relativo"}}, + # contraceptivo -> contracep + {"tivo",4,"",{"relativo"}}, + # esportivo -> esport + {"ivo",4,"",{"passivo","possessivo","pejorativo","positivo"}}, + # abalado -> abal + {"ado",2,"",{"grado"}}, + # impedido -> imped + {"ido",3,"",{"c芒ndido","consolido","r谩pido","decido","t铆mido","duvido","marido"}}, + # ralador -> ral + {"ador",3}, + # entendedor -> entend + {"edor",3}, + # cumpridor -> cumpr + {"idor",4,"",{"ouvidor"}}, + {"dor",4,"",{"ouvidor"}}, + {"sor",4,"",{"assessor"}}, + {"atoria",5}, + {"tor",3,"",{"benfeitor","leitor","editor","pastor","produtor","promotor","consultor"}}, + {"or",2,"",{"motor","melhor","redor","rigor","sensor","tambor","tumor","assessor","benfeitor","pastor","terior","favor","autor"}}, + # comparabilidade -> compar + {"abilidade",5}, + # abolicionista -> abol + {"icionista",4}, + # intervencionista -> interven + {"cionista",5}, + {"ionista",5}, + {"ionar",5}, + # profissional -> profiss + {"ional",4}, + # refer锚ncia -> refer + {"锚ncia",3}, + # repugn芒ncia -> repugn + {"芒ncia",4,"",{"ambul芒ncia"}}, + # abatedouro -> abat + {"edouro",3}, + # fofoqueiro -> fofoc + {"queiro",3,"c"}, + {"adeiro",4,"",{"desfiladeiro"}}, + # brasileiro -> brasil + {"eiro",3,"",{"desfiladeiro","pioneiro","mosteiro"}}, + {"uoso",3}, + # gostoso -> gost + {"oso",3,"",{"precioso"}}, + # comercializa莽 -> comerci + {"aliza莽",5}, + {"atiza莽",5}, + {"tiza莽",5}, + {"iza莽",5,"",{"organiza莽"}}, + # alega莽 -> aleg + {"a莽",3,"",{"equa莽","rela莽"}}, + # aboli莽 -> abol + {"i莽",3,"",{"elei莽"}}, + # anedot谩rio -> anedot + {"谩rio",3,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","lion谩rio","arm谩rio"}}, + {"at贸rio",3}, + {"rio",5,"",{"volunt谩rio","sal谩rio","anivers谩rio","di谩rio","compuls贸rio","lion谩rio","pr贸prio","st茅rio","arm谩rio"}}, + # minist茅rio -> minist + {"茅rio",6}, + # chin锚s -> chin + {"锚s",4}, + # beleza -> bel + {"eza",3}, + # rigidez -> rigid + {"ez",4}, + # parentesco -> parent + {"esco",4}, + # ocupante -> ocup + {"ante",2,"",{"gigante","elefante","adiante","possante","instante","restaurante"}}, + # bomb谩stico -> bomb + {"谩stico",4,"",{"eclesi谩stico"}}, + {"al铆stico",3}, + {"谩utico",4}, + {"锚utico",4}, + {"tico",3,"",{"pol铆tico","eclesi谩stico","diagnostico","pr谩tico","dom茅stico","diagn贸stico","id锚ntico","alop谩tico","art铆stico","aut锚ntico","ecl茅tico","cr铆tico","critico"}}, + # pol锚mico -> pol锚m + {"ico",4,"",{"tico","p煤blico","explico"}}, + # produtividade -> produt + {"ividade",5}, + # profundidade -> profund + {"idade",4,"",{"autoridade","comunidade"}}, + # aposentadoria -> aposentad + {"oria",4,"",{"categoria"}}, + # existencial -> exist + {"encial",5}, + # artista -> art + {"ista",4}, + {"auta",5}, + # maluquice -> maluc + {"quice",4,"c"}, + # chatice -> chat + {"ice",4,"",{"c煤mplice"}}, + # demon铆aco -> demon + {"铆aco",3}, + # decorrente -> decorr + {"ente",4,"",{"freq眉ente","alimente","acrescente","permanente","oriente","aparente"}}, + {"ense",5}, + # criminal -> crim + {"inal",3}, + # americano -> americ + {"ano",4}, + # am谩vel -> am + {"谩vel",2,"",{"af谩vel","razo谩vel","pot谩vel","vulner谩vel"}}, + # combust铆vel -> combust + {"铆vel",3,"",{"poss铆vel"}}, + {"vel",5,"",{"poss铆vel","vulner谩vel","sol煤vel"}}, + {"bil",3,"vel"}, + # cobertura -> cobert + {"ura",4,"",{"imatura","acupuntura","costura"}}, + {"ural",4}, + # consensual -> consens + {"ual",3,"",{"bissexual","virtual","visual","pontual"}}, + # mundial -> mund + {"ial",3}, + # experimental -> experiment + {"al",4,"",{"afinal","animal","estatal","bissexual","desleal","fiscal","formal","pessoal","liberal","postal","virtual","visual","pontual","sideral","sucursal"}}, + {"alismo",4}, + {"ivismo",4}, + {"ismo",3,"",{"cinismo"}}}; + +# Step 6: Verb Suffix Reduction +{ "Verb", 0, 0, {}, + # cantar铆amo -> cant + {"ar铆amo",2}, + # cant谩ssemo -> cant + {"谩ssemo",2}, + # beber铆amo -> beb + {"er铆amo",2}, + # beb锚ssemo -> beb + {"锚ssemo",2}, + # partir铆amo -> part + {"ir铆amo",3}, + # part铆ssemo -> part + {"铆ssemo",3}, + # cant谩ramo -> cant + {"谩ramo",2}, + # cant谩rei -> cant + {"谩rei",2}, + # cantaremo -> cant + {"aremo",2}, + # cantariam -> cant + {"ariam",2}, + # cantar铆ei -> cant + {"ar铆ei",2}, + # cant谩ssei -> cant + {"谩ssei",2}, + # cantassem -> cant + {"assem",2}, + # cant谩vamo -> cant + {"谩vamo",2}, + # beb锚ramo -> beb + {"锚ramo",3}, + # beberemo -> beb + {"eremo",3}, + # beberiam -> beb + {"eriam",3}, + # beber铆ei -> beb + {"er铆ei",3}, + # beb锚ssei -> beb + {"锚ssei",3}, + # bebessem -> beb + {"essem",3}, + # partir铆amo -> part + {"铆ramo",3}, + # partiremo -> part + {"iremo",3}, + # partiriam -> part + {"iriam",3}, + # partir铆ei -> part + {"ir铆ei",3}, + # part铆ssei -> part + {"铆ssei",3}, + # partissem -> part + {"issem",3}, + # cantando -> cant + {"ando",2}, + # bebendo -> beb + {"endo",3}, + # partindo -> part + {"indo",3}, + # propondo -> prop + {"ondo",3}, + # cantaram -> cant + {"aram",2}, + {"ar茫o",2}, + # cantarde -> cant + {"arde",2}, + # cantarei -> cant + {"arei",2}, + # cantarem -> cant + {"arem",2}, + # cantaria -> cant + {"aria",2}, + # cantarmo -> cant + {"armo",2}, + # cantasse -> cant + {"asse",2}, + # cantaste -> cant + {"aste",2}, + # cantavam -> cant + {"avam",2,"",{"agravam"}}, + # cant谩vei -> cant + {"谩vei",2}, + # beberam -> beb + {"eram",3}, + {"er茫o",3}, + # beberde -> beb + {"erde",3}, + # beberei -> beb + {"erei",3}, + # beb锚rei -> beb + {"锚rei",3}, + # beberem -> beb + {"erem",3}, + # beberia -> beb + {"eria",3}, + # bebermo -> beb + {"ermo",3}, + # bebesse -> beb + {"esse",3}, + # bebeste -> beb + {"este",3,"",{"faroeste","agreste"}}, + # beb铆amo -> beb + {"铆amo",3}, + # partiram -> part + {"iram",3}, + # conclu铆ram -> conclu + {"铆ram",3}, + {"ir茫o",2}, + # partirde -> part + {"irde",2}, + # part铆rei -> part + {"irei",3,"",{"admirei"}}, + # partirem -> part + {"irem",3,"",{"adquirem"}}, + # partiria -> part + {"iria",3}, + # partirmo -> part + {"irmo",3}, + # partisse -> part + {"isse",3}, + # partiste -> part + {"iste",4}, + {"iava",4,"",{"ampliava"}}, + # cantamo -> cant + {"amo",2}, + {"iona",3}, + # cantara -> cant + {"ara",2,"",{"arara","prepara"}}, + # cantar谩 -> cant + {"ar谩",2,"",{"alvar谩"}}, + # cantare -> cant + {"are",2,"",{"prepare"}}, + # cantava -> cant + {"ava",2,"",{"agrava"}}, + # cantemo -> cant + {"emo",2}, + # bebera -> beb + {"era",3,"",{"acelera","espera"}}, + # beber谩 -> beb + {"er谩",3}, + # bebere -> beb + {"ere",3,"",{"espere"}}, + # bebiam -> beb + {"iam",3,"",{"enfiam","ampliam","elogiam","ensaiam"}}, + # beb铆ei -> beb + {"铆ei",3}, + # partimo -> part + {"imo",3,"",{"reprimo","intimo","铆ntimo","nimo","queimo","ximo"}}, + # partira -> part + {"ira",3,"",{"fronteira","s谩tira"}}, + {"铆do",3}, + # partir谩 -> part + {"ir谩",3}, + {"tizar",4,"",{"alfabetizar"}}, + {"izar",5,"",{"organizar"}}, + {"itar",5,"",{"acreditar","explicitar","estreitar"}}, + # partire -> part + {"ire",3,"",{"adquire"}}, + # compomo -> comp + {"omo",3}, + # cantai -> cant + {"ai",2}, + # cantam -> cant + {"am",2}, + # barbear -> barb + {"ear",4,"",{"alardear","nuclear"}}, + # cantar -> cant + {"ar",2,"",{"azar","bazaar","patamar"}}, + # cheguei -> cheg + {"uei",3}, + {"u铆a",5,"u"}, + # cantei -> cant + {"ei",3}, + {"guem",3,"g"}, + # cantem -> cant + {"em",2,"",{"alem","virgem"}}, + # beber -> beb + {"er",2,"",{"茅ter","pier"}}, + # bebeu -> beb + {"eu",3,"",{"chapeu"}}, + # bebia -> beb + {"ia",3,"",{"est贸ria","fatia","acia","praia","elogia","mania","l谩bia","aprecia","pol铆cia","arredia","cheia","谩sia"}}, + # partir -> part + {"ir",3,"",{"freir"}}, + # partiu -> part + {"iu",3}, + {"eou",5}, + # chegou -> cheg + {"ou",3}, + # bebi -> beb + {"i",3}}; + +# Step 7: Vowel Removal +{ "Vowel", 0, 0, {}, + {"bil",2,"vel"}, + {"gue",2,"g",{"gangue","jegue"}}, + {"谩",3}, + {"锚",3,"",{"beb锚"}}, + # menina -> menin + {"a",3,"",{"谩sia"}}, + # grande -> grand + {"e",3}, + # menino -> menin + {"o",3,"",{"茫o"}}}; From fbfb07d90490f1ee37ab476232abecbd73975562 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 6 Jan 2011 15:07:12 +0000 Subject: [PATCH 013/252] LUCENE-2842: avoid java6-only String.isEmpty in rule parser git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1055906 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java index e27f6d35137..2fb7a1f236e 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/pt/RSLPStemmerBase.java @@ -321,7 +321,7 @@ public abstract class RSLPStemmerBase { } private static String[] parseList(String s) { - if (s.isEmpty()) + if (s.length() == 0) return null; String list[] = s.split(","); for (int i = 0; i < list.length; i++) @@ -337,7 +337,7 @@ public abstract class RSLPStemmerBase { String line = null; while ((line = r.readLine()) != null) { line = line.trim(); - if (!line.isEmpty() && line.charAt(0) != '#') + if (line.length() > 0 && line.charAt(0) != '#') return line; } return line; From 8d7d57abdcf5ff58dc35b4cbdf0373c4bb12b579 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Thu, 6 Jan 2011 19:15:21 +0000 Subject: [PATCH 014/252] LUCENE-2847: Added ASL2 license to supplementary macros generator, and to the generated file, and set svn:eol-style to native for both of them. git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056014 13f79535-47bb-0310-9956-ffa450edef68 --- .../standard/SUPPLEMENTARY.jflex-macro | 230 ++++++++++-------- .../icu/GenerateJFlexSupplementaryMacros.java | 38 +++ 2 files changed, 163 insertions(+), 105 deletions(-) diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro index 21c1ed940ae..fecf9777f9a 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/SUPPLEMENTARY.jflex-macro @@ -1,105 +1,125 @@ -ALetterSupp = ( - ([\ud80d][\uDC00-\uDC2E]) - | ([\ud80c][\uDC00-\uDFFF]) - | ([\ud809][\uDC00-\uDC62]) - | ([\ud808][\uDC00-\uDF6E]) - | ([\ud81a][\uDC00-\uDE38]) - | ([\ud804][\uDC03-\uDC37\uDC83-\uDCAF]) - | ([\ud835][\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]) - | ([\ud801][\uDC00-\uDC9D]) - | ([\ud800][\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF4A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]) - | ([\ud803][\uDC00-\uDC48]) - | ([\ud802][\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]) -) -FormatSupp = ( - ([\ud804][\uDCBD]) - | ([\ud834][\uDD73-\uDD7A]) - | ([\udb40][\uDC01\uDC20-\uDC7F]) -) -ExtendSupp = ( - ([\ud804][\uDC00-\uDC02\uDC38-\uDC46\uDC80-\uDC82\uDCB0-\uDCBA]) - | ([\ud834][\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]) - | ([\ud800][\uDDFD]) - | ([\udb40][\uDD00-\uDDEF]) - | ([\ud802][\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]) -) -NumericSupp = ( - ([\ud804][\uDC66-\uDC6F]) - | ([\ud835][\uDFCE-\uDFFF]) - | ([\ud801][\uDCA0-\uDCA9]) -) -KatakanaSupp = ( - ([\ud82c][\uDC00]) -) -MidLetterSupp = ( - [] -) -MidNumSupp = ( - [] -) -MidNumLetSupp = ( - [] -) -ExtendNumLetSupp = ( - [] -) -ExtendNumLetSupp = ( - [] -) -ComplexContextSupp = ( - [] -) -HanSupp = ( - ([\ud87e][\uDC00-\uDE1D]) - | ([\ud86b][\uDC00-\uDFFF]) - | ([\ud86a][\uDC00-\uDFFF]) - | ([\ud869][\uDC00-\uDED6\uDF00-\uDFFF]) - | ([\ud868][\uDC00-\uDFFF]) - | ([\ud86e][\uDC00-\uDC1D]) - | ([\ud86d][\uDC00-\uDF34\uDF40-\uDFFF]) - | ([\ud86c][\uDC00-\uDFFF]) - | ([\ud863][\uDC00-\uDFFF]) - | ([\ud862][\uDC00-\uDFFF]) - | ([\ud861][\uDC00-\uDFFF]) - | ([\ud860][\uDC00-\uDFFF]) - | ([\ud867][\uDC00-\uDFFF]) - | ([\ud866][\uDC00-\uDFFF]) - | ([\ud865][\uDC00-\uDFFF]) - | ([\ud864][\uDC00-\uDFFF]) - | ([\ud858][\uDC00-\uDFFF]) - | ([\ud859][\uDC00-\uDFFF]) - | ([\ud85a][\uDC00-\uDFFF]) - | ([\ud85b][\uDC00-\uDFFF]) - | ([\ud85c][\uDC00-\uDFFF]) - | ([\ud85d][\uDC00-\uDFFF]) - | ([\ud85e][\uDC00-\uDFFF]) - | ([\ud85f][\uDC00-\uDFFF]) - | ([\ud850][\uDC00-\uDFFF]) - | ([\ud851][\uDC00-\uDFFF]) - | ([\ud852][\uDC00-\uDFFF]) - | ([\ud853][\uDC00-\uDFFF]) - | ([\ud854][\uDC00-\uDFFF]) - | ([\ud855][\uDC00-\uDFFF]) - | ([\ud856][\uDC00-\uDFFF]) - | ([\ud857][\uDC00-\uDFFF]) - | ([\ud849][\uDC00-\uDFFF]) - | ([\ud848][\uDC00-\uDFFF]) - | ([\ud84b][\uDC00-\uDFFF]) - | ([\ud84a][\uDC00-\uDFFF]) - | ([\ud84d][\uDC00-\uDFFF]) - | ([\ud84c][\uDC00-\uDFFF]) - | ([\ud84f][\uDC00-\uDFFF]) - | ([\ud84e][\uDC00-\uDFFF]) - | ([\ud841][\uDC00-\uDFFF]) - | ([\ud840][\uDC00-\uDFFF]) - | ([\ud843][\uDC00-\uDFFF]) - | ([\ud842][\uDC00-\uDFFF]) - | ([\ud845][\uDC00-\uDFFF]) - | ([\ud844][\uDC00-\uDFFF]) - | ([\ud847][\uDC00-\uDFFF]) - | ([\ud846][\uDC00-\uDFFF]) -) -HiraganaSupp = ( - ([\ud83c][\uDE00]) - | ([\ud82c][\uDC01]) -) +/* + * Copyright 2010 The Apache Software Foundation. + * + * Licensed 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. + */ + +// Generated using ICU4J 4.6.0.0 on Thursday, January 6, 2011 7:02:52 PM UTC +// by org.apache.lucene.analysis.icu.GenerateJFlexSupplementaryMacros + + +ALetterSupp = ( + ([\ud80d][\uDC00-\uDC2E]) + | ([\ud80c][\uDC00-\uDFFF]) + | ([\ud809][\uDC00-\uDC62]) + | ([\ud808][\uDC00-\uDF6E]) + | ([\ud81a][\uDC00-\uDE38]) + | ([\ud804][\uDC03-\uDC37\uDC83-\uDCAF]) + | ([\ud835][\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]) + | ([\ud801][\uDC00-\uDC9D]) + | ([\ud800][\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1E\uDF30-\uDF4A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]) + | ([\ud803][\uDC00-\uDC48]) + | ([\ud802][\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDD00-\uDD15\uDD20-\uDD39\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72]) +) +FormatSupp = ( + ([\ud804][\uDCBD]) + | ([\ud834][\uDD73-\uDD7A]) + | ([\udb40][\uDC01\uDC20-\uDC7F]) +) +ExtendSupp = ( + ([\ud804][\uDC00-\uDC02\uDC38-\uDC46\uDC80-\uDC82\uDCB0-\uDCBA]) + | ([\ud834][\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]) + | ([\ud800][\uDDFD]) + | ([\udb40][\uDD00-\uDDEF]) + | ([\ud802][\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F]) +) +NumericSupp = ( + ([\ud804][\uDC66-\uDC6F]) + | ([\ud835][\uDFCE-\uDFFF]) + | ([\ud801][\uDCA0-\uDCA9]) +) +KatakanaSupp = ( + ([\ud82c][\uDC00]) +) +MidLetterSupp = ( + [] +) +MidNumSupp = ( + [] +) +MidNumLetSupp = ( + [] +) +ExtendNumLetSupp = ( + [] +) +ExtendNumLetSupp = ( + [] +) +ComplexContextSupp = ( + [] +) +HanSupp = ( + ([\ud87e][\uDC00-\uDE1D]) + | ([\ud86b][\uDC00-\uDFFF]) + | ([\ud86a][\uDC00-\uDFFF]) + | ([\ud869][\uDC00-\uDED6\uDF00-\uDFFF]) + | ([\ud868][\uDC00-\uDFFF]) + | ([\ud86e][\uDC00-\uDC1D]) + | ([\ud86d][\uDC00-\uDF34\uDF40-\uDFFF]) + | ([\ud86c][\uDC00-\uDFFF]) + | ([\ud863][\uDC00-\uDFFF]) + | ([\ud862][\uDC00-\uDFFF]) + | ([\ud861][\uDC00-\uDFFF]) + | ([\ud860][\uDC00-\uDFFF]) + | ([\ud867][\uDC00-\uDFFF]) + | ([\ud866][\uDC00-\uDFFF]) + | ([\ud865][\uDC00-\uDFFF]) + | ([\ud864][\uDC00-\uDFFF]) + | ([\ud858][\uDC00-\uDFFF]) + | ([\ud859][\uDC00-\uDFFF]) + | ([\ud85a][\uDC00-\uDFFF]) + | ([\ud85b][\uDC00-\uDFFF]) + | ([\ud85c][\uDC00-\uDFFF]) + | ([\ud85d][\uDC00-\uDFFF]) + | ([\ud85e][\uDC00-\uDFFF]) + | ([\ud85f][\uDC00-\uDFFF]) + | ([\ud850][\uDC00-\uDFFF]) + | ([\ud851][\uDC00-\uDFFF]) + | ([\ud852][\uDC00-\uDFFF]) + | ([\ud853][\uDC00-\uDFFF]) + | ([\ud854][\uDC00-\uDFFF]) + | ([\ud855][\uDC00-\uDFFF]) + | ([\ud856][\uDC00-\uDFFF]) + | ([\ud857][\uDC00-\uDFFF]) + | ([\ud849][\uDC00-\uDFFF]) + | ([\ud848][\uDC00-\uDFFF]) + | ([\ud84b][\uDC00-\uDFFF]) + | ([\ud84a][\uDC00-\uDFFF]) + | ([\ud84d][\uDC00-\uDFFF]) + | ([\ud84c][\uDC00-\uDFFF]) + | ([\ud84f][\uDC00-\uDFFF]) + | ([\ud84e][\uDC00-\uDFFF]) + | ([\ud841][\uDC00-\uDFFF]) + | ([\ud840][\uDC00-\uDFFF]) + | ([\ud843][\uDC00-\uDFFF]) + | ([\ud842][\uDC00-\uDFFF]) + | ([\ud845][\uDC00-\uDFFF]) + | ([\ud844][\uDC00-\uDFFF]) + | ([\ud847][\uDC00-\uDFFF]) + | ([\ud846][\uDC00-\uDFFF]) +) +HiraganaSupp = ( + ([\ud83c][\uDE00]) + | ([\ud82c][\uDC01]) +) diff --git a/modules/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java b/modules/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java index 09c965079e7..cd7bfea6f51 100644 --- a/modules/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java +++ b/modules/analysis/icu/src/tools/java/org/apache/lucene/analysis/icu/GenerateJFlexSupplementaryMacros.java @@ -17,16 +17,46 @@ package org.apache.lucene.analysis.icu; * limitations under the License. */ +import java.text.DateFormat; +import java.util.Date; import java.util.HashMap; +import java.util.Locale; +import java.util.TimeZone; import com.ibm.icu.text.UnicodeSet; import com.ibm.icu.text.UnicodeSetIterator; +import com.ibm.icu.util.VersionInfo; /** creates a macro to augment jflex's unicode wordbreak support for > BMP */ public class GenerateJFlexSupplementaryMacros { private static final UnicodeSet BMP = new UnicodeSet("[\u0000-\uFFFF]"); + private static final String NL = System.getProperty("line.separator"); + private static final DateFormat DATE_FORMAT = DateFormat.getDateTimeInstance + (DateFormat.FULL, DateFormat.FULL, Locale.US); + static { + DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + private static final String APACHE_LICENSE + = "/*" + NL + + " * Copyright 2010 The Apache Software Foundation." + NL + + " *" + NL + + " * Licensed under the Apache License, Version 2.0 (the \"License\");" + NL + + " * you may not use this file except in compliance with the License." + NL + + " * You may obtain a copy of the License at" + NL + + " *" + NL + + " * http://www.apache.org/licenses/LICENSE-2.0" + NL + + " *" + NL + + " * Unless required by applicable law or agreed to in writing, software" + NL + + " * distributed under the License is distributed on an \"AS IS\" BASIS," + NL + + " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied." + NL + + " * See the License for the specific language governing permissions and" + NL + + " * limitations under the License." + NL + + " */" + NL + NL; + public static void main(String args[]) throws Exception { + outputHeader(); outputMacro("ALetterSupp", "[:WordBreak=ALetter:]"); outputMacro("FormatSupp", "[:WordBreak=Format:]"); outputMacro("ExtendSupp", "[:WordBreak=Extend:]"); @@ -42,6 +72,14 @@ public class GenerateJFlexSupplementaryMacros { outputMacro("HiraganaSupp", "[:Script=Hiragana:]"); } + static void outputHeader() { + System.out.print(APACHE_LICENSE); + System.out.print("// Generated using ICU4J " + VersionInfo.ICU_VERSION.toString() + " on "); + System.out.println(DATE_FORMAT.format(new Date())); + System.out.println("// by " + GenerateJFlexSupplementaryMacros.class.getName()); + System.out.print(NL + NL); + } + // we have to carefully output the possibilities as compact utf-16 // range expressions, or jflex will OOM! static void outputMacro(String name, String pattern) { From 8dfb827d0c8da316a96be4c572ddef6d5416527d Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Thu, 6 Jan 2011 21:20:18 +0000 Subject: [PATCH 015/252] LUCENE-2837: only populate subSearchers if they will be used git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056086 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/search/IndexSearcher.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 4136c0458e8..2fdff34ad13 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -64,9 +64,10 @@ public class IndexSearcher { // in the next release protected final ReaderContext readerContext; protected final AtomicReaderContext[] leafContexts; - protected final IndexSearcher[] subSearchers; -// protected final int[] docStarts; + + // These are only used for multi-threaded search private final ExecutorService executor; + protected final IndexSearcher[] subSearchers; /** The Similarity implementation used by this searcher. */ private Similarity similarity = Similarity.getDefault(); @@ -165,12 +166,17 @@ public class IndexSearcher { assert context.leaves() != null : "non-atomic top-level context must have leaves"; this.leafContexts = context.leaves(); } - subSearchers = new IndexSearcher[this.leafContexts.length]; - for (int i = 0; i < subSearchers.length; i++) { // TODO do we need those IS if executor is null? - if (leafContexts[i].reader == context.reader) { - subSearchers[i] = this; - } else { - subSearchers[i] = new IndexSearcher(leafContexts[i].reader.getTopReaderContext()); // we need to get a TL context for sub searchers! + + if (executor == null) { + subSearchers = null; + } else { + subSearchers = new IndexSearcher[this.leafContexts.length]; + for (int i = 0; i < subSearchers.length; i++) { + if (leafContexts[i].reader == context.reader) { + subSearchers[i] = this; + } else { + subSearchers[i] = new IndexSearcher(leafContexts[i].reader.getTopReaderContext()); // we need to get a TL context for sub searchers! + } } } } From 4dca51491c950bdada326979df3fd86769b9de5a Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Fri, 7 Jan 2011 03:43:21 +0000 Subject: [PATCH 016/252] Fix source directories in the IntelliJ IDEA configuration git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056183 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/idea/lucene/contrib/ant/ant.iml | 1 + dev-tools/idea/lucene/contrib/queryparser/queryparser.iml | 1 + dev-tools/idea/modules/analysis/common/common.iml | 1 + dev-tools/idea/modules/benchmark/benchmark.iml | 1 - dev-tools/idea/solr/solr.iml | 1 - 5 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-tools/idea/lucene/contrib/ant/ant.iml b/dev-tools/idea/lucene/contrib/ant/ant.iml index 3f14daf7e33..fbe88c99764 100644 --- a/dev-tools/idea/lucene/contrib/ant/ant.iml +++ b/dev-tools/idea/lucene/contrib/ant/ant.iml @@ -6,6 +6,7 @@ + diff --git a/dev-tools/idea/lucene/contrib/queryparser/queryparser.iml b/dev-tools/idea/lucene/contrib/queryparser/queryparser.iml index 9ba52710867..f4a112719e5 100644 --- a/dev-tools/idea/lucene/contrib/queryparser/queryparser.iml +++ b/dev-tools/idea/lucene/contrib/queryparser/queryparser.iml @@ -6,6 +6,7 @@ + diff --git a/dev-tools/idea/modules/analysis/common/common.iml b/dev-tools/idea/modules/analysis/common/common.iml index 28d4158822a..57888ab9140 100644 --- a/dev-tools/idea/modules/analysis/common/common.iml +++ b/dev-tools/idea/modules/analysis/common/common.iml @@ -7,6 +7,7 @@ + diff --git a/dev-tools/idea/modules/benchmark/benchmark.iml b/dev-tools/idea/modules/benchmark/benchmark.iml index 95ca885a13c..fcd77da13e1 100644 --- a/dev-tools/idea/modules/benchmark/benchmark.iml +++ b/dev-tools/idea/modules/benchmark/benchmark.iml @@ -7,7 +7,6 @@ - diff --git a/dev-tools/idea/solr/solr.iml b/dev-tools/idea/solr/solr.iml index b8de790a000..218fd039de9 100644 --- a/dev-tools/idea/solr/solr.iml +++ b/dev-tools/idea/solr/solr.iml @@ -10,7 +10,6 @@ - From f70b9571a9f773232e2cc18be21227aed1f5e086 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Fri, 7 Jan 2011 14:31:09 +0000 Subject: [PATCH 017/252] LUCENE-2831: pre-migrate to atomic context git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056337 13f79535-47bb-0310-9956-ffa450edef68 --- solr/src/java/org/apache/solr/search/DocSet.java | 13 +++++-------- .../org/apache/solr/search/SortedIntDocSet.java | 13 +++++-------- .../src/test/org/apache/solr/search/TestDocSet.java | 5 +++++ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/solr/src/java/org/apache/solr/search/DocSet.java b/solr/src/java/org/apache/solr/search/DocSet.java index 32dc4f53e94..59b3286c98a 100644 --- a/solr/src/java/org/apache/solr/search/DocSet.java +++ b/solr/src/java/org/apache/solr/search/DocSet.java @@ -248,17 +248,14 @@ abstract class DocSetBase implements DocSet { return new Filter() { @Override public DocIdSet getDocIdSet(ReaderContext ctx) throws IOException { - int offset = 0; + IndexReader.AtomicReaderContext context = (IndexReader.AtomicReaderContext)ctx; // TODO: remove after lucene migration IndexReader reader = ctx.reader; - SolrIndexReader r = (SolrIndexReader)reader; - while (r.getParent() != null) { - offset += r.getBase(); - r = r.getParent(); + + if (context.isTopLevel) { + return bs; } - if (r==reader) return bs; - - final int base = offset; + final int base = context.docBase; final int maxDoc = reader.maxDoc(); final int max = base + maxDoc; // one past the max doc in this segment. diff --git a/solr/src/java/org/apache/solr/search/SortedIntDocSet.java b/solr/src/java/org/apache/solr/search/SortedIntDocSet.java index b0bb860407b..052bac50ef6 100755 --- a/solr/src/java/org/apache/solr/search/SortedIntDocSet.java +++ b/solr/src/java/org/apache/solr/search/SortedIntDocSet.java @@ -23,6 +23,7 @@ import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; @@ -552,15 +553,11 @@ public class SortedIntDocSet extends DocSetBase { int lastEndIdx = 0; @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { - int offset = 0; + public DocIdSet getDocIdSet(ReaderContext contextX) throws IOException { + AtomicReaderContext context = (AtomicReaderContext)contextX; // TODO: remove after lucene migration IndexReader reader = context.reader; - SolrIndexReader r = (SolrIndexReader)reader; - while (r.getParent() != null) { - offset += r.getBase(); - r = r.getParent(); - } - final int base = offset; + + final int base = context.docBase; final int maxDoc = reader.maxDoc(); final int max = base + maxDoc; // one past the max doc in this segment. int sidx = Math.max(0,lastEndIdx); diff --git a/solr/src/test/org/apache/solr/search/TestDocSet.java b/solr/src/test/org/apache/solr/search/TestDocSet.java index 280e58d39ae..8a87ac5d72b 100644 --- a/solr/src/test/org/apache/solr/search/TestDocSet.java +++ b/solr/src/test/org/apache/solr/search/TestDocSet.java @@ -413,10 +413,15 @@ public class TestDocSet extends LuceneTestCase { Filter fa = a.getTopFilter(); Filter fb = b.getTopFilter(); + /*** top level filters are no longer supported // test top-level DocIdSet da = fa.getDocIdSet(topLevelContext); DocIdSet db = fb.getDocIdSet(topLevelContext); doTestIteratorEqual(da, db); + ***/ + + DocIdSet da; + DocIdSet db; // first test in-sequence sub readers for (ReaderContext readerInfo : topLevelContext.leaves()) { From 602a4e906aacd0062c82edeb44253f82ff28a9ce Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Fri, 7 Jan 2011 17:42:44 +0000 Subject: [PATCH 018/252] don't use package private API to assert no unreferenced files git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056409 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/test/org/apache/lucene/index/TestIndexReader.java | 1 + lucene/src/test/org/apache/lucene/index/TestIndexWriter.java | 3 +-- .../test/org/apache/lucene/index/TestIndexWriterDelete.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java index e75d17c28dc..d3a3db8b691 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java @@ -981,6 +981,7 @@ public class TestIndexReader extends LuceneTestCase // new IndexFileDeleter, have it delete // unreferenced files, then verify that in fact // no files were deleted: + IndexWriter.unlock(dir); TestIndexWriter.assertNoUnreferencedFiles(dir, "reader.close() failed to delete unreferenced files"); // Finally, verify index is not corrupt, and, if diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java index 7f84850b4d9..c4e8ba82af6 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -43,7 +43,6 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.codecs.CodecProvider; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.document.Field.TermVector; @@ -157,7 +156,7 @@ public class TestIndexWriter extends LuceneTestCase { String[] startFiles = dir.listAll(); SegmentInfos infos = new SegmentInfos(); infos.read(dir); - new IndexFileDeleter(dir, new KeepOnlyLastCommitDeletionPolicy(), infos, null, CodecProvider.getDefault()); + new IndexWriter(dir, new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer())).rollback(); String[] endFiles = dir.listAll(); Arrays.sort(startFiles); diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexWriterDelete.java b/lucene/src/test/org/apache/lucene/index/TestIndexWriterDelete.java index 617a6b8d4a6..c546b2a3cb3 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexWriterDelete.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexWriterDelete.java @@ -832,8 +832,8 @@ public class TestIndexWriterDelete extends LuceneTestCase { } } - TestIndexWriter.assertNoUnreferencedFiles(dir, "docsWriter.abort() failed to delete unreferenced files"); modifier.close(); + TestIndexWriter.assertNoUnreferencedFiles(dir, "docsWriter.abort() failed to delete unreferenced files"); dir.close(); } From cabea439385b177abbbd2538b4e014e13d20d848 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Fri, 7 Jan 2011 18:02:35 +0000 Subject: [PATCH 019/252] LUCENE-2852: fix false EOF corner case in RAMInputStream git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056428 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/store/RAMInputStream.java | 2 +- .../apache/lucene/search/TestThreadSafe.java | 20 +++++++++---------- .../apache/lucene/store/TestRAMDirectory.java | 18 +++++++++++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/store/RAMInputStream.java b/lucene/src/java/org/apache/lucene/store/RAMInputStream.java index 15f87d5e595..b898f7b38dd 100644 --- a/lucene/src/java/org/apache/lucene/store/RAMInputStream.java +++ b/lucene/src/java/org/apache/lucene/store/RAMInputStream.java @@ -83,6 +83,7 @@ class RAMInputStream extends IndexInput implements Cloneable { } private final void switchCurrentBuffer(boolean enforceEOF) throws IOException { + bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; if (currentBufferIndex >= file.numBuffers()) { // end of file reached, no more buffers left if (enforceEOF) @@ -95,7 +96,6 @@ class RAMInputStream extends IndexInput implements Cloneable { } else { currentBuffer = file.getBuffer(currentBufferIndex); bufferPosition = 0; - bufferStart = (long) BUFFER_SIZE * (long) currentBufferIndex; long buflen = length - bufferStart; bufferLength = buflen > BUFFER_SIZE ? BUFFER_SIZE : (int) buflen; } diff --git a/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java b/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java index cb9f13f10a1..048ad57ecdc 100755 --- a/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java +++ b/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java @@ -27,6 +27,7 @@ import org.apache.lucene.document.*; import java.util.Random; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.io.IOException; public class TestThreadSafe extends LuceneTestCase { @@ -34,16 +35,16 @@ public class TestThreadSafe extends LuceneTestCase { IndexReader ir1; - String failure=null; - - class Thr extends Thread { final int iter; final Random rand; + final AtomicBoolean failed; + // pass in random in case we want to make things reproducable - public Thr(int iter, Random rand) { + public Thr(int iter, Random rand, AtomicBoolean failed) { this.iter = iter; this.rand = rand; + this.failed = failed; } @Override @@ -61,8 +62,8 @@ public class TestThreadSafe extends LuceneTestCase { } } catch (Throwable th) { - failure=th.toString(); - fail(failure); + failed.set(true); + throw new RuntimeException(th); } } @@ -124,16 +125,15 @@ public class TestThreadSafe extends LuceneTestCase { void doTest(int iter, int nThreads) throws Exception { Thr[] tarr = new Thr[nThreads]; + AtomicBoolean failed = new AtomicBoolean(); for (int i=0; i Date: Fri, 7 Jan 2011 18:43:58 +0000 Subject: [PATCH 020/252] LUCENE-2660 - Added alternative search provider option for Solr git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056452 13f79535-47bb-0310-9956-ffa450edef68 --- solr/site/features.html | 45 ++++++++++-- solr/site/images/solr.jpg | Bin 15574 -> 12719 bytes solr/site/index.html | 45 ++++++++++-- solr/site/issue_tracking.html | 45 ++++++++++-- solr/site/linkmap.html | 45 ++++++++++-- solr/site/mailing_lists.html | 45 ++++++++++-- solr/site/skin/screen.css | 2 +- solr/site/tutorial.html | 55 ++++++++++++--- solr/site/tutorial.pdf | 2 +- solr/site/version_control.html | 45 ++++++++++-- .../documentation/skins/lucene/css/screen.css | 2 +- .../skins/lucene/xslt/html/site-to-xhtml.xsl | 66 ++++++++++++++++-- 12 files changed, 356 insertions(+), 41 deletions(-) diff --git a/solr/site/features.html b/solr/site/features.html index c39c23e4b84..b195d27f326 100755 --- a/solr/site/features.html +++ b/solr/site/features.html @@ -48,12 +48,12 @@ |start Search +-->

    From 3ba7eafdefc72c3013b285f4b9839786e5ab434e Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Fri, 7 Jan 2011 23:19:14 +0000 Subject: [PATCH 021/252] SOLR-2288: Small tweaks to eliminate compiler warnings git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056558 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 4 ++ .../apache/solr/common/util/JavaBinCodec.java | 34 +++++----- .../apache/solr/common/util/NamedList.java | 23 ++++--- .../java/org/apache/solr/core/SolrCore.java | 6 +- .../solr/handler/RequestHandlerBase.java | 4 +- .../handler/admin/SolrInfoMBeanHandler.java | 10 +-- .../handler/component/DebugComponent.java | 16 ++--- .../handler/component/FacetComponent.java | 31 +++++---- .../handler/component/TermsComponent.java | 14 +++-- .../PerSegmentSingleValuedFaceting.java | 14 ++--- .../org/apache/solr/request/SimpleFacets.java | 63 ++++++++++--------- .../apache/solr/request/UnInvertedField.java | 4 +- .../solr/response/SolrQueryResponse.java | 11 ++-- .../java/org/apache/solr/search/QParser.java | 13 ++-- .../apache/solr/search/SolrIndexSearcher.java | 4 +- 15 files changed, 137 insertions(+), 114 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0550efb3e84..7affd988920 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -686,6 +686,10 @@ Other Changes * SOLR-2289: Tweak spatial coords for example docs so they are a bit more spread out (Erick Erickson via hossman) +* SOLR-2288: Small tweaks to eliminate compiler warnings. primarily + using Generics where applicable in method/object declatations, and + adding @SuppressWarnings("unchecked") when appropriate (hossman) + Build ---------------------- diff --git a/solr/src/common/org/apache/solr/common/util/JavaBinCodec.java b/solr/src/common/org/apache/solr/common/util/JavaBinCodec.java index cb7836c1906..1a990098db8 100755 --- a/solr/src/common/org/apache/solr/common/util/JavaBinCodec.java +++ b/solr/src/common/org/apache/solr/common/util/JavaBinCodec.java @@ -102,9 +102,9 @@ public class JavaBinCodec { } - public SimpleOrderedMap readOrderedMap(FastInputStream dis) throws IOException { + public SimpleOrderedMap readOrderedMap(FastInputStream dis) throws IOException { int sz = readSize(dis); - SimpleOrderedMap nl = new SimpleOrderedMap(); + SimpleOrderedMap nl = new SimpleOrderedMap(); for (int i = 0; i < sz; i++) { String name = (String) readVal(dis); Object val = readVal(dis); @@ -113,9 +113,9 @@ public class JavaBinCodec { return nl; } - public NamedList readNamedList(FastInputStream dis) throws IOException { + public NamedList readNamedList(FastInputStream dis) throws IOException { int sz = readSize(dis); - NamedList nl = new NamedList(); + NamedList nl = new NamedList(); for (int i = 0; i < sz; i++) { String name = (String) readVal(dis); Object val = readVal(dis); @@ -124,7 +124,7 @@ public class JavaBinCodec { return nl; } - public void writeNamedList(NamedList nl) throws IOException { + public void writeNamedList(NamedList nl) throws IOException { writeTag(nl instanceof SimpleOrderedMap ? ORDERED_MAP : NAMED_LST, nl.size()); for (int i = 0; i < nl.size(); i++) { String name = nl.getName(i); @@ -218,7 +218,7 @@ public class JavaBinCodec { public boolean writeKnownType(Object val) throws IOException { if (writePrimitive(val)) return true; if (val instanceof NamedList) { - writeNamedList((NamedList) val); + writeNamedList((NamedList) val); return true; } if (val instanceof SolrDocumentList) { // SolrDocumentList is a List, so must come before List check @@ -336,7 +336,8 @@ public class JavaBinCodec { solrDocs.setStart((Long) list.get(1)); solrDocs.setMaxScore((Float) list.get(2)); - List l = (List) readVal(dis); + @SuppressWarnings("unchecked") + List l = (List) readVal(dis); solrDocs.addAll(l); return solrDocs; } @@ -344,7 +345,7 @@ public class JavaBinCodec { public void writeSolrDocumentList(SolrDocumentList docs) throws IOException { writeTag(SOLRDOCLST); - List l = new ArrayList(3); + List l = new ArrayList(3); l.add(docs.getNumFound()); l.add(docs.getStart()); l.add(docs.getMaxScore()); @@ -352,10 +353,10 @@ public class JavaBinCodec { writeArray(docs); } - public Map readMap(FastInputStream dis) + public Map readMap(FastInputStream dis) throws IOException { int sz = readVInt(dis); - Map m = new LinkedHashMap(); + Map m = new LinkedHashMap(); for (int i = 0; i < sz; i++) { Object key = readVal(dis); Object val = readVal(dis); @@ -373,8 +374,8 @@ public class JavaBinCodec { writeVal(END_OBJ); } - public List readIterator(FastInputStream fis) throws IOException { - ArrayList l = new ArrayList(); + public List readIterator(FastInputStream fis) throws IOException { + ArrayList l = new ArrayList(); while (true) { Object o = readVal(fis); if (o == END_OBJ) break; @@ -406,9 +407,9 @@ public class JavaBinCodec { } } - public List readArray(FastInputStream dis) throws IOException { + public List readArray(FastInputStream dis) throws IOException { int sz = readSize(dis); - ArrayList l = new ArrayList(sz); + ArrayList l = new ArrayList(sz); for (int i = 0; i < sz; i++) { l.add(readVal(dis)); } @@ -603,10 +604,9 @@ public class JavaBinCodec { } - public void writeMap(Map val) - throws IOException { + public void writeMap(Map val) throws IOException { writeTag(MAP, val.size()); - for (Map.Entry entry : (Set) val.entrySet()) { + for (Map.Entry entry : val.entrySet()) { Object key = entry.getKey(); if (key instanceof String) { writeExternString((String) key); diff --git a/solr/src/common/org/apache/solr/common/util/NamedList.java b/solr/src/common/org/apache/solr/common/util/NamedList.java index 046b4927afd..517b53d3b80 100644 --- a/solr/src/common/org/apache/solr/common/util/NamedList.java +++ b/solr/src/common/org/apache/solr/common/util/NamedList.java @@ -50,11 +50,11 @@ import java.io.Serializable; * @version $Id$ */ public class NamedList implements Cloneable, Serializable, Iterable> { - protected final List nvPairs; + protected final List nvPairs; /** Creates an empty instance */ public NamedList() { - nvPairs = new ArrayList(); + nvPairs = new ArrayList(); } @@ -88,7 +88,7 @@ public class NamedList implements Cloneable, Serializable, Iterable nameValuePairs) { nvPairs=nameValuePairs; } @@ -104,8 +104,8 @@ public class NamedList implements Cloneable, Serializable, Iterable[] nameValuePairs) { - List result = new ArrayList(); + private List nameValueMapToList(Map.Entry[] nameValuePairs) { + List result = new ArrayList(); for (Map.Entry ent : nameValuePairs) { result.add(ent.getKey()); result.add(ent.getValue()); @@ -158,6 +158,7 @@ public class NamedList implements Cloneable, Serializable, Iterable implements Cloneable, Serializable, Iterable implements Cloneable, Serializable, Iterableshallow copy of the named list. */ public NamedList clone() { - ArrayList newList = new ArrayList(nvPairs.size()); + ArrayList newList = new ArrayList(nvPairs.size()); newList.addAll(nvPairs); return new NamedList(newList); } @@ -330,7 +333,7 @@ public class NamedList implements Cloneable, Serializable, Iterable> iterator() { - final NamedList list = this; + final NamedList list = this; Iterator> iter = new Iterator>() { @@ -349,7 +352,7 @@ public class NamedList implements Cloneable, Serializable, Iterable implements Cloneable, Serializable, Iterable toLog = rsp.getToLog(); // for back compat, we set these now just in case other code // are expecting them during handleRequest toLog.add("webapp", req.getContext().get("webapp")); @@ -1312,7 +1312,7 @@ public final class SolrCore implements SolrInfoMBean { public static void setResponseHeaderValues(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp) { // TODO should check that responseHeader has not been replaced by handler - NamedList responseHeader = rsp.getResponseHeader(); + NamedList responseHeader = rsp.getResponseHeader(); final int qtime=(int)(rsp.getEndTime() - req.getStartTime()); int status = 0; Exception exception = rsp.getException(); @@ -1586,7 +1586,7 @@ public final class SolrCore implements SolrInfoMBean { } public NamedList getStatistics() { - NamedList lst = new SimpleOrderedMap(); + NamedList lst = new SimpleOrderedMap(); lst.add("coreName", name==null ? "(null)" : name); lst.add("startTime", new Date(startTime)); lst.add("refCount", getOpenCount()); diff --git a/solr/src/java/org/apache/solr/handler/RequestHandlerBase.java b/solr/src/java/org/apache/solr/handler/RequestHandlerBase.java index 30821a8b51f..3fe4e026906 100644 --- a/solr/src/java/org/apache/solr/handler/RequestHandlerBase.java +++ b/solr/src/java/org/apache/solr/handler/RequestHandlerBase.java @@ -168,8 +168,8 @@ public abstract class RequestHandlerBase implements SolrRequestHandler, SolrInfo return null; // this can be overridden, but not required } - public NamedList getStatistics() { - NamedList lst = new SimpleOrderedMap(); + public NamedList getStatistics() { + NamedList lst = new SimpleOrderedMap(); lst.add("handlerStart",handlerStart); lst.add("requests", numRequests); lst.add("errors", numErrors); diff --git a/solr/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java b/solr/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java index d927920f6c0..aa8d94c22d9 100644 --- a/solr/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java +++ b/solr/src/java/org/apache/solr/handler/admin/SolrInfoMBeanHandler.java @@ -35,17 +35,17 @@ public class SolrInfoMBeanHandler extends RequestHandlerBase { public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { SolrCore core = req.getCore(); - NamedList cats = new NamedList(); + NamedList>> cats = new NamedList>>(); rsp.add("solr-mbeans", cats); String[] requestedCats = req.getParams().getParams("cat"); if (null == requestedCats || 0 == requestedCats.length) { for (SolrInfoMBean.Category cat : SolrInfoMBean.Category.values()) { - cats.add(cat.name(), new SimpleOrderedMap()); + cats.add(cat.name(), new SimpleOrderedMap>()); } } else { for (String catName : requestedCats) { - cats.add(catName,new SimpleOrderedMap()); + cats.add(catName,new SimpleOrderedMap>()); } } @@ -58,10 +58,10 @@ public class SolrInfoMBeanHandler extends RequestHandlerBase { if ( ! ( requestedKeys.isEmpty() || requestedKeys.contains(key) ) ) continue; - NamedList catInfo = (NamedList) cats.get(m.getCategory().name()); + NamedList> catInfo = cats.get(m.getCategory().name()); if ( null == catInfo ) continue; - NamedList mBeanInfo = new SimpleOrderedMap(); + NamedList mBeanInfo = new SimpleOrderedMap(); mBeanInfo.add("class", m.getName()); mBeanInfo.add("version", m.getVersion()); mBeanInfo.add("description", m.getDescription()); diff --git a/solr/src/java/org/apache/solr/handler/component/DebugComponent.java b/solr/src/java/org/apache/solr/handler/component/DebugComponent.java index ed864cefc58..d105c054150 100644 --- a/solr/src/java/org/apache/solr/handler/component/DebugComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/DebugComponent.java @@ -115,7 +115,7 @@ public class DebugComponent extends SearchComponent @Override public void finishStage(ResponseBuilder rb) { if (rb.isDebug() && rb.stage == ResponseBuilder.STAGE_GET_FIELDS) { - NamedList info = null; + NamedList info = null; NamedList explain = new SimpleOrderedMap(); Map.Entry[] arr = new NamedList.NamedListEntry[rb.resultIds.size()]; @@ -140,11 +140,11 @@ public class DebugComponent extends SearchComponent } if (rb.isDebugResults()) { - explain = SolrPluginUtils.removeNulls(new SimpleOrderedMap(arr)); + explain = SolrPluginUtils.removeNulls(new SimpleOrderedMap(arr)); } if (info == null) { - info = new SimpleOrderedMap(); + info = new SimpleOrderedMap(); } if (rb.isDebugResults()) { int idx = info.indexOf("explain",0); @@ -196,9 +196,11 @@ public class DebugComponent extends SearchComponent if (source instanceof NamedList && dest instanceof NamedList) { - NamedList tmp = new NamedList(); - NamedList sl = (NamedList)source; - NamedList dl = (NamedList)dest; + NamedList tmp = new NamedList(); + @SuppressWarnings("unchecked") + NamedList sl = (NamedList)source; + @SuppressWarnings("unchecked") + NamedList dl = (NamedList)dest; for (int i=0; i t = new ArrayList(); t.add(dest); t.add(source); return t; diff --git a/solr/src/java/org/apache/solr/handler/component/FacetComponent.java b/solr/src/java/org/apache/solr/handler/component/FacetComponent.java index 7a85513867d..5b0098680e9 100644 --- a/solr/src/java/org/apache/solr/handler/component/FacetComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/FacetComponent.java @@ -78,7 +78,7 @@ public class FacetComponent extends SearchComponent params, rb ); - NamedList counts = f.getFacetCounts(); + NamedList counts = f.getFacetCounts(); String[] pivots = params.getParams( FacetParams.FACET_PIVOT ); if( pivots != null && pivots.length > 0 ) { NamedList v = pivotHelper.process(rb, params, pivots); @@ -264,7 +264,9 @@ public class FacetComponent extends SearchComponent int shardNum = rb.getShardNum(srsp.getShard()); NamedList facet_counts = (NamedList)srsp.getSolrResponse().getResponse().get("facet_counts"); - fi.addExceptions((List)facet_counts.get("exception")); + @SuppressWarnings("unchecked") + List excepts = (List)facet_counts.get("exception"); + fi.addExceptions(excepts); // handle facet queries NamedList facet_queries = (NamedList)facet_counts.get("facet_queries"); @@ -298,7 +300,10 @@ public class FacetComponent extends SearchComponent if (dff.limit <= 0) continue; // no need to check these facets for refinement if (dff.minCount <= 1 && dff.sort.equals(FacetParams.FACET_SORT_INDEX)) continue; - dff._toRefine = new List[rb.shards.length]; + @SuppressWarnings("unchecked") // generic array's are anoying + List[] tmp = (List[]) new List[rb.shards.length]; + dff._toRefine = tmp; + ShardFacetCount[] counts = dff.getCountSorted(); int ntop = Math.min(counts.length, dff.offset + dff.limit); long smallestCount = counts.length == 0 ? 0 : counts[ntop-1].count; @@ -353,8 +358,10 @@ public class FacetComponent extends SearchComponent // int shardNum = rb.getShardNum(srsp.shard); NamedList facet_counts = (NamedList)srsp.getSolrResponse().getResponse().get("facet_counts"); NamedList facet_fields = (NamedList)facet_counts.get("facet_fields"); - - fi.addExceptions((List)facet_counts.get("exception")); + + @SuppressWarnings("unchecked") + List excepts = (List)facet_counts.get("exception"); + fi.addExceptions(excepts); if (facet_fields == null) continue; // this can happen when there's an exception @@ -384,23 +391,23 @@ public class FacetComponent extends SearchComponent FacetInfo fi = rb._facetInfo; - NamedList facet_counts = new SimpleOrderedMap(); + NamedList facet_counts = new SimpleOrderedMap(); if (fi.exceptionList != null) { facet_counts.add("exception",fi.exceptionList); } - NamedList facet_queries = new SimpleOrderedMap(); + NamedList facet_queries = new SimpleOrderedMap(); facet_counts.add("facet_queries",facet_queries); for (QueryFacet qf : fi.queryFacets.values()) { facet_queries.add(qf.getKey(), num(qf.count)); } - NamedList facet_fields = new SimpleOrderedMap(); + NamedList facet_fields = new SimpleOrderedMap(); facet_counts.add("facet_fields", facet_fields); for (DistribFieldFacet dff : fi.facets.values()) { - NamedList fieldCounts = new NamedList(); // order is more important for facets + NamedList fieldCounts = new NamedList(); // order is more important for facets facet_fields.add(dff.getKey(), fieldCounts); ShardFacetCount[] counts; @@ -486,7 +493,7 @@ public class FacetComponent extends SearchComponent public static class FacetInfo { public LinkedHashMap queryFacets; public LinkedHashMap facets; - public List exceptionList; + public List exceptionList; void parse(SolrParams params, ResponseBuilder rb) { queryFacets = new LinkedHashMap(); @@ -510,9 +517,9 @@ public class FacetComponent extends SearchComponent } } - public void addExceptions(List exceptions) { + public void addExceptions(List exceptions) { if (exceptions == null) return; - if (exceptionList == null) exceptionList = new ArrayList(); + if (exceptionList == null) exceptionList = new ArrayList(); exceptionList.addAll(exceptions); } } diff --git a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java index 17aba9096f2..b0bf7c00e62 100644 --- a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java @@ -75,7 +75,7 @@ public class TermsComponent extends SearchComponent { String[] fields = params.getParams(TermsParams.TERMS_FIELD); - NamedList termsResult = new SimpleOrderedMap(); + NamedList termsResult = new SimpleOrderedMap(); rb.rsp.add("terms", termsResult); if (fields == null || fields.length==0) return; @@ -107,7 +107,7 @@ public class TermsComponent extends SearchComponent { Fields lfields = MultiFields.getFields(sr); for (String field : fields) { - NamedList fieldTerms = new NamedList(); + NamedList fieldTerms = new NamedList(); termsResult.add(field, fieldTerms); Terms terms = lfields == null ? null : lfields.terms(field); @@ -273,7 +273,9 @@ public class TermsComponent extends SearchComponent { TermsHelper th = rb._termsHelper; if (th != null) { for (ShardResponse srsp : sreq.responses) { - th.parse((NamedList) srsp.getSolrResponse().getResponse().get("terms")); + @SuppressWarnings("unchecked") + NamedList terms = (NamedList) srsp.getSolrResponse().getResponse().get("terms"); + th.parse(terms); } } } @@ -331,7 +333,7 @@ public class TermsComponent extends SearchComponent { } } - public void parse(NamedList terms) { + public void parse(NamedList terms) { // exit if there is no terms if (terms == null) { return; @@ -364,7 +366,7 @@ public class TermsComponent extends SearchComponent { } public NamedList buildResponse() { - NamedList response = new SimpleOrderedMap(); + NamedList response = new SimpleOrderedMap(); // determine if we are going index or count sort boolean sort = !TermsParams.TERMS_SORT_INDEX.equals(params.get( @@ -393,7 +395,7 @@ public class TermsComponent extends SearchComponent { // loop though each field we want terms from for (String key : fieldmap.keySet()) { - NamedList fieldterms = new SimpleOrderedMap(); + NamedList fieldterms = new SimpleOrderedMap(); TermsResponse.Term[] data = null; if (sort) { data = getCountSorted(fieldmap.get(key)); diff --git a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java index 24938cbb9c2..8743072d5da 100755 --- a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java +++ b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java @@ -63,7 +63,7 @@ class PerSegmentSingleValuedFaceting { } - NamedList getFacetCounts(Executor executor) throws IOException { + NamedList getFacetCounts(Executor executor) throws IOException { CompletionService completionService = new ExecutorCompletionService(executor); @@ -189,7 +189,7 @@ class PerSegmentSingleValuedFaceting { if (stop) break; } - NamedList res = collector.getFacetCounts(); + NamedList res = collector.getFacetCounts(); // convert labels to readable form FieldType ft = searcher.getSchema().getFieldType(fieldName); @@ -321,7 +321,7 @@ class PerSegmentSingleValuedFaceting { abstract class FacetCollector { /*** return true to stop collection */ public abstract boolean collect(BytesRef term, int count); - public abstract NamedList getFacetCounts(); + public abstract NamedList getFacetCounts(); } @@ -355,8 +355,8 @@ class CountSortedFacetCollector extends FacetCollector { } @Override - public NamedList getFacetCounts() { - NamedList res = new NamedList(); + public NamedList getFacetCounts() { + NamedList res = new NamedList(); int off=offset; int lim=limit>=0 ? limit : Integer.MAX_VALUE; // now select the right page from the results @@ -374,7 +374,7 @@ class IndexSortedFacetCollector extends FacetCollector { int offset; int limit; final int mincount; - final NamedList res = new NamedList(); + final NamedList res = new NamedList(); public IndexSortedFacetCollector(int offset, int limit, int mincount) { @@ -403,7 +403,7 @@ class IndexSortedFacetCollector extends FacetCollector { } @Override - public NamedList getFacetCounts() { + public NamedList getFacetCounts() { return res; } } diff --git a/solr/src/java/org/apache/solr/request/SimpleFacets.java b/solr/src/java/org/apache/solr/request/SimpleFacets.java index 3d06d57793a..15ef35d7c15 100644 --- a/solr/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/src/java/org/apache/solr/request/SimpleFacets.java @@ -70,7 +70,7 @@ public class SimpleFacets { protected SolrQueryRequest req; protected ResponseBuilder rb; - protected SimpleOrderedMap facetResponse; + protected SimpleOrderedMap facetResponse; // per-facet values SolrParams localParams; // localParams on this particular facet command @@ -175,13 +175,13 @@ public class SimpleFacets { * @see FacetParams#FACET * @return a NamedList of Facet Count info or null */ - public NamedList getFacetCounts() { + public NamedList getFacetCounts() { // if someone called this method, benefit of the doubt: assume true if (!params.getBool(FacetParams.FACET,true)) return null; - facetResponse = new SimpleOrderedMap(); + facetResponse = new SimpleOrderedMap(); try { facetResponse.add("facet_queries", getFacetQueryCounts()); facetResponse.add("facet_fields", getFacetFieldCounts()); @@ -196,9 +196,11 @@ public class SimpleFacets { } public void addException(String msg, Exception e) { - List exceptions = (List)facetResponse.get("exception"); + @SuppressWarnings("unchecked") + List exceptions = (List)facetResponse.get("exception"); + if (exceptions == null) { - exceptions = new ArrayList(); + exceptions = new ArrayList(); facetResponse.add("exception", exceptions); } @@ -212,9 +214,9 @@ public class SimpleFacets { * * @see FacetParams#FACET_QUERY */ - public NamedList getFacetQueryCounts() throws IOException,ParseException { + public NamedList getFacetQueryCounts() throws IOException,ParseException { - NamedList res = new SimpleOrderedMap(); + NamedList res = new SimpleOrderedMap(); /* Ignore CommonParams.DF - could have init param facet.query assuming * the schema default with query param DF intented to only affect Q. @@ -246,10 +248,10 @@ public class SimpleFacets { } - public NamedList getTermCounts(String field) throws IOException { + public NamedList getTermCounts(String field) throws IOException { int offset = params.getFieldInt(field, FacetParams.FACET_OFFSET, 0); int limit = params.getFieldInt(field, FacetParams.FACET_LIMIT, 100); - if (limit == 0) return new NamedList(); + if (limit == 0) return new NamedList(); Integer mincount = params.getFieldInt(field, FacetParams.FACET_MINCOUNT); if (mincount==null) { Boolean zeros = params.getFieldBool(field, FacetParams.FACET_ZEROS); @@ -263,7 +265,7 @@ public class SimpleFacets { String prefix = params.getFieldParam(field,FacetParams.FACET_PREFIX); - NamedList counts; + NamedList counts; SchemaField sf = searcher.getSchema().getField(field); FieldType ft = sf.getType(); @@ -335,10 +337,10 @@ public class SimpleFacets { * @see #getFieldMissingCount * @see #getFacetTermEnumCounts */ - public NamedList getFacetFieldCounts() + public NamedList getFacetFieldCounts() throws IOException, ParseException { - NamedList res = new SimpleOrderedMap(); + NamedList res = new SimpleOrderedMap(); String[] facetFs = params.getParams(FacetParams.FACET_FIELD); if (null != facetFs) { for (String f : facetFs) { @@ -361,10 +363,10 @@ public class SimpleFacets { } - private NamedList getListedTermCounts(String field, String termList) throws IOException { + private NamedList getListedTermCounts(String field, String termList) throws IOException { FieldType ft = searcher.getSchema().getFieldType(field); List terms = StrUtils.splitSmart(termList, ",", true); - NamedList res = new NamedList(); + NamedList res = new NamedList(); Term t = new Term(field); for (String term : terms) { String internal = ft.toInternal(term); @@ -394,7 +396,7 @@ public class SimpleFacets { * Use the Lucene FieldCache to get counts for each unique field value in docs. * The field must have at most one indexed token per document. */ - public static NamedList getFieldCacheCounts(SolrIndexSearcher searcher, DocSet docs, String fieldName, int offset, int limit, int mincount, boolean missing, String sort, String prefix) throws IOException { + public static NamedList getFieldCacheCounts(SolrIndexSearcher searcher, DocSet docs, String fieldName, int offset, int limit, int mincount, boolean missing, String sort, String prefix) throws IOException { // TODO: If the number of terms is high compared to docs.size(), and zeros==false, // we should use an alternate strategy to avoid // 1) creating another huge int[] for the counts @@ -409,7 +411,7 @@ public class SimpleFacets { // trying to pass all the various params around. FieldType ft = searcher.getSchema().getFieldType(fieldName); - NamedList res = new NamedList(); + NamedList res = new NamedList(); FieldCache.DocTermsIndex si = FieldCache.DEFAULT.getTermsIndex(searcher.getReader(), fieldName); @@ -589,7 +591,7 @@ public class SimpleFacets { * @see FacetParams#FACET_ZEROS * @see FacetParams#FACET_MISSING */ - public NamedList getFacetTermEnumCounts(SolrIndexSearcher searcher, DocSet docs, String field, int offset, int limit, int mincount, boolean missing, String sort, String prefix) + public NamedList getFacetTermEnumCounts(SolrIndexSearcher searcher, DocSet docs, String field, int offset, int limit, int mincount, boolean missing, String sort, String prefix) throws IOException { /* :TODO: potential optimization... @@ -615,7 +617,7 @@ public class SimpleFacets { boolean sortByCount = sort.equals("count") || sort.equals("true"); final int maxsize = limit>=0 ? offset+limit : Integer.MAX_VALUE-1; final BoundedTreeSet> queue = sortByCount ? new BoundedTreeSet>(maxsize) : null; - final NamedList res = new NamedList(); + final NamedList res = new NamedList(); int min=mincount-1; // the smallest value in the top 'N' values int off=offset; @@ -776,10 +778,10 @@ public class SimpleFacets { * @see FacetParams#FACET_DATE */ - public NamedList getFacetDateCounts() + public NamedList getFacetDateCounts() throws IOException, ParseException { - final NamedList resOuter = new SimpleOrderedMap(); + final NamedList resOuter = new SimpleOrderedMap(); final String[] fields = params.getParams(FacetParams.FACET_DATE); if (null == fields || 0 == fields.length) return resOuter; @@ -797,7 +799,7 @@ public class SimpleFacets { return resOuter; } - public void getFacetDateCounts(String dateFacet, NamedList resOuter) + public void getFacetDateCounts(String dateFacet, NamedList resOuter) throws IOException, ParseException { final IndexSchema schema = searcher.getSchema(); @@ -806,7 +808,7 @@ public class SimpleFacets { String f = facetValue; - final NamedList resInner = new SimpleOrderedMap(); + final NamedList resInner = new SimpleOrderedMap(); resOuter.add(key, resInner); final SchemaField sf = schema.getField(f); if (! (sf.getType() instanceof DateField)) { @@ -948,8 +950,8 @@ public class SimpleFacets { * @see FacetParams#FACET_RANGE */ - public NamedList getFacetRangeCounts() { - final NamedList resOuter = new SimpleOrderedMap(); + public NamedList getFacetRangeCounts() { + final NamedList resOuter = new SimpleOrderedMap(); final String[] fields = params.getParams(FacetParams.FACET_RANGE); if (null == fields || 0 == fields.length) return resOuter; @@ -967,7 +969,7 @@ public class SimpleFacets { return resOuter; } - void getFacetRangeCounts(String facetRange, NamedList resOuter) + void getFacetRangeCounts(String facetRange, NamedList resOuter) throws IOException, ParseException { final IndexSchema schema = searcher.getSchema(); @@ -978,7 +980,7 @@ public class SimpleFacets { final SchemaField sf = schema.getField(f); final FieldType ft = sf.getType(); - RangeEndpointCalculator calc = null; + RangeEndpointCalculator calc = null; if (ft instanceof TrieField) { final TrieField trie = (TrieField)ft; @@ -1025,8 +1027,8 @@ public class SimpleFacets { final RangeEndpointCalculator calc) throws IOException { final String f = sf.getName(); - final NamedList res = new SimpleOrderedMap(); - final NamedList counts = new SimpleOrderedMap(); + final NamedList res = new SimpleOrderedMap(); + final NamedList counts = new SimpleOrderedMap(); res.add("counts", counts); final T start = calc.getValue(required.getFieldParam(f,FacetParams.FACET_RANGE_START)); @@ -1176,8 +1178,9 @@ public class SimpleFacets { return key.hashCode() ^ val.hashCode(); } public boolean equals(Object o) { - return (o instanceof CountPair) - && (0 == this.compareTo((CountPair) o)); + if (! (o instanceof CountPair)) return false; + CountPair that = (CountPair) o; + return (this.key.equals(that.key) && this.val.equals(that.val)); } public int compareTo(CountPair o) { int vc = o.val.compareTo(val); diff --git a/solr/src/java/org/apache/solr/request/UnInvertedField.java b/solr/src/java/org/apache/solr/request/UnInvertedField.java index c92423e9c29..01fe7ae017d 100755 --- a/solr/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/src/java/org/apache/solr/request/UnInvertedField.java @@ -457,12 +457,12 @@ public class UnInvertedField { - public NamedList getCounts(SolrIndexSearcher searcher, DocSet baseDocs, int offset, int limit, Integer mincount, boolean missing, String sort, String prefix) throws IOException { + public NamedList getCounts(SolrIndexSearcher searcher, DocSet baseDocs, int offset, int limit, Integer mincount, boolean missing, String sort, String prefix) throws IOException { use.incrementAndGet(); FieldType ft = searcher.getSchema().getFieldType(field); - NamedList res = new NamedList(); // order is important + NamedList res = new NamedList(); // order is important DocSet docs = baseDocs; int baseSize = docs.size(); diff --git a/solr/src/java/org/apache/solr/response/SolrQueryResponse.java b/solr/src/java/org/apache/solr/response/SolrQueryResponse.java index fc3de1a7880..bbb2f1cd530 100644 --- a/solr/src/java/org/apache/solr/response/SolrQueryResponse.java +++ b/solr/src/java/org/apache/solr/response/SolrQueryResponse.java @@ -66,12 +66,12 @@ public class SolrQueryResponse { * @see #setAllValues * @see Note on Returnable Data */ - protected NamedList values = new SimpleOrderedMap(); + protected NamedList values = new SimpleOrderedMap(); /** * Container for storing information that should be logged by Solr before returning. */ - protected NamedList toLog = new SimpleOrderedMap(); + protected NamedList toLog = new SimpleOrderedMap(); protected Set defaultReturnFields; @@ -103,7 +103,7 @@ public class SolrQueryResponse { * Sets data to be returned in this response * @see Note on Returnable Data */ - public void setAllValues(NamedList nameValuePairs) { + public void setAllValues(NamedList nameValuePairs) { values=nameValuePairs; } @@ -189,7 +189,8 @@ public class SolrQueryResponse { } /** Repsonse header to be logged */ - public NamedList getResponseHeader() { + public NamedList getResponseHeader() { + @SuppressWarnings("unchecked") SimpleOrderedMap header = (SimpleOrderedMap) values.get("responseHeader"); return header; } @@ -207,7 +208,7 @@ public class SolrQueryResponse { * * @return things to log */ - public NamedList getToLog() { + public NamedList getToLog() { return toLog; } diff --git a/solr/src/java/org/apache/solr/search/QParser.java b/solr/src/java/org/apache/solr/search/QParser.java index 52254858d17..9b845e65d7e 100755 --- a/solr/src/java/org/apache/solr/search/QParser.java +++ b/solr/src/java/org/apache/solr/search/QParser.java @@ -63,10 +63,11 @@ public abstract class QParser { if (localParams != null) { String tagStr = localParams.get(CommonParams.TAG); if (tagStr != null) { - Map context = req.getContext(); - Map> tagMap = (Map>)req.getContext().get("tags"); + Map context = req.getContext(); + @SuppressWarnings("unchecked") + Map> tagMap = (Map>)req.getContext().get("tags"); if (tagMap == null) { - tagMap = new HashMap>(); + tagMap = new HashMap>(); context.put("tags", tagMap); } if (tagStr.indexOf(',') >= 0) { @@ -85,10 +86,10 @@ public abstract class QParser { } - private static void addTag(Map tagMap, Object key, Object val) { - Collection lst = (Collection)tagMap.get(key); + private static void addTag(Map> tagMap, Object key, Object val) { + Collection lst = tagMap.get(key); if (lst == null) { - lst = new ArrayList(2); + lst = new ArrayList(2); tagMap.put(key, lst); } lst.add(val); diff --git a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java index d7dcff8525b..a3183f6be5b 100644 --- a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -1767,8 +1767,8 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { return null; } - public NamedList getStatistics() { - NamedList lst = new SimpleOrderedMap(); + public NamedList getStatistics() { + NamedList lst = new SimpleOrderedMap(); lst.add("searcherName", name); lst.add("caching", cachingEnabled); lst.add("numDocs", reader.numDocs()); From 44b5ae0b6905fd4e7b2cc927b4c29c383a28ae47 Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Fri, 7 Jan 2011 23:57:11 +0000 Subject: [PATCH 022/252] revert an inadvertant javac change yonik made in r1052540 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056564 13f79535-47bb-0310-9956-ffa450edef68 --- solr/common-build.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/solr/common-build.xml b/solr/common-build.xml index b63ba6e1a54..f7367a506a0 100644 --- a/solr/common-build.xml +++ b/solr/common-build.xml @@ -270,6 +270,7 @@ includeAntRuntime="${javac.includeAntRuntime}" sourcepath="" classpathref="@{classpathref}"> + From cd90c9a911f3a1e2788d5396f43d6a07dc1895fe Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Sat, 8 Jan 2011 00:59:11 +0000 Subject: [PATCH 023/252] SOLR-2288: more small tweaks to eliminate compiler warnings git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056578 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/common/util/ConcurrentLRUCache.java | 32 +++++++++++-------- .../solr/common/util/SimpleOrderedMap.java | 4 +-- .../handler/component/TermsComponent.java | 4 +-- .../client/solrj/response/FieldStatsInfo.java | 2 ++ .../client/solrj/response/QueryResponse.java | 12 +++---- .../solrj/response/SpellCheckResponse.java | 26 +++++++++------ .../client/solrj/response/TermsResponse.java | 6 ++-- 7 files changed, 50 insertions(+), 36 deletions(-) diff --git a/solr/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java b/solr/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java index ed352f2e186..a3ca8be6264 100644 --- a/solr/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java +++ b/solr/src/common/org/apache/solr/common/util/ConcurrentLRUCache.java @@ -20,6 +20,8 @@ import org.apache.lucene.util.PriorityQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeSet; @@ -182,6 +184,7 @@ public class ConcurrentLRUCache { int wantToKeep = lowerWaterMark; int wantToRemove = sz - lowerWaterMark; + @SuppressWarnings("unchecked") // generic array's are anoying CacheEntry[] eset = new CacheEntry[sz]; int eSize = 0; @@ -280,7 +283,7 @@ public class ConcurrentLRUCache { wantToKeep = lowerWaterMark - numKept; wantToRemove = sz - lowerWaterMark - numRemoved; - PQueue queue = new PQueue(wantToRemove); + PQueue queue = new PQueue(wantToRemove); for (int i=eSize-1; i>=0; i--) { CacheEntry ce = eset[i]; @@ -331,9 +334,8 @@ public class ConcurrentLRUCache { // Now delete everything in the priority queue. // avoid using pop() since order doesn't matter anymore - for (Object o : queue.getValues()) { - if (o==null) continue; - CacheEntry ce = (CacheEntry)o; + for (CacheEntry ce : queue.getValues()) { + if (ce==null) continue; evictEntry(ce.key); numRemoved++; } @@ -349,27 +351,29 @@ public class ConcurrentLRUCache { } } - private static class PQueue extends PriorityQueue { + private static class PQueue extends PriorityQueue> { int myMaxSize; PQueue(int maxSz) { super.initialize(maxSz); myMaxSize = maxSz; } - Object[] getValues() { return heap; } + Iterable> getValues() { + return Collections.unmodifiableCollection(Arrays.asList(heap)); + } - protected boolean lessThan(Object a, Object b) { + protected boolean lessThan(CacheEntry a, CacheEntry b) { // reverse the parameter order so that the queue keeps the oldest items - return ((CacheEntry)b).lastAccessedCopy < ((CacheEntry)a).lastAccessedCopy; + return b.lastAccessedCopy < a.lastAccessedCopy; } // necessary because maxSize is private in base class - public Object myInsertWithOverflow(Object element) { + public CacheEntry myInsertWithOverflow(CacheEntry element) { if (size() < myMaxSize) { add(element); return null; } else if (size() > 0 && !lessThan(element, heap[1])) { - Object ret = heap[1]; + CacheEntry ret = heap[1]; heap[1] = element; updateTop(); return ret; @@ -400,11 +404,11 @@ public class ConcurrentLRUCache { Map result = new LinkedHashMap(); if (n <= 0) return result; - TreeSet tree = new TreeSet(); + TreeSet> tree = new TreeSet>(); markAndSweepLock.lock(); try { for (Map.Entry> entry : map.entrySet()) { - CacheEntry ce = entry.getValue(); + CacheEntry ce = entry.getValue(); ce.lastAccessedCopy = ce.lastAccessed; if (tree.size() < n) { tree.add(ce); @@ -418,7 +422,7 @@ public class ConcurrentLRUCache { } finally { markAndSweepLock.unlock(); } - for (CacheEntry e : tree) { + for (CacheEntry e : tree) { result.put(e.key, e.value); } return result; @@ -428,7 +432,7 @@ public class ConcurrentLRUCache { Map result = new LinkedHashMap(); if (n <= 0) return result; - TreeSet tree = new TreeSet(); + TreeSet> tree = new TreeSet>(); // we need to grab the lock since we are changing lastAccessedCopy markAndSweepLock.lock(); try { diff --git a/solr/src/common/org/apache/solr/common/util/SimpleOrderedMap.java b/solr/src/common/org/apache/solr/common/util/SimpleOrderedMap.java index e00938b8e86..01ed9cefdce 100755 --- a/solr/src/common/org/apache/solr/common/util/SimpleOrderedMap.java +++ b/solr/src/common/org/apache/solr/common/util/SimpleOrderedMap.java @@ -50,7 +50,7 @@ public class SimpleOrderedMap extends NamedList { * @param nameValuePairs underlying List which should be used to implement a SimpleOrderedMap; modifying this List will affect the SimpleOrderedMap. */ @Deprecated - public SimpleOrderedMap(List nameValuePairs) { + public SimpleOrderedMap(List nameValuePairs) { super(nameValuePairs); } @@ -60,7 +60,7 @@ public class SimpleOrderedMap extends NamedList { @Override public SimpleOrderedMap clone() { - ArrayList newList = new ArrayList(nvPairs.size()); + ArrayList newList = new ArrayList(nvPairs.size()); newList.addAll(nvPairs); return new SimpleOrderedMap(newList); } diff --git a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java index b0bf7c00e62..ee2e51f1f51 100644 --- a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java @@ -274,7 +274,7 @@ public class TermsComponent extends SearchComponent { if (th != null) { for (ShardResponse srsp : sreq.responses) { @SuppressWarnings("unchecked") - NamedList terms = (NamedList) srsp.getSolrResponse().getResponse().get("terms"); + NamedList> terms = (NamedList>) srsp.getSolrResponse().getResponse().get("terms"); th.parse(terms); } } @@ -333,7 +333,7 @@ public class TermsComponent extends SearchComponent { } } - public void parse(NamedList terms) { + public void parse(NamedList> terms) { // exit if there is no terms if (terms == null) { return; diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/FieldStatsInfo.java b/solr/src/solrj/org/apache/solr/client/solrj/response/FieldStatsInfo.java index aa35c7d6ac4..f2064dd5b3c 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/FieldStatsInfo.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/FieldStatsInfo.java @@ -74,11 +74,13 @@ public class FieldStatsInfo implements Serializable { stddev = (Double)entry.getValue(); } else if( "facets".equals( entry.getKey() ) ) { + @SuppressWarnings("unchecked") NamedList fields = (NamedList)entry.getValue(); facets = new HashMap>(); for( Map.Entry ev : fields ) { List vals = new ArrayList(); facets.put( ev.getKey(), vals ); + @SuppressWarnings("unchecked") NamedList> vnl = (NamedList>) ev.getValue(); for( int i=0; i _facetInfo = null; private NamedList _debugInfo = null; private NamedList _highlightingInfo = null; - private NamedList _spellInfo = null; + private NamedList> _spellInfo = null; private NamedList _statsInfo = null; - private NamedList _termsInfo = null; + private NamedList> _termsInfo = null; // Facet stuff private Map _facetQuery = null; @@ -116,7 +116,7 @@ public class QueryResponse extends SolrResponseBase extractHighlightingInfo( _highlightingInfo ); } else if ( "spellcheck".equals( n ) ) { - _spellInfo = (NamedList) res.getVal( i ); + _spellInfo = (NamedList>) res.getVal( i ); extractSpellCheckInfo( _spellInfo ); } else if ( "stats".equals( n ) ) { @@ -124,17 +124,17 @@ public class QueryResponse extends SolrResponseBase extractStatsInfo( _statsInfo ); } else if ( "terms".equals( n ) ) { - _termsInfo = (NamedList) res.getVal( i ); + _termsInfo = (NamedList>) res.getVal( i ); extractTermsInfo( _termsInfo ); } } } - private void extractSpellCheckInfo(NamedList spellInfo) { + private void extractSpellCheckInfo(NamedList> spellInfo) { _spellResponse = new SpellCheckResponse(spellInfo); } - private void extractTermsInfo(NamedList termsInfo) { + private void extractTermsInfo(NamedList> termsInfo) { _termsResponse = new TermsResponse(termsInfo); } diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/SpellCheckResponse.java b/solr/src/solrj/org/apache/solr/client/solrj/response/SpellCheckResponse.java index 25eb3c71c88..e4001ec19c6 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/SpellCheckResponse.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/SpellCheckResponse.java @@ -35,8 +35,8 @@ public class SpellCheckResponse { private List suggestions = new ArrayList(); Map suggestionMap = new LinkedHashMap(); - public SpellCheckResponse(NamedList spellInfo) { - NamedList sugg = (NamedList) spellInfo.get("suggestions"); + public SpellCheckResponse(NamedList> spellInfo) { + NamedList sugg = spellInfo.get("suggestions"); if (sugg == null) { correctlySpelled = true; return; @@ -55,12 +55,14 @@ public class SpellCheckResponse { collations.add(new Collation() .setCollationQueryString((String) sugg.getVal(i))); } else if (o instanceof NamedList) { - NamedList expandedCollation = (NamedList) o; - String collationQuery = (String) expandedCollation - .get("collationQuery"); + @SuppressWarnings("unchecked") + NamedList expandedCollation = (NamedList) o; + String collationQuery + = (String) expandedCollation.get("collationQuery"); int hits = (Integer) expandedCollation.get("hits"); - NamedList misspellingsAndCorrections = (NamedList) expandedCollation - .get("misspellingsAndCorrections"); + @SuppressWarnings("unchecked") + NamedList misspellingsAndCorrections + = (NamedList) expandedCollation.get("misspellingsAndCorrections"); Collation collation = new Collation(); collation.setCollationQueryString(collationQuery); @@ -79,6 +81,7 @@ public class SpellCheckResponse { } } } else { + @SuppressWarnings("unchecked") Suggestion s = new Suggestion(n, (NamedList) sugg.getVal(i)); suggestionMap.put(n, s); suggestions.add(s); @@ -152,16 +155,21 @@ public class SpellCheckResponse { } else if ("origFreq".equals(n)) { originalFrequency = (Integer) suggestion.getVal(i); } else if ("suggestion".equals(n)) { + @SuppressWarnings("unchecked") List list = (List)suggestion.getVal(i); if (list.size() > 0 && list.get(0) instanceof NamedList) { // extended results detected + @SuppressWarnings("unchecked") + List extended = (List)list; alternativeFrequencies = new ArrayList(); - for (NamedList nl : (List)list) { + for (NamedList nl : extended) { alternatives.add((String)nl.get("word")); alternativeFrequencies.add((Integer)nl.get("freq")); } } else { - alternatives.addAll(list); + @SuppressWarnings("unchecked") + List alts = (List) list; + alternatives.addAll(alts); } } } diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/TermsResponse.java b/solr/src/solrj/org/apache/solr/client/solrj/response/TermsResponse.java index f0b28b405c2..0924a1041f1 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/TermsResponse.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/TermsResponse.java @@ -29,14 +29,14 @@ import java.util.Map; public class TermsResponse { private Map> termMap = new HashMap>(); - public TermsResponse(NamedList termsInfo) { + public TermsResponse(NamedList> termsInfo) { for (int i = 0; i < termsInfo.size(); i++) { String fieldName = termsInfo.getName(i); List itemList = new ArrayList(); - NamedList items = (NamedList) termsInfo.getVal(i); + NamedList items = termsInfo.getVal(i); for (int j = 0; j < items.size(); j++) { - Term t = new Term(items.getName(j), ((Number) items.getVal(j)).longValue()); + Term t = new Term(items.getName(j), items.getVal(j).longValue()); itemList.add(t); } From 1aa40cd3953ea1e5863eb830f3529da6a3223498 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 8 Jan 2011 01:17:43 +0000 Subject: [PATCH 024/252] LUCENE-2831: attempt to use the correct reader context rather than doing getTopReaderContext on a leaf git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056585 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/schema/LatLonType.java | 4 +- .../java/org/apache/solr/search/Grouping.java | 2 +- .../solr/search/SolrConstantScoreQuery.java | 2 +- .../apache/solr/search/ValueSourceParser.java | 2 - .../solr/search/function/BoostedQuery.java | 2 +- .../solr/search/function/FunctionQuery.java | 2 +- .../search/function/QueryValueSource.java | 29 ++++++++++--- .../solr/search/function/ValueSource.java | 43 ++++++++++++++++++- .../apache/solr/search/TestIndexSearcher.java | 2 +- 9 files changed, 72 insertions(+), 16 deletions(-) diff --git a/solr/src/java/org/apache/solr/schema/LatLonType.java b/solr/src/java/org/apache/solr/schema/LatLonType.java index c76187fd325..75694f7eaa9 100644 --- a/solr/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/src/java/org/apache/solr/schema/LatLonType.java @@ -342,8 +342,8 @@ class SpatialDistanceQuery extends Query { public SpatialWeight(IndexSearcher searcher) throws IOException { this.searcher = searcher; - this.latContext = latSource.newContext(); - this.lonContext = lonSource.newContext(); + this.latContext = latSource.newContext(searcher); + this.lonContext = lonSource.newContext(searcher); latSource.createWeight(latContext, searcher); lonSource.createWeight(lonContext, searcher); } diff --git a/solr/src/java/org/apache/solr/search/Grouping.java b/solr/src/java/org/apache/solr/search/Grouping.java index f76616adfbf..c46d25ea4b5 100755 --- a/solr/src/java/org/apache/solr/search/Grouping.java +++ b/solr/src/java/org/apache/solr/search/Grouping.java @@ -151,7 +151,7 @@ public class Grouping { @Override void prepare() throws IOException { - Map context = ValueSource.newContext(); + Map context = ValueSource.newContext(searcher); groupBy.createWeight(context, searcher); } diff --git a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java index 422f5926199..0c5179e3d8e 100755 --- a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java +++ b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java @@ -62,7 +62,7 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery { public ConstantWeight(IndexSearcher searcher) throws IOException { this.similarity = getSimilarity(searcher); - this.context = ValueSource.newContext(); + this.context = ValueSource.newContext(searcher); if (filter instanceof SolrFilter) ((SolrFilter)filter).createWeight(context, searcher); } diff --git a/solr/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/src/java/org/apache/solr/search/ValueSourceParser.java index f9ceb1feec6..116058fc301 100755 --- a/solr/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/src/java/org/apache/solr/search/ValueSourceParser.java @@ -890,8 +890,6 @@ abstract class Double2Parser extends NamedParser { @Override public void createWeight(Map context, IndexSearcher searcher) throws IOException { - a.createWeight(context,searcher); - b.createWeight(context,searcher); } public int hashCode() { diff --git a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java index c1ea5e97870..9530484fe99 100755 --- a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -66,7 +66,7 @@ public class BoostedQuery extends Query { public BoostedWeight(IndexSearcher searcher) throws IOException { this.searcher = searcher; this.qWeight = q.weight(searcher); - this.context = boostVal.newContext(); + this.context = boostVal.newContext(searcher); boostVal.createWeight(context,searcher); } diff --git a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java index 397798f064e..1a6ad49bb6e 100644 --- a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java +++ b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java @@ -67,7 +67,7 @@ public class FunctionQuery extends Query { public FunctionWeight(IndexSearcher searcher) throws IOException { this.searcher = searcher; - this.context = func.newContext(); + this.context = func.newContext(searcher); func.createWeight(context, searcher); } diff --git a/solr/src/java/org/apache/solr/search/function/QueryValueSource.java b/solr/src/java/org/apache/solr/search/function/QueryValueSource.java index cf65b3968fe..b3b0c66b44d 100755 --- a/solr/src/java/org/apache/solr/search/function/QueryValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/QueryValueSource.java @@ -44,8 +44,8 @@ public class QueryValueSource extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - return new QueryDocValues(reader, q, defVal, context==null ? null : (Weight)context.get(this)); + public DocValues getValues(Map fcontext, IndexReader reader) throws IOException { + return new QueryDocValues(reader, q, defVal, fcontext); } public int hashCode() { @@ -71,6 +71,7 @@ class QueryDocValues extends DocValues { final IndexReader reader; final Weight weight; final float defVal; + final Map fcontext; Scorer scorer; int scorerDoc; // the document the scorer is on @@ -79,18 +80,36 @@ class QueryDocValues extends DocValues { // to trigger a scorer reset on first access. int lastDocRequested=Integer.MAX_VALUE; - public QueryDocValues(IndexReader reader, Query q, float defVal, Weight w) throws IOException { + public QueryDocValues(IndexReader reader, Query q, float defVal, Map fcontext) throws IOException { this.reader = reader; this.q = q; this.defVal = defVal; - weight = w!=null ? w : q.weight(new IndexSearcher(reader)); + this.fcontext = fcontext; + + Weight w = fcontext==null ? null : (Weight)fcontext.get(q); + if (w == null) { + IndexSearcher weightSearcher = fcontext == null ? new IndexSearcher(reader) : (IndexSearcher)fcontext.get("searcher"); + + // TODO: sort by function doesn't weight (SOLR-1297 is open because of this bug)... so weightSearcher will currently be null + if (weightSearcher == null) weightSearcher = new IndexSearcher(reader); + + w = q.weight(weightSearcher); + } + weight = w; } public float floatVal(int doc) { try { if (doc < lastDocRequested) { // out-of-order access.... reset scorer. - scorer = weight.scorer(reader.getTopReaderContext(), true, false); + IndexReader.AtomicReaderContext ctx = ValueSource.readerToContext(fcontext, reader); + + if (ctx == null) { + // TODO: this is because SOLR-1297 does not weight + ctx = (IndexReader.AtomicReaderContext)reader.getTopReaderContext(); // this is the incorrect context + } + + scorer = weight.scorer(ctx, true, false); if (scorer==null) return defVal; scorerDoc = -1; } diff --git a/solr/src/java/org/apache/solr/search/function/ValueSource.java b/solr/src/java/org/apache/solr/search/function/ValueSource.java index 48a56ce15cf..daaffd65504 100644 --- a/solr/src/java/org/apache/solr/search/function/ValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/ValueSource.java @@ -18,6 +18,8 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparatorSource; import org.apache.lucene.search.Scorer; @@ -25,6 +27,7 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.SortField; import org.apache.lucene.util.Bits; import org.apache.lucene.index.MultiFields; +import org.apache.solr.common.SolrException; import java.io.IOException; import java.io.Serializable; @@ -90,10 +93,46 @@ public abstract class ValueSource implements Serializable { /** * Returns a new non-threadsafe context map. */ - public static Map newContext() { - return new IdentityHashMap(); + public static Map newContext(IndexSearcher searcher) { + Map context = new IdentityHashMap(); + context.put("searcher", searcher); + return context; } + /* @lucene.internal + * This will most likely go away in the future. + */ + public static AtomicReaderContext readerToContext(Map fcontext, IndexReader reader) { + Object v = fcontext.get(reader); + if (v == null) { + IndexSearcher searcher = (IndexSearcher)fcontext.get("searcher"); + if (searcher == null) { + return null; + // TODO + // throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "no searcher found in function context"); + } + ReaderContext rcontext = searcher.getIndexReader().getTopReaderContext(); + if (rcontext.isAtomic) { + assert rcontext.reader == reader; + fcontext.put(rcontext.reader, (AtomicReaderContext)rcontext); + } else { + for (AtomicReaderContext subCtx : rcontext.leaves()) { + fcontext.put(subCtx.reader, subCtx); + } + } + + v = fcontext.get(reader); + if (v == null) { + return null; + // TODO + // throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "reader " + reader + " is not from the top reader " + searcher.getIndexReader()); + } + } + + return (AtomicReaderContext)v; + } + + class ValueSourceComparatorSource extends FieldComparatorSource { diff --git a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java index 8b0f0edecf6..4ecd72df623 100755 --- a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java +++ b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java @@ -36,7 +36,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { private String getStringVal(SolrQueryRequest sqr, String field, int doc) throws IOException { SchemaField sf = sqr.getSchema().getField(field); ValueSource vs = sf.getType().getValueSource(sf, null); - Map context = ValueSource.newContext(); + Map context = ValueSource.newContext(sqr.getSearcher()); vs.createWeight(context, sqr.getSearcher()); SolrIndexReader sr = sqr.getSearcher().getReader(); int idx = SolrIndexReader.readerIndex(doc, sr.getLeafOffsets()); From 071104c07d2db5b10b014754d0b7c585463d5e60 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 8 Jan 2011 01:37:07 +0000 Subject: [PATCH 025/252] LUCENE-2831: attempt to use the correct reader context rather than doing getTopReaderContext on a leaf git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056588 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/search/function/BoostedQuery.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java index 9530484fe99..963a776d3a0 100755 --- a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -61,13 +61,13 @@ public class BoostedQuery extends Query { private class BoostedWeight extends Weight { IndexSearcher searcher; Weight qWeight; - Map context; + Map fcontext; public BoostedWeight(IndexSearcher searcher) throws IOException { this.searcher = searcher; this.qWeight = q.weight(searcher); - this.context = boostVal.newContext(searcher); - boostVal.createWeight(context,searcher); + this.fcontext = boostVal.newContext(searcher); + boostVal.createWeight(fcontext,searcher); } public Query getQuery() { @@ -106,7 +106,7 @@ public class BoostedQuery extends Query { if (!subQueryExpl.isMatch()) { return subQueryExpl; } - DocValues vals = boostVal.getValues(context, readerContext.reader); + DocValues vals = boostVal.getValues(fcontext, readerContext.reader); float sc = subQueryExpl.getValue() * vals.floatVal(doc); Explanation res = new ComplexExplanation( true, sc, BoostedQuery.this.toString() + ", product of:"); @@ -133,7 +133,7 @@ public class BoostedQuery extends Query { this.scorer = scorer; this.reader = reader; this.searcher = searcher; // for explain - this.vals = vs.getValues(weight.context, reader); + this.vals = vs.getValues(weight.fcontext, reader); } @Override @@ -162,7 +162,7 @@ public class BoostedQuery extends Query { } public Explanation explain(int doc) throws IOException { - Explanation subQueryExpl = weight.qWeight.explain(reader.getTopReaderContext() ,doc); + Explanation subQueryExpl = weight.qWeight.explain(ValueSource.readerToContext(weight.fcontext,reader) ,doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } From abfa458e2a082eb0f1f7e53d495e0c399499e07d Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 8 Jan 2011 01:45:08 +0000 Subject: [PATCH 026/252] LUCENE-2831: remove another erroneous use of a non-atomic context git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056589 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/search/SolrIndexSearcher.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java index a3183f6be5b..a011acf4f01 100644 --- a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -898,22 +898,6 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { return positive ? getDocSetNC(absQ,filter) : filter.andNot(getPositiveDocSet(absQ)); } - - /** - * Converts a filter into a DocSet. - * This method is not cache-aware and no caches are checked. - */ - public DocSet convertFilter(Filter lfilter) throws IOException { - DocIdSet docSet = lfilter.getDocIdSet(this.reader.getTopReaderContext()); - OpenBitSet obs = new OpenBitSet(); - DocIdSetIterator it = docSet.iterator(); - int doc; - while((doc = it.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS) { - obs.fastSet(doc); - } - return new BitDocSet(obs); - } - /** * Returns documents matching both query and filter * and sorted by sort. From 98b448aa8cf393379246c04cdc827646860b4713 Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Sat, 8 Jan 2011 01:58:15 +0000 Subject: [PATCH 027/252] SOLR-2288: more small tweaks to eliminate compiler warnings .. inlcudes a small code de-dup refactoring in FieldAnalysisResponse git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056594 13f79535-47bb-0310-9956-ffa450edef68 --- .../solrj/response/AnalysisResponseBase.java | 10 ++--- .../response/DocumentAnalysisResponse.java | 28 ++++++++----- .../solrj/response/FieldAnalysisResponse.java | 42 +++++++++---------- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/AnalysisResponseBase.java b/solr/src/solrj/org/apache/solr/client/solrj/response/AnalysisResponseBase.java index f98d2a0b364..55d87d4fbe8 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/AnalysisResponseBase.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/AnalysisResponseBase.java @@ -62,12 +62,12 @@ public class AnalysisResponseBase extends SolrResponseBase { * * @return The built analysis phases list. */ - protected List buildPhases(NamedList phaseNL) { + protected List buildPhases(NamedList>> phaseNL) { List phases = new ArrayList(phaseNL.size()); - for (Map.Entry phaseEntry : phaseNL) { + for (Map.Entry>> phaseEntry : phaseNL) { AnalysisPhase phase = new AnalysisPhase(phaseEntry.getKey()); - List tokens = (List) phaseEntry.getValue(); - for (NamedList token : tokens) { + List> tokens = phaseEntry.getValue(); + for (NamedList token : tokens) { TokenInfo tokenInfo = buildTokenInfo(token); phase.addTokenInfo(tokenInfo); } @@ -95,7 +95,7 @@ public class AnalysisResponseBase extends SolrResponseBase { * * @return The built token info. */ - protected TokenInfo buildTokenInfo(NamedList tokenNL) { + protected TokenInfo buildTokenInfo(NamedList tokenNL) { String text = (String) tokenNL.get("text"); String rawText = (String) tokenNL.get("rawText"); String type = (String) tokenNL.get("type"); diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java b/solr/src/solrj/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java index 9cc66b9f384..f0d5dff787e 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/DocumentAnalysisResponse.java @@ -42,24 +42,30 @@ public class DocumentAnalysisResponse extends AnalysisResponseBase implements It public void setResponse(NamedList response) { super.setResponse(response); - NamedList analysis = (NamedList) response.get("analysis"); - for (Map.Entry documentEntry : analysis) { - DocumentAnalysis documentAnalysis = new DocumentAnalysis(documentEntry.getKey()); - NamedList document = (NamedList) documentEntry.getValue(); - for (Map.Entry fieldEntry : document) { + @SuppressWarnings("unchecked") + NamedList>> analysis + = (NamedList>>) response.get("analysis"); + for (Map.Entry>> document : analysis) { + DocumentAnalysis documentAnalysis = new DocumentAnalysis(document.getKey()); + for (Map.Entry> fieldEntry : document.getValue()) { FieldAnalysis fieldAnalysis = new FieldAnalysis(fieldEntry.getKey()); - NamedList field = (NamedList) fieldEntry.getValue(); - NamedList query = (NamedList) field.get("query"); + NamedList field = fieldEntry.getValue(); + + @SuppressWarnings("unchecked") + NamedList>> query + = (NamedList>>) field.get("query"); if (query != null) { List phases = buildPhases(query); fieldAnalysis.setQueryPhases(phases); } - - NamedList index = (NamedList) field.get("index"); - for (Map.Entry valueEntry : index) { + + @SuppressWarnings("unchecked") + NamedList>>> index + = (NamedList>>>) field.get("index"); + for (Map.Entry>>> valueEntry : index) { String fieldValue = valueEntry.getKey(); - NamedList valueNL = (NamedList) valueEntry.getValue(); + NamedList>> valueNL = valueEntry.getValue(); List phases = buildPhases(valueNL); fieldAnalysis.setIndexPhases(fieldValue, phases); } diff --git a/solr/src/solrj/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java b/solr/src/solrj/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java index 722c2c96cc8..e7343647db8 100644 --- a/solr/src/solrj/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java +++ b/solr/src/solrj/org/apache/solr/client/solrj/response/FieldAnalysisResponse.java @@ -42,35 +42,35 @@ public class FieldAnalysisResponse extends AnalysisResponseBase { public void setResponse(NamedList response) { super.setResponse(response); - NamedList analysisNL = (NamedList) response.get("analysis"); + @SuppressWarnings("unchecked") + NamedList>>>>> analysisNL + = (NamedList>>>>>) response.get("analysis"); - NamedList fieldTypesNL = (NamedList) analysisNL.get("field_types"); - for (Map.Entry entry : fieldTypesNL) { - Analysis analysis = new Analysis(); - NamedList fieldTypeNL = (NamedList) entry.getValue(); - NamedList queryNL = (NamedList) fieldTypeNL.get("query"); - List phases = (queryNL == null) ? null : buildPhases(queryNL); - analysis.setQueryPhases(phases); - NamedList indexNL = (NamedList) fieldTypeNL.get("index"); - phases = buildPhases(indexNL); - analysis.setIndexPhases(phases); - String fieldTypeName = entry.getKey(); - analysisByFieldTypeName.put(fieldTypeName, analysis); + for (Map.Entry>>>> entry + : analysisNL.get("field_types")) { + + analysisByFieldTypeName.put(entry.getKey(), buildAnalysis(entry.getValue())); } - NamedList fieldNamesNL = (NamedList) analysisNL.get("field_names"); - for (Map.Entry entry : fieldNamesNL) { + for (Map.Entry>>>> entry + : analysisNL.get("field_names")) { + + analysisByFieldName.put(entry.getKey(), buildAnalysis(entry.getValue())); + } + } + + private Analysis buildAnalysis(NamedList>>> value) { Analysis analysis = new Analysis(); - NamedList fieldNameNL = (NamedList) entry.getValue(); - NamedList queryNL = (NamedList) fieldNameNL.get("query"); + + NamedList>> queryNL = value.get("query"); List phases = (queryNL == null) ? null : buildPhases(queryNL); analysis.setQueryPhases(phases); - NamedList indexNL = (NamedList) fieldNameNL.get("index"); + + NamedList>> indexNL = value.get("index"); phases = buildPhases(indexNL); analysis.setIndexPhases(phases); - String fieldName = entry.getKey(); - analysisByFieldName.put(fieldName, analysis); - } + + return analysis; } /** From 6813c2ed596ef93da2826f3ac39136603cac73f0 Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Sat, 8 Jan 2011 02:07:49 +0000 Subject: [PATCH 028/252] SOLR-2288: i horrificly didn't notice that i broke some tests (compilation failure no less) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056595 13f79535-47bb-0310-9956-ffa450edef68 --- .../client/solrj/response/DocumentAnalysisResponseTest.java | 2 +- .../solr/client/solrj/response/FieldAnalysisResponseTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solr/src/test/org/apache/solr/client/solrj/response/DocumentAnalysisResponseTest.java b/solr/src/test/org/apache/solr/client/solrj/response/DocumentAnalysisResponseTest.java index fbfbafeab8e..5cbf67f0865 100644 --- a/solr/src/test/org/apache/solr/client/solrj/response/DocumentAnalysisResponseTest.java +++ b/solr/src/test/org/apache/solr/client/solrj/response/DocumentAnalysisResponseTest.java @@ -48,7 +48,7 @@ public class DocumentAnalysisResponseTest extends LuceneTestCase { DocumentAnalysisResponse response = new DocumentAnalysisResponse() { @Override - protected List buildPhases(NamedList phaseNL) { + protected List buildPhases(NamedList>> phaseNL) { return phases; } }; diff --git a/solr/src/test/org/apache/solr/client/solrj/response/FieldAnalysisResponseTest.java b/solr/src/test/org/apache/solr/client/solrj/response/FieldAnalysisResponseTest.java index 73b506dc0cd..f6f62aaa2f9 100644 --- a/solr/src/test/org/apache/solr/client/solrj/response/FieldAnalysisResponseTest.java +++ b/solr/src/test/org/apache/solr/client/solrj/response/FieldAnalysisResponseTest.java @@ -49,7 +49,7 @@ public class FieldAnalysisResponseTest extends LuceneTestCase { NamedList responseNL = buildResponse(); FieldAnalysisResponse response = new FieldAnalysisResponse() { @Override - protected List buildPhases(NamedList phaseNL) { + protected List buildPhases(NamedList>> phaseNL) { return phases; } }; From bdd7fea1e408c7a427d2afef3ae8447eb661acff Mon Sep 17 00:00:00 2001 From: "Chris M. Hostetter" Date: Sat, 8 Jan 2011 03:47:31 +0000 Subject: [PATCH 029/252] SOLR-2288: more small tweaks to eliminate compiler warnings git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056612 13f79535-47bb-0310-9956-ffa450edef68 --- .../handler/AnalysisRequestHandlerBase.java | 11 ++-- .../DocumentAnalysisRequestHandler.java | 12 ++-- .../solr/handler/DumpRequestHandler.java | 2 +- .../org/apache/solr/handler/JsonLoader.java | 1 + .../solr/handler/ReplicationHandler.java | 10 +-- .../org/apache/solr/handler/SnapPuller.java | 32 +++++---- .../org/apache/solr/handler/SnapShooter.java | 3 +- .../handler/component/StatsComponent.java | 12 ++-- .../component/TermVectorComponent.java | 66 +++++++++---------- .../apache/solr/request/UnInvertedField.java | 7 +- .../apache/solr/search/SolrIndexSearcher.java | 4 +- 11 files changed, 85 insertions(+), 75 deletions(-) diff --git a/solr/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java b/solr/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java index b5216f7b274..b87dcc3d56f 100644 --- a/solr/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java +++ b/solr/src/java/org/apache/solr/handler/AnalysisRequestHandlerBase.java @@ -47,6 +47,8 @@ import java.util.*; */ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { + public static final Set EMPTY_STRING_SET = Collections.emptySet(); + public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception { rsp.add("analysis", doAnalysis(req)); } @@ -70,7 +72,7 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { * * @return NamedList containing the tokens produced by analyzing the given value */ - protected NamedList> analyzeValue(String value, AnalysisContext context) { + protected NamedList analyzeValue(String value, AnalysisContext context) { Analyzer analyzer = context.getAnalyzer(); @@ -93,7 +95,7 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { TokenizerFactory tfac = tokenizerChain.getTokenizerFactory(); TokenFilterFactory[] filtfacs = tokenizerChain.getTokenFilterFactories(); - NamedList> namedList = new NamedList>(); + NamedList namedList = new NamedList(); if( cfiltfacs != null ){ String source = value; @@ -234,7 +236,7 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { return tokensNamedLists; } - private String writeCharStream(NamedList out, CharStream input ){ + private String writeCharStream(NamedList out, CharStream input ){ final int BUFFER_SIZE = 1024; char[] buf = new char[BUFFER_SIZE]; int len = 0; @@ -252,7 +254,6 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { return sb.toString(); } - // ================================================= Inner classes ================================================= /** @@ -342,7 +343,7 @@ public abstract class AnalysisRequestHandlerBase extends RequestHandlerBase { * */ public AnalysisContext(String fieldName, FieldType fieldType, Analyzer analyzer) { - this(fieldName, fieldType, analyzer, Collections.EMPTY_SET); + this(fieldName, fieldType, analyzer, EMPTY_STRING_SET); } /** diff --git a/solr/src/java/org/apache/solr/handler/DocumentAnalysisRequestHandler.java b/solr/src/java/org/apache/solr/handler/DocumentAnalysisRequestHandler.java index 0f0aead5ec4..519674c782c 100644 --- a/solr/src/java/org/apache/solr/handler/DocumentAnalysisRequestHandler.java +++ b/solr/src/java/org/apache/solr/handler/DocumentAnalysisRequestHandler.java @@ -230,9 +230,8 @@ public class DocumentAnalysisRequestHandler extends AnalysisRequestHandlerBase { if (request.getQuery() != null) { try { - AnalysisContext analysisContext = new AnalysisContext(fieldType, fieldType.getQueryAnalyzer(), Collections.EMPTY_SET); - NamedList> tokens = analyzeValue(request.getQuery(), analysisContext); - fieldTokens.add("query", tokens); + AnalysisContext analysisContext = new AnalysisContext(fieldType, fieldType.getQueryAnalyzer(), EMPTY_STRING_SET); + fieldTokens.add("query", analyzeValue(request.getQuery(), analysisContext)); } catch (Exception e) { // ignore analysis exceptions since we are applying arbitrary text to all fields } @@ -241,10 +240,11 @@ public class DocumentAnalysisRequestHandler extends AnalysisRequestHandlerBase { Analyzer analyzer = fieldType.getAnalyzer(); AnalysisContext analysisContext = new AnalysisContext(fieldType, analyzer, termsToMatch); Collection fieldValues = document.getFieldValues(name); - NamedList>> indexTokens = new SimpleOrderedMap>>(); + NamedList> indexTokens + = new SimpleOrderedMap>(); for (Object fieldValue : fieldValues) { - NamedList> tokens = analyzeValue(fieldValue.toString(), analysisContext); - indexTokens.add(String.valueOf(fieldValue), tokens); + indexTokens.add(String.valueOf(fieldValue), + analyzeValue(fieldValue.toString(), analysisContext)); } fieldTokens.add("index", indexTokens); } diff --git a/solr/src/java/org/apache/solr/handler/DumpRequestHandler.java b/solr/src/java/org/apache/solr/handler/DumpRequestHandler.java index f1190005dfb..d858ef66e15 100644 --- a/solr/src/java/org/apache/solr/handler/DumpRequestHandler.java +++ b/solr/src/java/org/apache/solr/handler/DumpRequestHandler.java @@ -38,7 +38,7 @@ public class DumpRequestHandler extends RequestHandlerBase // Write the streams... if( req.getContentStreams() != null ) { - ArrayList streams = new ArrayList(); + ArrayList> streams = new ArrayList>(); // Cycle through each stream for( ContentStream content : req.getContentStreams() ) { NamedList stream = new SimpleOrderedMap(); diff --git a/solr/src/java/org/apache/solr/handler/JsonLoader.java b/solr/src/java/org/apache/solr/handler/JsonLoader.java index b96430bcd0c..c233ce634e4 100644 --- a/solr/src/java/org/apache/solr/handler/JsonLoader.java +++ b/solr/src/java/org/apache/solr/handler/JsonLoader.java @@ -69,6 +69,7 @@ class JsonLoader extends ContentStreamLoader { } } + @SuppressWarnings("fallthrough") void processUpdate(SolrQueryRequest req, UpdateRequestProcessor processor, JSONParser parser) throws IOException { int ev = parser.nextEvent(); diff --git a/solr/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/src/java/org/apache/solr/handler/ReplicationHandler.java index ad0cf117caf..a9983c798c8 100644 --- a/solr/src/java/org/apache/solr/handler/ReplicationHandler.java +++ b/solr/src/java/org/apache/solr/handler/ReplicationHandler.java @@ -94,7 +94,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw private volatile IndexCommit indexCommitPoint; - volatile NamedList snapShootDetails; + volatile NamedList snapShootDetails; private AtomicBoolean replicationEnabled = new AtomicBoolean(true); @@ -189,13 +189,13 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw } } - private List getCommits() { + private List> getCommits() { Map commits = core.getDeletionPolicy().getCommits(); - List l = new ArrayList(); + List> l = new ArrayList>(); for (IndexCommit c : commits.values()) { try { - NamedList nl = new NamedList(); + NamedList nl = new NamedList(); nl.add("indexVersion", c.getVersion()); nl.add(GENERATION, c.getGeneration()); nl.add(CMD_GET_FILE_LIST, c.getFileNames()); @@ -701,7 +701,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw return details; } - private void addVal(NamedList nl, String key, Properties props, Class clzz) { + private void addVal(NamedList nl, String key, Properties props, Class clzz) { String s = props.getProperty(key); if (s == null || s.trim().length() == 0) return; if (clzz == Date.class) { diff --git a/solr/src/java/org/apache/solr/handler/SnapPuller.java b/solr/src/java/org/apache/solr/handler/SnapPuller.java index 9af131fd1c4..1a41f827680 100644 --- a/solr/src/java/org/apache/solr/handler/SnapPuller.java +++ b/solr/src/java/org/apache/solr/handler/SnapPuller.java @@ -63,6 +63,9 @@ import java.util.zip.InflaterInputStream; public class SnapPuller { private static final Logger LOG = LoggerFactory.getLogger(SnapPuller.class.getName()); + private static final List> EMPTY_LIST_OF_MAPS + = Collections.emptyList(); + private final String masterUrl; private final ReplicationHandler replicationHandler; @@ -192,14 +195,14 @@ public class SnapPuller { return getNamedListResponse(post); } - private NamedList getNamedListResponse(PostMethod method) throws IOException { + private NamedList getNamedListResponse(PostMethod method) throws IOException { try { int status = myHttpClient.executeMethod(method); if (status != HttpStatus.SC_OK) { throw new SolrException(SolrException.ErrorCode.SERVICE_UNAVAILABLE, "Request failed for the url " + method); } - return (NamedList) new JavaBinCodec().unmarshal(method.getResponseBodyAsStream()); + return (NamedList) new JavaBinCodec().unmarshal(method.getResponseBodyAsStream()); } finally { try { method.releaseConnection(); @@ -216,8 +219,12 @@ public class SnapPuller { post.addParameter(COMMAND, CMD_GET_FILE_LIST); post.addParameter(CMD_INDEX_VERSION, String.valueOf(version)); post.addParameter("wt", "javabin"); - NamedList nl = getNamedListResponse(post); - List> f = (List>) nl.get(CMD_GET_FILE_LIST); + + @SuppressWarnings("unchecked") + NamedList>> nl + = (NamedList>>) getNamedListResponse(post); + + List> f = nl.get(CMD_GET_FILE_LIST); if (f != null) filesToDownload = Collections.synchronizedList(f); else { @@ -225,7 +232,7 @@ public class SnapPuller { LOG.error("No files to download for indexversion: "+ version); } - f = (List>) nl.get(CONF_FILES); + f = nl.get(CONF_FILES); if (f != null) confFilesToDownload = Collections.synchronizedList(f); } @@ -704,10 +711,11 @@ public class SnapPuller { */ private Collection> getModifiedConfFiles(List> confFilesToDownload) { if (confFilesToDownload == null || confFilesToDownload.isEmpty()) - return Collections.EMPTY_LIST; + return EMPTY_LIST_OF_MAPS; + //build a map with alias/name as the key Map> nameVsFile = new HashMap>(); - NamedList names = new NamedList(); + NamedList names = new NamedList(); for (Map map : confFilesToDownload) { //if alias is present that is the name the file may have in the slave String name = (String) (map.get(ALIAS) == null ? map.get(NAME) : map.get(ALIAS)); @@ -725,7 +733,7 @@ public class SnapPuller { nameVsFile.remove(name); //checksums are same so the file need not be downloaded } } - return nameVsFile.isEmpty() ? Collections.EMPTY_LIST : nameVsFile.values(); + return nameVsFile.isEmpty() ? EMPTY_LIST_OF_MAPS : nameVsFile.values(); } /** @@ -788,25 +796,25 @@ public class SnapPuller { //make a copy first because it can be null later List> tmp = confFilesToDownload; //create a new instance. or else iterator may fail - return tmp == null ? Collections.EMPTY_LIST : new ArrayList>(tmp); + return tmp == null ? EMPTY_LIST_OF_MAPS : new ArrayList>(tmp); } List> getConfFilesDownloaded() { //make a copy first because it can be null later List> tmp = confFilesDownloaded; // NOTE: it's safe to make a copy of a SynchronizedCollection(ArrayList) - return tmp == null ? Collections.EMPTY_LIST : new ArrayList>(tmp); + return tmp == null ? EMPTY_LIST_OF_MAPS : new ArrayList>(tmp); } List> getFilesToDownload() { //make a copy first because it can be null later List> tmp = filesToDownload; - return tmp == null ? Collections.EMPTY_LIST : new ArrayList>(tmp); + return tmp == null ? EMPTY_LIST_OF_MAPS : new ArrayList>(tmp); } List> getFilesDownloaded() { List> tmp = filesDownloaded; - return tmp == null ? Collections.EMPTY_LIST : new ArrayList>(tmp); + return tmp == null ? EMPTY_LIST_OF_MAPS : new ArrayList>(tmp); } Map getCurrentFile() { diff --git a/solr/src/java/org/apache/solr/handler/SnapShooter.java b/solr/src/java/org/apache/solr/handler/SnapShooter.java index df99c7cb97d..c1992636c2e 100644 --- a/solr/src/java/org/apache/solr/handler/SnapShooter.java +++ b/solr/src/java/org/apache/solr/handler/SnapShooter.java @@ -71,7 +71,8 @@ public class SnapShooter { } void createSnapshot(final IndexCommit indexCommit, ReplicationHandler replicationHandler) { - NamedList details = new NamedList(); + + NamedList details = new NamedList(); details.add("startTime", new Date().toString()); File snapShotDir = null; String directoryName = null; diff --git a/solr/src/java/org/apache/solr/handler/component/StatsComponent.java b/solr/src/java/org/apache/solr/handler/component/StatsComponent.java index 8896d73d172..dc0b4333047 100644 --- a/solr/src/java/org/apache/solr/handler/component/StatsComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/StatsComponent.java @@ -124,8 +124,8 @@ public class StatsComponent extends SearchComponent { StatsInfo si = rb._statsInfo; - NamedList stats = new SimpleOrderedMap(); - NamedList stats_fields = new SimpleOrderedMap(); + NamedList> stats = new SimpleOrderedMap>(); + NamedList stats_fields = new SimpleOrderedMap(); stats.add("stats_fields", stats_fields); for (String field : si.statsFields.keySet()) { NamedList stv = si.statsFields.get(field).getStatsValues(); @@ -209,8 +209,8 @@ class SimpleStats { return res; } - public NamedList getStatsFields() throws IOException { - NamedList> res = new SimpleOrderedMap>(); + public NamedList getStatsFields() throws IOException { + NamedList res = new SimpleOrderedMap(); String[] statsFs = params.getParams(StatsParams.STATS_FIELD); boolean isShard = params.getBool(ShardParams.IS_SHARD, false); if (null != statsFs) { @@ -221,7 +221,7 @@ class SimpleStats { } SchemaField sf = searcher.getSchema().getField(f); FieldType ft = sf.getType(); - NamedList stv; + NamedList stv; // Currently, only UnInvertedField can deal with multi-part trie fields String prefix = TrieField.getMainValuePrefix(ft); @@ -243,7 +243,7 @@ class SimpleStats { return res; } - public NamedList getFieldCacheStats(String fieldName, String[] facet ) { + public NamedList getFieldCacheStats(String fieldName, String[] facet ) { FieldType ft = searcher.getSchema().getFieldType(fieldName); FieldCache.DocTermsIndex si = null; diff --git a/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java b/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java index f190ab4ba1f..59310c6fa14 100644 --- a/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java @@ -77,7 +77,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar return; } - NamedList termVectors = new NamedList(); + NamedList termVectors = new NamedList(); rb.rsp.add(TERM_VECTORS, termVectors); FieldOptions allFields = new FieldOptions(); //figure out what options we have, and try to get the appropriate vector @@ -106,7 +106,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar IndexSchema schema = rb.req.getSchema(); //Build up our per field mapping Map fieldOptions = new HashMap(); - NamedList warnings = new NamedList(); + NamedList> warnings = new NamedList>(); List noTV = new ArrayList(); List noPos = new ArrayList(); List noOff = new ArrayList(); @@ -187,7 +187,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar mapper.fieldOptions = allFields; //this will only stay set if fieldOptions.isEmpty() (in other words, only if the user didn't set any fields) while (iter.hasNext()) { Integer docId = iter.next(); - NamedList docNL = new NamedList(); + NamedList docNL = new NamedList(); mapper.docNL = docNL; termVectors.add("doc-" + docId, docNL); @@ -272,7 +272,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar private static class TVMapper extends TermVectorMapper { private IndexReader reader; - private NamedList docNL; + private NamedList docNL; //needs to be set for each new field FieldOptions fieldOptions; @@ -280,7 +280,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar //internal vars not passed in by construction private boolean useOffsets, usePositions; //private Map idfCache; - private NamedList fieldNL; + private NamedList fieldNL; private Term currentTerm; @@ -289,34 +289,34 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar } public void map(BytesRef term, int frequency, TermVectorOffsetInfo[] offsets, int[] positions) { - NamedList termInfo = new NamedList(); - fieldNL.add(term.utf8ToString(), termInfo); - if (fieldOptions.termFreq == true) { - termInfo.add("tf", frequency); + NamedList termInfo = new NamedList(); + fieldNL.add(term.utf8ToString(), termInfo); + if (fieldOptions.termFreq == true) { + termInfo.add("tf", frequency); + } + if (useOffsets == true) { + NamedList theOffsets = new NamedList(); + termInfo.add("offsets", theOffsets); + for (int i = 0; i < offsets.length; i++) { + TermVectorOffsetInfo offset = offsets[i]; + theOffsets.add("start", offset.getStartOffset()); + theOffsets.add("end", offset.getEndOffset()); } - if (useOffsets == true) { - NamedList theOffsets = new NamedList(); - termInfo.add("offsets", theOffsets); - for (int i = 0; i < offsets.length; i++) { - TermVectorOffsetInfo offset = offsets[i]; - theOffsets.add("start", offset.getStartOffset()); - theOffsets.add("end", offset.getEndOffset()); - } - } - if (usePositions == true) { - NamedList positionsNL = new NamedList(); - for (int i = 0; i < positions.length; i++) { - positionsNL.add("position", positions[i]); - } - termInfo.add("positions", positionsNL); - } - if (fieldOptions.docFreq == true) { - termInfo.add("df", getDocFreq(term)); - } - if (fieldOptions.tfIdf == true) { - double tfIdfVal = ((double) frequency) / getDocFreq(term); - termInfo.add("tf-idf", tfIdfVal); + } + if (usePositions == true) { + NamedList positionsNL = new NamedList(); + for (int i = 0; i < positions.length; i++) { + positionsNL.add("position", positions[i]); } + termInfo.add("positions", positionsNL); + } + if (fieldOptions.docFreq == true) { + termInfo.add("df", getDocFreq(term)); + } + if (fieldOptions.tfIdf == true) { + double tfIdfVal = ((double) frequency) / getDocFreq(term); + termInfo.add("tf-idf", tfIdfVal); + } } private int getDocFreq(BytesRef term) { @@ -343,7 +343,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar } useOffsets = storeOffsets && fieldOptions.offsets; usePositions = storePositions && fieldOptions.positions; - fieldNL = new NamedList(); + fieldNL = new NamedList(); docNL.add(field, fieldNL); } @@ -394,4 +394,4 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar class FieldOptions { String fieldName; boolean termFreq, positions, offsets, docFreq, tfIdf; -} \ No newline at end of file +} diff --git a/solr/src/java/org/apache/solr/request/UnInvertedField.java b/solr/src/java/org/apache/solr/request/UnInvertedField.java index 01fe7ae017d..3845ec9ba31 100755 --- a/solr/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/src/java/org/apache/solr/request/UnInvertedField.java @@ -900,15 +900,15 @@ public class UnInvertedField { //////////////////////////// caching ///////////////////////////// ////////////////////////////////////////////////////////////////// public static UnInvertedField getUnInvertedField(String field, SolrIndexSearcher searcher) throws IOException { - SolrCache cache = searcher.getFieldValueCache(); + SolrCache cache = searcher.getFieldValueCache(); if (cache == null) { return new UnInvertedField(field, searcher); } - UnInvertedField uif = (UnInvertedField)cache.get(field); + UnInvertedField uif = cache.get(field); if (uif == null) { synchronized (cache) { - uif = (UnInvertedField)cache.get(field); + uif = cache.get(field); if (uif == null) { uif = new UnInvertedField(field, searcher); cache.put(field, uif); @@ -918,7 +918,6 @@ public class UnInvertedField { return uif; } - } diff --git a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java index a011acf4f01..d175a712835 100644 --- a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -79,7 +79,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { private final SolrCache filterCache; private final SolrCache queryResultCache; private final SolrCache documentCache; - private final SolrCache fieldValueCache; + private final SolrCache fieldValueCache; private final LuceneQueryOptimizer optimizer; @@ -470,7 +470,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { //////////////////////////////////////////////////////////////////////////////// /** expert: internal API, subject to change */ - public SolrCache getFieldValueCache() { + public SolrCache getFieldValueCache() { return fieldValueCache; } From ba13db682731c082ddb8486190b2fa90f9774dde Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 8 Jan 2011 13:45:44 +0000 Subject: [PATCH 030/252] fix LineFileDocs to seek to random start on open git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056702 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/index/TestNRTThreads.java | 2 +- .../org/apache/lucene/util/LineFileDocs.java | 59 +++++++++++++------ .../lucene/util/automaton/fst/TestFSTs.java | 2 +- 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java b/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java index 56a18c73fd6..af0cde305c8 100644 --- a/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java +++ b/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java @@ -65,7 +65,7 @@ public class TestNRTThreads extends LuceneTestCase { CodecProvider.getDefault().setDefaultFieldCodec("Standard"); } - final LineFileDocs docs = new LineFileDocs(true); + final LineFileDocs docs = new LineFileDocs(random); final File tempDir = _TestUtil.getTempDir("nrtopenfiles"); final MockDirectoryWrapper dir = new MockDirectoryWrapper(random, FSDirectory.open(tempDir)); final IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()); diff --git a/lucene/src/test/org/apache/lucene/util/LineFileDocs.java b/lucene/src/test/org/apache/lucene/util/LineFileDocs.java index fe3c0eb355a..56cb3e089d3 100644 --- a/lucene/src/test/org/apache/lucene/util/LineFileDocs.java +++ b/lucene/src/test/org/apache/lucene/util/LineFileDocs.java @@ -18,6 +18,7 @@ package org.apache.lucene.util; */ import java.io.Closeable; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.BufferedReader; @@ -26,6 +27,7 @@ import java.io.InputStream; import java.io.BufferedInputStream; import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.GZIPInputStream; +import java.util.Random; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -36,21 +38,19 @@ import org.apache.lucene.document.Field; public class LineFileDocs implements Closeable { private BufferedReader reader; - private final boolean forever; private final static int BUFFER_SIZE = 1 << 16; // 64K private final AtomicInteger id = new AtomicInteger(); private final String path; // If forever is true, we rewind the file at EOF (repeat // the docs over and over) - public LineFileDocs(String path, boolean forever) throws IOException { + public LineFileDocs(Random random, String path) throws IOException { this.path = path; - this.forever = forever; - open(); + open(random); } - public LineFileDocs(boolean forever) throws IOException { - this(LuceneTestCase.TEST_LINE_DOCS_FILE, forever); + public LineFileDocs(Random random) throws IOException { + this(random, LuceneTestCase.TEST_LINE_DOCS_FILE); } public synchronized void close() throws IOException { @@ -60,22 +60,49 @@ public class LineFileDocs implements Closeable { } } - private synchronized void open() throws IOException { + private synchronized void open(Random random) throws IOException { InputStream is = getClass().getResourceAsStream(path); if (is == null) { // if its not in classpath, we load it as absolute filesystem path (e.g. Hudson's home dir) is = new FileInputStream(path); } + File file = new File(path); + long size; + if (file.exists()) { + size = file.length(); + } else { + size = is.available(); + } if (path.endsWith(".gz")) { is = new GZIPInputStream(is); + // guestimate: + size *= 2.8; } + final InputStream in = new BufferedInputStream(is, BUFFER_SIZE); reader = new BufferedReader(new InputStreamReader(in, "UTF-8"), BUFFER_SIZE); + + // Override sizes for currently "known" line files: + if (path.equals("europarl.lines.txt.gz")) { + size = 15129506L; + } else if (path.equals("/home/hudson/lucene-data/enwiki.random.lines.txt.gz")) { + size = 3038178822L; + } + + // Randomly seek to starting point: + if (random != null && size > 3) { + final long seekTo = (random.nextLong()&Long.MAX_VALUE) % (size/3); + if (LuceneTestCase.VERBOSE) { + System.out.println("TEST: LineFileDocs: seek to fp=" + seekTo + " on open"); + } + reader.skip(seekTo); + reader.readLine(); + } } - public synchronized void reset() throws IOException { + public synchronized void reset(Random random) throws IOException { close(); - open(); + open(random); id.set(0); } @@ -117,15 +144,13 @@ public class LineFileDocs implements Closeable { synchronized(this) { line = reader.readLine(); if (line == null) { - if (forever) { - if (LuceneTestCase.VERBOSE) { - System.out.println("TEST: LineFileDocs: now rewind file..."); - } - close(); - open(); - line = reader.readLine(); + // Always rewind at end: + if (LuceneTestCase.VERBOSE) { + System.out.println("TEST: LineFileDocs: now rewind file..."); } - return null; + close(); + open(null); + line = reader.readLine(); } } diff --git a/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java b/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java index 72a68709713..df4b54cda8f 100644 --- a/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java +++ b/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java @@ -944,7 +944,7 @@ public class TestFSTs extends LuceneTestCase { CodecProvider.getDefault().setDefaultFieldCodec("Standard"); } - final LineFileDocs docs = new LineFileDocs(false); + final LineFileDocs docs = new LineFileDocs(random); final int RUN_TIME_SEC = LuceneTestCase.TEST_NIGHTLY ? 100 : 1; final IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()).setMaxBufferedDocs(-1).setRAMBufferSizeMB(64); final File tempDir = _TestUtil.getTempDir("fstlines"); From 8b241d9230380b75157ad396c74ca1498f287666 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 8 Jan 2011 16:51:08 +0000 Subject: [PATCH 031/252] LUCENE-2831: remove/fix more uses of non top-level readers in prep for AtomicReaderContext git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056734 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/search/ValueSourceParser.java | 11 ++-- .../solr/search/function/OrdFieldSource.java | 34 +++++++--- .../function/ReverseOrdFieldSource.java | 26 +++++--- .../search/function/ScaleFloatFunction.java | 62 +++++++++++++------ 4 files changed, 93 insertions(+), 40 deletions(-) diff --git a/solr/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/src/java/org/apache/solr/search/ValueSourceParser.java index 116058fc301..5b1805ee017 100755 --- a/solr/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/src/java/org/apache/solr/search/ValueSourceParser.java @@ -83,7 +83,7 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { addParser("ord", new ValueSourceParser() { public ValueSource parse(FunctionQParser fp) throws ParseException { String field = fp.parseId(); - return new TopValueSource(new OrdFieldSource(field)); + return new OrdFieldSource(field); } }); addParser("literal", new ValueSourceParser() { @@ -94,15 +94,14 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { addParser("rord", new ValueSourceParser() { public ValueSource parse(FunctionQParser fp) throws ParseException { String field = fp.parseId(); - return new TopValueSource(new ReverseOrdFieldSource(field)); + return new ReverseOrdFieldSource(field); } }); addParser("top", new ValueSourceParser() { public ValueSource parse(FunctionQParser fp) throws ParseException { + // top(vs) is now a no-op ValueSource source = fp.parseValueSource(); - // nested top is redundant, and ord and rord get automatically wrapped - if (source instanceof TopValueSource) return source; - return new TopValueSource(source); + return source; } }); addParser("linear", new ValueSourceParser() { @@ -134,7 +133,7 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin { ValueSource source = fp.parseValueSource(); float min = fp.parseFloat(); float max = fp.parseFloat(); - return new TopValueSource(new ScaleFloatFunction(source, min, max)); + return new ScaleFloatFunction(source, min, max); } }); addParser("div", new ValueSourceParser() { diff --git a/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java b/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java index 93da97395d1..d68185664cb 100644 --- a/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/OrdFieldSource.java @@ -18,8 +18,10 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.FieldCache; import org.apache.solr.search.MutableValue; import org.apache.solr.search.MutableValueInt; +import org.apache.solr.search.SolrIndexReader; import java.io.IOException; import java.util.Map; @@ -55,38 +57,52 @@ public class OrdFieldSource extends ValueSource { public DocValues getValues(Map context, IndexReader reader) throws IOException { - return new StringIndexDocValues(this, reader, field) { + int offset = 0; + IndexReader topReader = reader; + if (topReader instanceof SolrIndexReader) { + SolrIndexReader r = (SolrIndexReader)topReader; + while (r.getParent() != null) { + offset += r.getBase(); + r = r.getParent(); + } + topReader = r; + } + final int off = offset; + + final FieldCache.DocTermsIndex sindex = FieldCache.DEFAULT.getTermsIndex(topReader, field); + + return new DocValues() { protected String toTerm(String readableValue) { return readableValue; } public float floatVal(int doc) { - return (float)termsIndex.getOrd(doc); + return (float)sindex.getOrd(doc+off); } public int intVal(int doc) { - return termsIndex.getOrd(doc); + return sindex.getOrd(doc+off); } public long longVal(int doc) { - return (long)termsIndex.getOrd(doc); + return (long)sindex.getOrd(doc+off); } public double doubleVal(int doc) { - return (double)termsIndex.getOrd(doc); + return (double)sindex.getOrd(doc+off); } public int ordVal(int doc) { - return termsIndex.getOrd(doc); + return sindex.getOrd(doc+off); } public int numOrd() { - return termsIndex.numOrd(); + return sindex.numOrd(); } public String strVal(int doc) { // the string value of the ordinal, not the string itself - return Integer.toString(termsIndex.getOrd(doc)); + return Integer.toString(sindex.getOrd(doc+off)); } public String toString(int doc) { @@ -105,7 +121,7 @@ public class OrdFieldSource extends ValueSource { @Override public void fillValue(int doc) { - mval.value = termsIndex.getOrd(doc); + mval.value = sindex.getOrd(doc); mval.exists = mval.value!=0; } }; diff --git a/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java b/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java index ef595a59aae..455fc3ab0f8 100644 --- a/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/ReverseOrdFieldSource.java @@ -19,6 +19,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.FieldCache; +import org.apache.solr.search.SolrIndexReader; import java.io.IOException; import java.util.Map; @@ -56,25 +57,36 @@ public class ReverseOrdFieldSource extends ValueSource { } public DocValues getValues(Map context, IndexReader reader) throws IOException { - final FieldCache.DocTermsIndex sindex = FieldCache.DEFAULT.getTermsIndex(reader, field); + int offset = 0; + IndexReader topReader = reader; + if (topReader instanceof SolrIndexReader) { + SolrIndexReader r = (SolrIndexReader)topReader; + while (r.getParent() != null) { + offset += r.getBase(); + r = r.getParent(); + } + topReader = r; + } + final int off = offset; + final FieldCache.DocTermsIndex sindex = FieldCache.DEFAULT.getTermsIndex(topReader, field); final int end = sindex.numOrd(); return new DocValues() { public float floatVal(int doc) { - return (float)(end - sindex.getOrd(doc)); + return (float)(end - sindex.getOrd(doc+off)); } public int intVal(int doc) { - return (end - sindex.getOrd(doc)); + return (end - sindex.getOrd(doc+off)); } public long longVal(int doc) { - return (long)(end - sindex.getOrd(doc)); + return (long)(end - sindex.getOrd(doc+off)); } public int ordVal(int doc) { - return (end - sindex.getOrd(doc)); + return (end - sindex.getOrd(doc+off)); } public int numOrd() { @@ -82,12 +94,12 @@ public class ReverseOrdFieldSource extends ValueSource { } public double doubleVal(int doc) { - return (double)(end - sindex.getOrd(doc)); + return (double)(end - sindex.getOrd(doc+off)); } public String strVal(int doc) { // the string value of the ordinal, not the string itself - return Integer.toString((end - sindex.getOrd(doc))); + return Integer.toString((end - sindex.getOrd(doc+off))); } public String toString(int doc) { diff --git a/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java b/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java index 6e8cd65c343..74875bedbfc 100755 --- a/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java @@ -18,7 +18,9 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; +import org.apache.solr.search.SolrIndexReader; import java.io.IOException; import java.util.Map; @@ -49,24 +51,25 @@ public class ScaleFloatFunction extends ValueSource { return "scale(" + source.description() + "," + min + "," + max + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals = source.getValues(context, reader); - int maxDoc = reader.maxDoc(); + private static class ScaleInfo { + float minVal; + float maxVal; + } - // this doesn't take into account deleted docs! - float minVal=0.0f; - float maxVal=0.0f; + private ScaleInfo createScaleInfo(Map context, IndexReader reader) throws IOException { + IndexReader.ReaderContext ctx = ValueSource.readerToContext(context, reader); + while (ctx.parent != null) ctx = ctx.parent; + AtomicReaderContext[] leaves = ctx.leaves(); + if (ctx == null) leaves = new AtomicReaderContext[] {(AtomicReaderContext)ctx}; - if (maxDoc>0) { - minVal = maxVal = vals.floatVal(0); - } + float minVal = Float.POSITIVE_INFINITY; + float maxVal = Float.NEGATIVE_INFINITY; - // Traverse the complete set of values to get the min and the max. - // Future alternatives include being able to ask a DocValues for min/max - // Another memory-intensive option is to cache the values in - // a float[] on this first pass. + for (AtomicReaderContext leaf : leaves) { + int maxDoc = leaf.reader.maxDoc(); + DocValues vals = source.getValues(context, leaf.reader); + for (int i=0; i maxVal) { + } + if (val > maxVal) { maxVal = val; } } + } - final float scale = (maxVal-minVal==0) ? 0 : (max-min)/(maxVal-minVal); - final float minSource = minVal; - final float maxSource = maxVal; + if (minVal == Float.POSITIVE_INFINITY) { + // must have been an empty index + minVal = maxVal = 0; + } + + ScaleInfo scaleInfo = new ScaleInfo(); + scaleInfo.minVal = minVal; + scaleInfo.maxVal = maxVal; + context.put(this.source, scaleInfo); + return scaleInfo; + } + + public DocValues getValues(Map context, IndexReader reader) throws IOException { + + ScaleInfo scaleInfo = (ScaleInfo)context.get(source); + if (scaleInfo == null) { + scaleInfo = createScaleInfo(context, reader); + } + + final float scale = (scaleInfo.maxVal-scaleInfo.minVal==0) ? 0 : (max-min)/(scaleInfo.maxVal-scaleInfo.minVal); + final float minSource = scaleInfo.minVal; + final float maxSource = scaleInfo.maxVal; + + final DocValues vals = source.getValues(context, reader); return new DocValues() { public float floatVal(int doc) { From a518f57756f5b254f7b553455e4ea94aab1e9215 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 8 Jan 2011 17:50:24 +0000 Subject: [PATCH 032/252] LUCENE-2831: delete TopValueSource - will be illegal in the future git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056746 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/search/function/TopValueSource.java | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100755 solr/src/java/org/apache/solr/search/function/TopValueSource.java diff --git a/solr/src/java/org/apache/solr/search/function/TopValueSource.java b/solr/src/java/org/apache/solr/search/function/TopValueSource.java deleted file mode 100755 index 45bb0c7473a..00000000000 --- a/solr/src/java/org/apache/solr/search/function/TopValueSource.java +++ /dev/null @@ -1,101 +0,0 @@ -package org.apache.solr.search.function; -/** - * 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 org.apache.solr.search.SolrIndexReader; -import org.apache.lucene.index.IndexReader; - -import java.io.IOException; -import java.util.Map; - -/** - * A value source that wraps another and ensures that the top level reader - * is used. This is useful for value sources like ord() who's value depend - * on all those around it. - */ -public class TopValueSource extends ValueSource { - private final ValueSource vs; - - public TopValueSource(ValueSource vs) { - this.vs = vs; - } - - public ValueSource getValueSource() { - return vs; - } - - public String description() { - return "top(" + vs.description() + ')'; - } - - public DocValues getValues(Map context, IndexReader reader) throws IOException { - int offset = 0; - IndexReader topReader = reader; - if (topReader instanceof SolrIndexReader) { - SolrIndexReader r = (SolrIndexReader)topReader; - while (r.getParent() != null) { - offset += r.getBase(); - r = r.getParent(); - } - topReader = r; - } - final int off = offset; - final DocValues vals = vs.getValues(context, topReader); - if (topReader == reader) return vals; - - return new DocValues() { - public float floatVal(int doc) { - return vals.floatVal(doc + off); - } - - public int intVal(int doc) { - return vals.intVal(doc + off); - } - - public long longVal(int doc) { - return vals.longVal(doc + off); - } - - public double doubleVal(int doc) { - return vals.doubleVal(doc + off); - } - - public String strVal(int doc) { - return vals.strVal(doc + off); - } - - public String toString(int doc) { - return vals.strVal(doc + off); - } - }; - } - - public boolean equals(Object o) { - if (o.getClass() != TopValueSource.class) return false; - TopValueSource other = (TopValueSource)o; - return vs.equals(other.vs); - } - - public int hashCode() { - int h = vs.hashCode(); - return (h<<1) | (h>>>31); - } - - public String toString() { - return "top("+vs.toString()+')'; - } -} \ No newline at end of file From 4f7eba849a001ae27d879482e9ee06313874be3b Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 8 Jan 2011 19:20:05 +0000 Subject: [PATCH 033/252] LUCENE-2854: remove SimilarityDelegator; force cutover of Similarity.lengthNorm -> Similarity.computeNorm git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056771 13f79535-47bb-0310-9956-ffa450edef68 --- .../instantiated/InstantiatedIndexWriter.java | 8 +- .../lucene/index/FieldNormModifier.java | 7 +- .../lucene/misc/SweetSpotSimilarity.java | 5 +- .../lucene/index/TestFieldNormModifier.java | 4 +- .../lucene/misc/SweetSpotSimilarityTest.java | 63 +++++++++++---- .../lucene/misc/TestLengthNormModifier.java | 21 ++--- .../lucene/search/FuzzyLikeThisQuery.java | 44 +---------- .../apache/lucene/index/FieldInvertState.java | 12 +++ .../apache/lucene/search/BooleanQuery.java | 38 ++++------ .../apache/lucene/search/BooleanScorer.java | 7 +- .../apache/lucene/search/BooleanScorer2.java | 52 +++++++------ .../lucene/search/ConjunctionScorer.java | 10 +-- .../lucene/search/DefaultSimilarity.java | 8 +- .../org/apache/lucene/search/Similarity.java | 30 ++++++-- .../lucene/search/SimilarityDelegator.java | 76 ------------------- .../index/TestIndexReaderCloneNorms.java | 5 +- .../org/apache/lucene/index/TestNorms.java | 5 +- .../org/apache/lucene/index/TestOmitTf.java | 2 +- .../lucene/search/JustCompileSearch.java | 3 +- .../lucene/search/TestBooleanScorer.java | 2 +- .../search/TestDisjunctionMaxQuery.java | 6 +- .../apache/lucene/search/TestSimilarity.java | 3 +- .../search/payloads/TestPayloadNearQuery.java | 5 +- .../search/payloads/TestPayloadTermQuery.java | 5 +- .../apache/lucene/search/spans/TestSpans.java | 2 +- .../apache/solr/search/SolrSimilarity.java | 37 --------- .../search/function/TestFunctionQuery.java | 6 +- 27 files changed, 191 insertions(+), 275 deletions(-) delete mode 100644 lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java delete mode 100644 solr/src/java/org/apache/solr/search/SolrSimilarity.java diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java index 093b907193b..0bfa8bd6e26 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java @@ -38,6 +38,7 @@ import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.document.Document; import org.apache.lucene.document.Fieldable; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermVectorOffsetInfo; @@ -235,9 +236,10 @@ public class InstantiatedIndexWriter implements Closeable { termsInDocument += eFieldTermDocInfoFactoriesByTermText.getValue().size(); if (eFieldTermDocInfoFactoriesByTermText.getKey().indexed && !eFieldTermDocInfoFactoriesByTermText.getKey().omitNorms) { - float norm = eFieldTermDocInfoFactoriesByTermText.getKey().boost; - norm *= document.getDocument().getBoost(); - norm *= similarity.lengthNorm(eFieldTermDocInfoFactoriesByTermText.getKey().fieldName, eFieldTermDocInfoFactoriesByTermText.getKey().fieldLength); + final FieldInvertState invertState = new FieldInvertState(); + invertState.setBoost(eFieldTermDocInfoFactoriesByTermText.getKey().boost * document.getDocument().getBoost()); + invertState.setLength(eFieldTermDocInfoFactoriesByTermText.getKey().fieldLength); + final float norm = similarity.computeNorm(eFieldTermDocInfoFactoriesByTermText.getKey().fieldName, invertState); normsByFieldNameAndDocumentNumber.get(eFieldTermDocInfoFactoriesByTermText.getKey().fieldName)[document.getDocumentNumber()] = similarity.encodeNormValue(norm); } else { System.currentTimeMillis(); diff --git a/lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java b/lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java index 9cfd56803ca..14fa0970fd6 100644 --- a/lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java +++ b/lucene/contrib/misc/src/java/org/apache/lucene/index/FieldNormModifier.java @@ -33,7 +33,7 @@ import org.apache.lucene.util.ReaderUtil; /** * Given a directory and a list of fields, updates the fieldNorms in place for every document. * - * If Similarity class is specified, uses its lengthNorm method to set norms. + * If Similarity class is specified, uses its computeNorm method to set norms. * If -n command line argument is used, removed field norms, as if * {@link org.apache.lucene.document.Field.Index}.NO_NORMS was used. * @@ -119,6 +119,7 @@ public class FieldNormModifier { final List subReaders = new ArrayList(); ReaderUtil.gatherSubReaders(subReaders, reader); + final FieldInvertState invertState = new FieldInvertState(); for(IndexReader subReader : subReaders) { final Bits delDocs = subReader.getDeletedDocs(); @@ -143,9 +144,11 @@ public class FieldNormModifier { } } + invertState.setBoost(1.0f); for (int d = 0; d < termCounts.length; d++) { if (delDocs == null || !delDocs.get(d)) { - subReader.setNorm(d, fieldName, sim.encodeNormValue(sim.lengthNorm(fieldName, termCounts[d]))); + invertState.setLength(termCounts[d]); + subReader.setNorm(d, fieldName, sim.encodeNormValue(sim.computeNorm(fieldName, invertState))); } } } diff --git a/lucene/contrib/misc/src/java/org/apache/lucene/misc/SweetSpotSimilarity.java b/lucene/contrib/misc/src/java/org/apache/lucene/misc/SweetSpotSimilarity.java index 00a60eb1a82..cda2f0790bf 100644 --- a/lucene/contrib/misc/src/java/org/apache/lucene/misc/SweetSpotSimilarity.java +++ b/lucene/contrib/misc/src/java/org/apache/lucene/misc/SweetSpotSimilarity.java @@ -146,7 +146,7 @@ public class SweetSpotSimilarity extends DefaultSimilarity { else numTokens = state.getLength(); - return state.getBoost() * lengthNorm(fieldName, numTokens); + return state.getBoost() * computeLengthNorm(fieldName, numTokens); } /** @@ -167,8 +167,7 @@ public class SweetSpotSimilarity extends DefaultSimilarity { * * @see #setLengthNormFactors */ - @Override - public float lengthNorm(String fieldName, int numTerms) { + public float computeLengthNorm(String fieldName, int numTerms) { int l = ln_min; int h = ln_max; float s = ln_steep; diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java index 078ba2c3f26..8066ea4e399 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java @@ -43,8 +43,8 @@ public class TestFieldNormModifier extends LuceneTestCase { /** inverts the normal notion of lengthNorm */ public static Similarity s = new DefaultSimilarity() { @Override - public float lengthNorm(String fieldName, int numTokens) { - return numTokens; + public float computeNorm(String fieldName, FieldInvertState state) { + return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength()); } }; diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/misc/SweetSpotSimilarityTest.java b/lucene/contrib/misc/src/test/org/apache/lucene/misc/SweetSpotSimilarityTest.java index 36450e23ae3..170ef247842 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/misc/SweetSpotSimilarityTest.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/misc/SweetSpotSimilarityTest.java @@ -21,13 +21,14 @@ package org.apache.lucene.misc; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.Similarity; import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.index.FieldInvertState; /** * Test of the SweetSpotSimilarity */ public class SweetSpotSimilarityTest extends LuceneTestCase { - public void testSweetSpotLengthNorm() { + public void testSweetSpotComputeNorm() { SweetSpotSimilarity ss = new SweetSpotSimilarity(); ss.setLengthNormFactors(1,1,0.5f); @@ -37,10 +38,13 @@ public class SweetSpotSimilarityTest extends LuceneTestCase { // base case, should degrade - + final FieldInvertState invertState = new FieldInvertState(); + invertState.setBoost(1.0f); for (int i = 1; i < 1000; i++) { + invertState.setLength(i); assertEquals("base case: i="+i, - d.lengthNorm("foo",i), s.lengthNorm("foo",i), + d.computeNorm("foo", invertState), + s.computeNorm("foo", invertState), 0.0f); } @@ -49,14 +53,21 @@ public class SweetSpotSimilarityTest extends LuceneTestCase { ss.setLengthNormFactors(3,10,0.5f); for (int i = 3; i <=10; i++) { + invertState.setLength(i); assertEquals("3,10: spot i="+i, - 1.0f, s.lengthNorm("foo",i), + 1.0f, + s.computeNorm("foo", invertState), 0.0f); } for (int i = 10; i < 1000; i++) { + invertState.setLength(i-9); + final float normD = d.computeNorm("foo", invertState); + invertState.setLength(i); + final float normS = s.computeNorm("foo", invertState); assertEquals("3,10: 10positionIncrement == 0. * @return the numOverlap @@ -81,6 +85,10 @@ public final class FieldInvertState { return numOverlap; } + public void setNumOverlap(int numOverlap) { + this.numOverlap = numOverlap; + } + /** * Get end offset of the last processed term. * @return the offset @@ -99,6 +107,10 @@ public final class FieldInvertState { return boost; } + public void setBoost(float boost) { + this.boost = boost; + } + public AttributeSource getAttributeSource() { return attributeSource; } diff --git a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java index d756eff3bad..65523a6da7d 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java @@ -63,10 +63,12 @@ public class BooleanQuery extends Query implements Iterable { } private ArrayList clauses = new ArrayList(); - private boolean disableCoord; + private final boolean disableCoord; /** Constructs an empty boolean query. */ - public BooleanQuery() {} + public BooleanQuery() { + disableCoord = false; + } /** Constructs an empty boolean query. * @@ -87,22 +89,6 @@ public class BooleanQuery extends Query implements Iterable { */ public boolean isCoordDisabled() { return disableCoord; } - // Implement coord disabling. - // Inherit javadoc. - @Override - public Similarity getSimilarity(IndexSearcher searcher) { - Similarity result = super.getSimilarity(searcher); - if (disableCoord) { // disable coord as requested - result = new SimilarityDelegator(result) { - @Override - public float coord(int overlap, int maxOverlap) { - return 1.0f; - } - }; - } - return result; - } - /** * Specifies a minimum number of the optional BooleanClauses * which must be satisfied. @@ -179,10 +165,12 @@ public class BooleanQuery extends Query implements Iterable { protected Similarity similarity; protected ArrayList weights; protected int maxCoord; // num optional + num required + private final boolean disableCoord; - public BooleanWeight(IndexSearcher searcher) + public BooleanWeight(IndexSearcher searcher, boolean disableCoord) throws IOException { this.similarity = getSimilarity(searcher); + this.disableCoord = disableCoord; weights = new ArrayList(clauses.size()); for (int i = 0 ; i < clauses.size(); i++) { BooleanClause c = clauses.get(i); @@ -285,10 +273,10 @@ public class BooleanQuery extends Query implements Iterable { sumExpl.setMatch(0 < coord ? Boolean.TRUE : Boolean.FALSE); sumExpl.setValue(sum); - float coordFactor = similarity.coord(coord, maxCoord); - if (coordFactor == 1.0f) // coord is no-op + final float coordFactor = disableCoord ? 1.0f : similarity.coord(coord, maxCoord); + if (coordFactor == 1.0f) { return sumExpl; // eliminate wrapper - else { + } else { ComplexExplanation result = new ComplexExplanation(sumExpl.isMatch(), sum*coordFactor, "product of:"); @@ -324,7 +312,7 @@ public class BooleanQuery extends Query implements Iterable { // Check if we can return a BooleanScorer if (!scoreDocsInOrder && topScorer && required.size() == 0 && prohibited.size() < 32) { - return new BooleanScorer(this, similarity, minNrShouldMatch, optional, prohibited, maxCoord); + return new BooleanScorer(this, disableCoord, similarity, minNrShouldMatch, optional, prohibited, maxCoord); } if (required.size() == 0 && optional.size() == 0) { @@ -338,7 +326,7 @@ public class BooleanQuery extends Query implements Iterable { } // Return a BooleanScorer2 - return new BooleanScorer2(this, similarity, minNrShouldMatch, required, prohibited, optional, maxCoord); + return new BooleanScorer2(this, disableCoord, similarity, minNrShouldMatch, required, prohibited, optional, maxCoord); } @Override @@ -364,7 +352,7 @@ public class BooleanQuery extends Query implements Iterable { @Override public Weight createWeight(IndexSearcher searcher) throws IOException { - return new BooleanWeight(searcher); + return new BooleanWeight(searcher, disableCoord); } @Override diff --git a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java index 3a90fe023ce..a4db5bdb4de 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java @@ -197,9 +197,9 @@ final class BooleanScorer extends Scorer { private Bucket current; private int doc = -1; - BooleanScorer(Weight weight, Similarity similarity, int minNrShouldMatch, + BooleanScorer(Weight weight, boolean disableCoord, Similarity similarity, int minNrShouldMatch, List optionalScorers, List prohibitedScorers, int maxCoord) throws IOException { - super(similarity, weight); + super(null, weight); // Similarity not used this.minNrShouldMatch = minNrShouldMatch; if (optionalScorers != null && optionalScorers.size() > 0) { @@ -222,9 +222,8 @@ final class BooleanScorer extends Scorer { } coordFactors = new float[optionalScorers.size() + 1]; - Similarity sim = getSimilarity(); for (int i = 0; i < coordFactors.length; i++) { - coordFactors[i] = sim.coord(i, maxCoord); + coordFactors[i] = disableCoord ? 1.0f : similarity.coord(i, maxCoord); } } diff --git a/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java b/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java index c8dcf2eba20..0d47da6ce58 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java @@ -42,14 +42,12 @@ class BooleanScorer2 extends Scorer { int maxCoord = 0; // to be increased for each non prohibited scorer int nrMatchers; // to be increased by score() of match counting scorers. - void init() { // use after all scorers have been added. + void init(Similarity sim, boolean disableCoord) { // use after all scorers have been added. coordFactors = new float[optionalScorers.size() + requiredScorers.size() + 1]; - Similarity sim = getSimilarity(); for (int i = 0; i < coordFactors.length; i++) { - coordFactors[i] = sim.coord(i, maxCoord); + coordFactors[i] = disableCoord ? 1.0f : sim.coord(i, maxCoord); } } - } private final Coordinator coordinator; @@ -82,9 +80,9 @@ class BooleanScorer2 extends Scorer { * @param optional * the list of optional scorers. */ - public BooleanScorer2(Weight weight, Similarity similarity, int minNrShouldMatch, + public BooleanScorer2(Weight weight, boolean disableCoord, Similarity similarity, int minNrShouldMatch, List required, List prohibited, List optional, int maxCoord) throws IOException { - super(similarity, weight); + super(null, weight); // Similarity not used if (minNrShouldMatch < 0) { throw new IllegalArgumentException("Minimum number of optional scorers should not be negative"); } @@ -96,8 +94,8 @@ class BooleanScorer2 extends Scorer { requiredScorers = required; prohibitedScorers = prohibited; - coordinator.init(); - countingSumScorer = makeCountingSumScorer(); + coordinator.init(similarity, disableCoord); + countingSumScorer = makeCountingSumScorer(disableCoord, similarity); } /** Count a scorer as a single match. */ @@ -109,7 +107,7 @@ class BooleanScorer2 extends Scorer { private float lastDocScore = Float.NaN; SingleMatchScorer(Scorer scorer) { - super(scorer.getSimilarity()); + super(null); // No similarity used. this.scorer = scorer; } @@ -164,12 +162,12 @@ class BooleanScorer2 extends Scorer { }; } - private static final Similarity defaultSimilarity = Similarity.getDefault(); - - private Scorer countingConjunctionSumScorer(List requiredScorers) throws IOException { + private Scorer countingConjunctionSumScorer(boolean disableCoord, + Similarity similarity, + List requiredScorers) throws IOException { // each scorer from the list counted as a single matcher final int requiredNrMatchers = requiredScorers.size(); - return new ConjunctionScorer(defaultSimilarity, requiredScorers) { + return new ConjunctionScorer(disableCoord ? 1.0f : similarity.coord(requiredScorers.size(), requiredScorers.size()), requiredScorers) { private int lastScoredDoc = -1; // Save the score of lastScoredDoc, so that we don't compute it more than // once in score(). @@ -192,8 +190,10 @@ class BooleanScorer2 extends Scorer { }; } - private Scorer dualConjunctionSumScorer(Scorer req1, Scorer req2) throws IOException { // non counting. - return new ConjunctionScorer(defaultSimilarity, req1, req2); + private Scorer dualConjunctionSumScorer(boolean disableCoord, + Similarity similarity, + Scorer req1, Scorer req2) throws IOException { // non counting. + return new ConjunctionScorer(disableCoord ? 1.0f : similarity.coord(2, 2), req1, req2); // All scorers match, so defaultSimilarity always has 1 as // the coordination factor. // Therefore the sum of the scores of two scorers @@ -203,13 +203,14 @@ class BooleanScorer2 extends Scorer { /** Returns the scorer to be used for match counting and score summing. * Uses requiredScorers, optionalScorers and prohibitedScorers. */ - private Scorer makeCountingSumScorer() throws IOException { // each scorer counted as a single matcher + private Scorer makeCountingSumScorer(boolean disableCoord, + Similarity similarity) throws IOException { // each scorer counted as a single matcher return (requiredScorers.size() == 0) - ? makeCountingSumScorerNoReq() - : makeCountingSumScorerSomeReq(); + ? makeCountingSumScorerNoReq(disableCoord, similarity) + : makeCountingSumScorerSomeReq(disableCoord, similarity); } - private Scorer makeCountingSumScorerNoReq() throws IOException { // No required scorers + private Scorer makeCountingSumScorerNoReq(boolean disableCoord, Similarity similarity) throws IOException { // No required scorers // minNrShouldMatch optional scorers are required, but at least 1 int nrOptRequired = (minNrShouldMatch < 1) ? 1 : minNrShouldMatch; Scorer requiredCountingSumScorer; @@ -217,24 +218,27 @@ class BooleanScorer2 extends Scorer { requiredCountingSumScorer = countingDisjunctionSumScorer(optionalScorers, nrOptRequired); else if (optionalScorers.size() == 1) requiredCountingSumScorer = new SingleMatchScorer(optionalScorers.get(0)); - else - requiredCountingSumScorer = countingConjunctionSumScorer(optionalScorers); + else { + requiredCountingSumScorer = countingConjunctionSumScorer(disableCoord, similarity, optionalScorers); + } return addProhibitedScorers(requiredCountingSumScorer); } - private Scorer makeCountingSumScorerSomeReq() throws IOException { // At least one required scorer. + private Scorer makeCountingSumScorerSomeReq(boolean disableCoord, Similarity similarity) throws IOException { // At least one required scorer. if (optionalScorers.size() == minNrShouldMatch) { // all optional scorers also required. ArrayList allReq = new ArrayList(requiredScorers); allReq.addAll(optionalScorers); - return addProhibitedScorers(countingConjunctionSumScorer(allReq)); + return addProhibitedScorers(countingConjunctionSumScorer(disableCoord, similarity, allReq)); } else { // optionalScorers.size() > minNrShouldMatch, and at least one required scorer Scorer requiredCountingSumScorer = requiredScorers.size() == 1 ? new SingleMatchScorer(requiredScorers.get(0)) - : countingConjunctionSumScorer(requiredScorers); + : countingConjunctionSumScorer(disableCoord, similarity, requiredScorers); if (minNrShouldMatch > 0) { // use a required disjunction scorer over the optional scorers return addProhibitedScorers( dualConjunctionSumScorer( // non counting + disableCoord, + similarity, requiredCountingSumScorer, countingDisjunctionSumScorer( optionalScorers, diff --git a/lucene/src/java/org/apache/lucene/search/ConjunctionScorer.java b/lucene/src/java/org/apache/lucene/search/ConjunctionScorer.java index dd254755a31..3429e3711c5 100644 --- a/lucene/src/java/org/apache/lucene/search/ConjunctionScorer.java +++ b/lucene/src/java/org/apache/lucene/search/ConjunctionScorer.java @@ -29,14 +29,14 @@ class ConjunctionScorer extends Scorer { private final float coord; private int lastDoc = -1; - public ConjunctionScorer(Similarity similarity, Collection scorers) throws IOException { - this(similarity, scorers.toArray(new Scorer[scorers.size()])); + public ConjunctionScorer(float coord, Collection scorers) throws IOException { + this(coord, scorers.toArray(new Scorer[scorers.size()])); } - public ConjunctionScorer(Similarity similarity, Scorer... scorers) throws IOException { - super(similarity); + public ConjunctionScorer(float coord, Scorer... scorers) throws IOException { + super(null); this.scorers = scorers; - coord = similarity.coord(scorers.length, scorers.length); + this.coord = coord; for (int i = 0; i < scorers.length; i++) { if (scorers[i].nextDoc() == NO_MORE_DOCS) { diff --git a/lucene/src/java/org/apache/lucene/search/DefaultSimilarity.java b/lucene/src/java/org/apache/lucene/search/DefaultSimilarity.java index 0ab551ad8b2..e321ff3662c 100644 --- a/lucene/src/java/org/apache/lucene/search/DefaultSimilarity.java +++ b/lucene/src/java/org/apache/lucene/search/DefaultSimilarity.java @@ -37,13 +37,7 @@ public class DefaultSimilarity extends Similarity { numTerms = state.getLength() - state.getNumOverlap(); else numTerms = state.getLength(); - return (state.getBoost() * lengthNorm(field, numTerms)); - } - - /** Implemented as 1/sqrt(numTerms). */ - @Override - public float lengthNorm(String fieldName, int numTerms) { - return (float)(1.0 / Math.sqrt(numTerms)); + return state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms))); } /** Implemented as 1/sqrt(sumOfSquaredWeights). */ diff --git a/lucene/src/java/org/apache/lucene/search/Similarity.java b/lucene/src/java/org/apache/lucene/search/Similarity.java index 81b1a810047..041db1e8ffa 100644 --- a/lucene/src/java/org/apache/lucene/search/Similarity.java +++ b/lucene/src/java/org/apache/lucene/search/Similarity.java @@ -462,12 +462,14 @@ import org.apache.lucene.util.SmallFloat; * {@link org.apache.lucene.document.Fieldable#setBoost(float) field.setBoost()} * before adding the field to a document. * - *
  19. {@link #lengthNorm(String, int) lengthNorm(field)} - computed + *
  20. lengthNorm - computed * when the document is added to the index in accordance with the number of tokens * of this field in the document, so that shorter fields contribute more to the score. * LengthNorm is computed by the Similarity class in effect at indexing. *
  21. * + * The {@link #computeNorm} method is responsible for + * combining all of these factors into a single float. * *

    * When a document is added to the index, all the above factors are multiplied. @@ -480,7 +482,7 @@ import org.apache.lucene.util.SmallFloat; * norm(t,d)   =   * {@link org.apache.lucene.document.Document#getBoost() doc.getBoost()} *  ·  - * {@link #lengthNorm(String, int) lengthNorm(field)} + * lengthNorm *  ·  * * @@ -570,12 +572,23 @@ public abstract class Similarity implements Serializable { } /** - * Compute the normalization value for a field, given the accumulated + * Computes the normalization value for a field, given the accumulated * state of term processing for this field (see {@link FieldInvertState}). * *

    Implementations should calculate a float value based on the field * state and then return that value. * + *

    Matches in longer fields are less precise, so implementations of this + * method usually return smaller values when state.getLength() is large, + * and larger values when state.getLength() is small. + * + *

    Note that the return values are computed under + * {@link org.apache.lucene.index.IndexWriter#addDocument(org.apache.lucene.document.Document)} + * and then stored using + * {@link #encodeNormValue(float)}. + * Thus they have limited precision, and documents + * must be re-indexed if this method is altered. + * *

    For backward compatibility this method by default calls * {@link #lengthNorm(String, int)} passing * {@link FieldInvertState#getLength()} as the second argument, and @@ -587,9 +600,7 @@ public abstract class Similarity implements Serializable { * @param state current processing state for this field * @return the calculated float norm */ - public float computeNorm(String field, FieldInvertState state) { - return (state.getBoost() * lengthNorm(field, state.getLength())); - } + public abstract float computeNorm(String field, FieldInvertState state); /** Computes the normalization value for a field given the total number of * terms contained in a field. These values, together with field boosts, are @@ -613,8 +624,13 @@ public abstract class Similarity implements Serializable { * @return a normalization factor for hits on this field of this document * * @see org.apache.lucene.document.Field#setBoost(float) + * + * @deprecated Please override computeNorm instead */ - public abstract float lengthNorm(String fieldName, int numTokens); + @Deprecated + public final float lengthNorm(String fieldName, int numTokens) { + throw new UnsupportedOperationException("please use computeNorm instead"); + } /** Computes the normalization value for a query given the sum of the squared * weights of each of the query terms. This value is multiplied into the diff --git a/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java b/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java deleted file mode 100644 index d68e18aba36..00000000000 --- a/lucene/src/java/org/apache/lucene/search/SimilarityDelegator.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.lucene.search; - -import org.apache.lucene.index.FieldInvertState; - -/** - * 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. - */ - -/** Expert: Delegating scoring implementation. Useful in {@link - * Query#getSimilarity(IndexSearcher)} implementations, to override only certain - * methods of a Searcher's Similarity implementation.. */ -public class SimilarityDelegator extends Similarity { - - private Similarity delegee; - - /** Construct a {@link Similarity} that delegates all methods to another. - * - * @param delegee the Similarity implementation to delegate to - */ - public SimilarityDelegator(Similarity delegee) { - this.delegee = delegee; - } - - @Override - public float computeNorm(String fieldName, FieldInvertState state) { - return delegee.computeNorm(fieldName, state); - } - - @Override - public float lengthNorm(String fieldName, int numTerms) { - return delegee.lengthNorm(fieldName, numTerms); - } - - @Override - public float queryNorm(float sumOfSquaredWeights) { - return delegee.queryNorm(sumOfSquaredWeights); - } - - @Override - public float tf(float freq) { - return delegee.tf(freq); - } - - @Override - public float sloppyFreq(int distance) { - return delegee.sloppyFreq(distance); - } - - @Override - public float idf(int docFreq, int numDocs) { - return delegee.idf(docFreq, numDocs); - } - - @Override - public float coord(int overlap, int maxOverlap) { - return delegee.coord(overlap, maxOverlap); - } - - @Override - public float scorePayload(int docId, String fieldName, int start, int end, byte [] payload, int offset, int length) { - return delegee.scorePayload(docId, fieldName, start, end, payload, offset, length); - } -} diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java b/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java index 4a0e6b7162c..157c08719eb 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexReaderCloneNorms.java @@ -42,8 +42,9 @@ public class TestIndexReaderCloneNorms extends LuceneTestCase { private class SimilarityOne extends DefaultSimilarity { @Override - public float lengthNorm(String fieldName, int numTerms) { - return 1; + public float computeNorm(String fieldName, FieldInvertState state) { + // diable length norm + return state.getBoost(); } } diff --git a/lucene/src/test/org/apache/lucene/index/TestNorms.java b/lucene/src/test/org/apache/lucene/index/TestNorms.java index 460e61338c6..ceeae1552fb 100755 --- a/lucene/src/test/org/apache/lucene/index/TestNorms.java +++ b/lucene/src/test/org/apache/lucene/index/TestNorms.java @@ -41,8 +41,9 @@ public class TestNorms extends LuceneTestCase { private class SimilarityOne extends DefaultSimilarity { @Override - public float lengthNorm(String fieldName, int numTerms) { - return 1; + public float computeNorm(String fieldName, FieldInvertState state) { + // Disable length norm + return state.getBoost(); } } diff --git a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java index 49c72e6c029..78b96dc5d32 100644 --- a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java +++ b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java @@ -35,7 +35,7 @@ import org.apache.lucene.search.Explanation.IDFExplanation; public class TestOmitTf extends LuceneTestCase { public static class SimpleSimilarity extends Similarity { - @Override public float lengthNorm(String field, int numTerms) { return 1.0f; } + @Override public float computeNorm(String field, FieldInvertState state) { return state.getBoost(); } @Override public float queryNorm(float sumOfSquaredWeights) { return 1.0f; } @Override public float tf(float freq) { return freq; } @Override public float sloppyFreq(int distance) { return 2.0f; } diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index 25c43b69921..43cd8370e5a 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -22,6 +22,7 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.util.PriorityQueue; /** @@ -253,7 +254,7 @@ final class JustCompileSearch { } @Override - public float lengthNorm(String fieldName, int numTokens) { + public float computeNorm(String fieldName, FieldInvertState state) { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java b/lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java index 297aabe3f4c..4628e911773 100644 --- a/lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestBooleanScorer.java @@ -83,7 +83,7 @@ public class TestBooleanScorer extends LuceneTestCase } }}; - BooleanScorer bs = new BooleanScorer(null, sim, 1, Arrays.asList(scorers), null, scorers.length); + BooleanScorer bs = new BooleanScorer(null, false, sim, 1, Arrays.asList(scorers), null, scorers.length); assertEquals("should have received 3000", 3000, bs.nextDoc()); assertEquals("should have received NO_MORE_DOCS", DocIdSetIterator.NO_MORE_DOCS, bs.nextDoc()); diff --git a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java index 1b89d4dd7dc..aa7b9faaff5 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java @@ -23,6 +23,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.SlowMultiReaderWrapper; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexReader.ReaderContext; @@ -60,8 +61,9 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { } @Override - public float lengthNorm(String fieldName, int numTerms) { - return 1.0f; + public float computeNorm(String fieldName, FieldInvertState state) { + // Disable length norm + return state.getBoost(); } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestSimilarity.java b/lucene/src/test/org/apache/lucene/search/TestSimilarity.java index 9518a025ed9..fd459103777 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSimilarity.java +++ b/lucene/src/test/org/apache/lucene/search/TestSimilarity.java @@ -21,6 +21,7 @@ import org.apache.lucene.util.LuceneTestCase; import java.io.IOException; import java.util.Collection; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -38,7 +39,7 @@ import org.apache.lucene.search.Explanation.IDFExplanation; public class TestSimilarity extends LuceneTestCase { public static class SimpleSimilarity extends Similarity { - @Override public float lengthNorm(String field, int numTerms) { return 1.0f; } + @Override public float computeNorm(String field, FieldInvertState state) { return state.getBoost(); } @Override public float queryNorm(float sumOfSquaredWeights) { return 1.0f; } @Override public float tf(float freq) { return freq; } @Override public float sloppyFreq(int distance) { return 2.0f; } diff --git a/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java b/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java index a006fb04e81..8863e783bb4 100644 --- a/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java +++ b/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadNearQuery.java @@ -26,6 +26,7 @@ import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.PayloadAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Payload; import org.apache.lucene.index.RandomIndexWriter; @@ -305,8 +306,8 @@ public class TestPayloadNearQuery extends LuceneTestCase { //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Make everything else 1 so we see the effect of the payload //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - @Override public float lengthNorm(String fieldName, int numTerms) { - return 1.0f; + @Override public float computeNorm(String fieldName, FieldInvertState state) { + return state.getBoost(); } @Override public float queryNorm(float sumOfSquaredWeights) { diff --git a/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java b/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java index a5a8550f623..0a053584165 100644 --- a/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java +++ b/lucene/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java @@ -34,6 +34,7 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.TokenFilter; import org.apache.lucene.analysis.tokenattributes.PayloadAttribute; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Payload; import org.apache.lucene.index.RandomIndexWriter; @@ -299,8 +300,8 @@ public class TestPayloadTermQuery extends LuceneTestCase { //Make everything else 1 so we see the effect of the payload //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @Override - public float lengthNorm(String fieldName, int numTerms) { - return 1; + public float computeNorm(String fieldName, FieldInvertState state) { + return state.getBoost(); } @Override diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java index 9d3c83adbae..ca83e3a67e0 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java @@ -419,7 +419,7 @@ public class TestSpans extends LuceneTestCase { public Similarity getSimilarity(IndexSearcher s) { return sim; } - }; + }; Scorer spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), true, false); diff --git a/solr/src/java/org/apache/solr/search/SolrSimilarity.java b/solr/src/java/org/apache/solr/search/SolrSimilarity.java deleted file mode 100644 index 60525376d57..00000000000 --- a/solr/src/java/org/apache/solr/search/SolrSimilarity.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * 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. - */ - -package org.apache.solr.search; - -import org.apache.lucene.search.DefaultSimilarity; - -import java.util.HashMap; - -/** - */ -// don't make it public for now... easier to change later. - -// This class is currently unused. -class SolrSimilarity extends DefaultSimilarity { - private final HashMap lengthNormConfig = new HashMap(); - - public float lengthNorm(String fieldName, int numTerms) { - // Float f = lengthNormConfig. - // if (lengthNormDisabled.) - return super.lengthNorm(fieldName, numTerms); - } -} diff --git a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java index 4cfebb79c94..7ac1d8e50fa 100755 --- a/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java +++ b/solr/src/test/org/apache/solr/search/function/TestFunctionQuery.java @@ -17,6 +17,7 @@ package org.apache.solr.search.function; +import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.Similarity; @@ -294,8 +295,11 @@ public class TestFunctionQuery extends SolrTestCaseJ4 { "//float[@name='score']='" + similarity.idf(3,6) + "'"); assertQ(req("fl","*,score","q", "{!func}tf(a_t,cow)", "fq","id:6"), "//float[@name='score']='" + similarity.tf(5) + "'"); + FieldInvertState state = new FieldInvertState(); + state.setBoost(1.0f); + state.setLength(4); assertQ(req("fl","*,score","q", "{!func}norm(a_t)", "fq","id:2"), - "//float[@name='score']='" + similarity.lengthNorm("a_t",4) + "'"); // sqrt(4)==2 and is exactly representable when quantized to a byte + "//float[@name='score']='" + similarity.computeNorm("a_t",state) + "'"); // sqrt(4)==2 and is exactly representable when quantized to a byte // test that ord and rord are working on a global index basis, not just // at the segment level (since Lucene 2.9 has switched to per-segment searching) From eacd3d2636d1baefd503e76c467d5ae07cfce728 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Sat, 8 Jan 2011 22:31:00 +0000 Subject: [PATCH 034/252] LUCENE-1260: use the provided sim to encode norms git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056821 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/lucene/index/NormsWriter.java | 2 +- .../lucene/index/NormsWriterPerField.java | 2 +- .../org/apache/lucene/search/Similarity.java | 11 ++++- .../org/apache/lucene/index/TestNorms.java | 48 +++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/NormsWriter.java b/lucene/src/java/org/apache/lucene/index/NormsWriter.java index c145227382b..036832297cf 100644 --- a/lucene/src/java/org/apache/lucene/index/NormsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/NormsWriter.java @@ -37,7 +37,7 @@ import org.apache.lucene.search.Similarity; final class NormsWriter extends InvertedDocEndConsumer { - private static final byte defaultNorm = Similarity.getDefault().encodeNormValue(1.0f); + private final byte defaultNorm = Similarity.getDefault().encodeNormValue(1.0f); private FieldInfos fieldInfos; @Override public InvertedDocEndConsumerPerThread addThread(DocInverterPerThread docInverterPerThread) { diff --git a/lucene/src/java/org/apache/lucene/index/NormsWriterPerField.java b/lucene/src/java/org/apache/lucene/index/NormsWriterPerField.java index c2b331db057..b0827597097 100644 --- a/lucene/src/java/org/apache/lucene/index/NormsWriterPerField.java +++ b/lucene/src/java/org/apache/lucene/index/NormsWriterPerField.java @@ -73,7 +73,7 @@ final class NormsWriterPerField extends InvertedDocEndConsumerPerField implement norms = ArrayUtil.grow(norms, 1+upto); } final float norm = docState.similarity.computeNorm(fieldInfo.name, fieldState); - norms[upto] = Similarity.getDefault().encodeNormValue(norm); + norms[upto] = docState.similarity.encodeNormValue(norm); docIDs[upto] = docState.docID; upto++; } diff --git a/lucene/src/java/org/apache/lucene/search/Similarity.java b/lucene/src/java/org/apache/lucene/search/Similarity.java index 041db1e8ffa..e1278cb3605 100644 --- a/lucene/src/java/org/apache/lucene/search/Similarity.java +++ b/lucene/src/java/org/apache/lucene/search/Similarity.java @@ -565,6 +565,11 @@ public abstract class Similarity implements Serializable { } /** Decodes a normalization factor stored in an index. + *

    + * WARNING: If you override this method, you should change the default + * Similarity to your implementation with {@link Similarity#setDefault(Similarity)}. + * Otherwise, your method may not always be called, especially if you omit norms + * for some fields. * @see #encodeNormValue(float) */ public float decodeNormValue(byte b) { @@ -657,7 +662,11 @@ public abstract class Similarity implements Serializable { * are rounded down to the largest representable value. Positive values too * small to represent are rounded up to the smallest positive representable * value. - * + *

    + * WARNING: If you override this method, you should change the default + * Similarity to your implementation with {@link Similarity#setDefault(Similarity)}. + * Otherwise, your method may not always be called, especially if you omit norms + * for some fields. * @see org.apache.lucene.document.Field#setBoost(float) * @see org.apache.lucene.util.SmallFloat */ diff --git a/lucene/src/test/org/apache/lucene/index/TestNorms.java b/lucene/src/test/org/apache/lucene/index/TestNorms.java index ceeae1552fb..b7efe88fa35 100755 --- a/lucene/src/test/org/apache/lucene/index/TestNorms.java +++ b/lucene/src/test/org/apache/lucene/index/TestNorms.java @@ -237,4 +237,52 @@ public class TestNorms extends LuceneTestCase { return norm; } + class CustomNormEncodingSimilarity extends DefaultSimilarity { + @Override + public byte encodeNormValue(float f) { + return (byte) f; + } + + @Override + public float decodeNormValue(byte b) { + return (float) b; + } + + @Override + public float computeNorm(String field, FieldInvertState state) { + return (float) state.getLength(); + } + } + + // LUCENE-1260 + public void testCustomEncoder() throws Exception { + Directory dir = newDirectory(); + IndexWriterConfig config = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer()); + config.setSimilarity(new CustomNormEncodingSimilarity()); + RandomIndexWriter writer = new RandomIndexWriter(random, dir, config); + Document doc = new Document(); + Field foo = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED); + Field bar = newField("bar", "", Field.Store.NO, Field.Index.ANALYZED); + doc.add(foo); + doc.add(bar); + + for (int i = 0; i < 100; i++) { + bar.setValue("singleton"); + writer.addDocument(doc); + } + + IndexReader reader = writer.getReader(); + writer.close(); + + byte fooNorms[] = MultiNorms.norms(reader, "foo"); + for (int i = 0; i < reader.maxDoc(); i++) + assertEquals(0, fooNorms[i]); + + byte barNorms[] = MultiNorms.norms(reader, "bar"); + for (int i = 0; i < reader.maxDoc(); i++) + assertEquals(1, barNorms[i]); + + reader.close(); + dir.close(); + } } From 821e52604c9cd4d9ea8499f8b5b99d8a292d9491 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sun, 9 Jan 2011 14:59:13 +0000 Subject: [PATCH 035/252] whitespace git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1056955 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/java/org/apache/lucene/search/Similarity.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/search/Similarity.java b/lucene/src/java/org/apache/lucene/search/Similarity.java index e1278cb3605..f88645b6a8b 100644 --- a/lucene/src/java/org/apache/lucene/search/Similarity.java +++ b/lucene/src/java/org/apache/lucene/search/Similarity.java @@ -761,7 +761,7 @@ public abstract class Similarity implements Serializable { public float getIdf() { return idf; }}; - } + } /** * This method forwards to {@link @@ -770,7 +770,7 @@ public abstract class Similarity implements Serializable { */ public IDFExplanation idfExplain(final Term term, final IndexSearcher searcher) throws IOException { return idfExplain(term, searcher, searcher.docFreq(term)); - } + } /** * Computes a score factor for a phrase. From a04ade4448a0623829b00dff45bc77dc2705105f Mon Sep 17 00:00:00 2001 From: Uwe Schindler Date: Sun, 9 Jan 2011 19:48:14 +0000 Subject: [PATCH 036/252] LUCENE-2839: Scorer#score(Collector,int,int) is now public because it is called from other classes and part of public API git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057010 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 +++ lucene/src/java/org/apache/lucene/search/BooleanScorer.java | 2 +- lucene/src/java/org/apache/lucene/search/BooleanScorer2.java | 2 +- .../src/java/org/apache/lucene/search/ConstantScoreQuery.java | 4 +--- .../java/org/apache/lucene/search/DisjunctionSumScorer.java | 2 +- .../org/apache/lucene/search/ScoreCachingWrappingScorer.java | 2 +- lucene/src/java/org/apache/lucene/search/Scorer.java | 2 +- lucene/src/java/org/apache/lucene/search/TermScorer.java | 2 +- .../src/test/org/apache/lucene/search/JustCompileSearch.java | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index fdd2e6c78d1..7ca14de759b 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -131,6 +131,9 @@ Changes in backwards compatibility policy * LUCENE-2837: Changed Weight#scorer, Weight#explain & Filter#getDocIdSet to operate on a ReaderContext instead of directly on IndexReader to enable searches to be aware of IndexSearcher's context. (Simon Willnauer) + +* LUCENE-2839: Scorer#score(Collector,int,int) is now public because it is + called from other classes and part of public API. (Uwe Schindler) Changes in Runtime Behavior diff --git a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java index a4db5bdb4de..6374e89f98b 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java @@ -229,7 +229,7 @@ final class BooleanScorer extends Scorer { // firstDocID is ignored since nextDoc() initializes 'current' @Override - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { boolean more; Bucket tmp; BucketScorer bs = new BucketScorer(); diff --git a/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java b/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java index 0d47da6ce58..d1a7a6d38b7 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanScorer2.java @@ -280,7 +280,7 @@ class BooleanScorer2 extends Scorer { } @Override - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { doc = firstDocID; collector.setScorer(this); while (doc < max) { diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index 6af8ed5305c..10090e98ee9 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -244,10 +244,8 @@ public class ConstantScoreQuery extends Query { } // this optimization allows out of order scoring as top scorer, - // TODO: theoretically this method should not be called because its protected and - // this class does not use it, it should be public in Scorer! @Override - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { if (docIdSetIterator instanceof Scorer) { return ((Scorer) docIdSetIterator).score(wrapCollector(collector), max, firstDocID); } else { diff --git a/lucene/src/java/org/apache/lucene/search/DisjunctionSumScorer.java b/lucene/src/java/org/apache/lucene/search/DisjunctionSumScorer.java index 7e5016d902b..5ec3514e95b 100644 --- a/lucene/src/java/org/apache/lucene/search/DisjunctionSumScorer.java +++ b/lucene/src/java/org/apache/lucene/search/DisjunctionSumScorer.java @@ -123,7 +123,7 @@ class DisjunctionSumScorer extends Scorer { * @return true if more matching documents may remain. */ @Override - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { // firstDocID is ignored since nextDoc() sets 'currentDoc' collector.setScorer(this); while (currentDoc < max) { diff --git a/lucene/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java b/lucene/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java index 09a0bcd817d..b35e452252f 100644 --- a/lucene/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java +++ b/lucene/src/java/org/apache/lucene/search/ScoreCachingWrappingScorer.java @@ -43,7 +43,7 @@ public class ScoreCachingWrappingScorer extends Scorer { } @Override - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { return scorer.score(collector, max, firstDocID); } diff --git a/lucene/src/java/org/apache/lucene/search/Scorer.java b/lucene/src/java/org/apache/lucene/search/Scorer.java index 84e51431e88..907cdf3aa8a 100644 --- a/lucene/src/java/org/apache/lucene/search/Scorer.java +++ b/lucene/src/java/org/apache/lucene/search/Scorer.java @@ -90,7 +90,7 @@ public abstract class Scorer extends DocIdSetIterator { * this method. * @return true if more matching documents may remain. */ - protected boolean score(Collector collector, int max, int firstDocID) throws IOException { + public boolean score(Collector collector, int max, int firstDocID) throws IOException { collector.setScorer(this); int doc = firstDocID; while (doc < max) { diff --git a/lucene/src/java/org/apache/lucene/search/TermScorer.java b/lucene/src/java/org/apache/lucene/search/TermScorer.java index 48ddd3e05cd..cffea443afc 100644 --- a/lucene/src/java/org/apache/lucene/search/TermScorer.java +++ b/lucene/src/java/org/apache/lucene/search/TermScorer.java @@ -77,7 +77,7 @@ final class TermScorer extends Scorer { // firstDocID is ignored since nextDoc() sets 'doc' @Override - protected boolean score(Collector c, int end, int firstDocID) throws IOException { + public boolean score(Collector c, int end, int firstDocID) throws IOException { c.setScorer(this); while (doc < end) { // for docs in window c.collect(doc); // collect score diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index 43cd8370e5a..f0488f5b7d4 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -215,7 +215,7 @@ final class JustCompileSearch { } @Override - protected boolean score(Collector collector, int max, int firstDocID) + public boolean score(Collector collector, int max, int firstDocID) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } From b36ad7b31b5c2cf866261647e99c66c0e5197d81 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Sun, 9 Jan 2011 20:42:16 +0000 Subject: [PATCH 037/252] LUCENE-2611: Added autolinkification for JIRA issues in log comments (thanks to David Smiley) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057023 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/idea/.idea/vcs.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dev-tools/idea/.idea/vcs.xml b/dev-tools/idea/.idea/vcs.xml index ebabb34f161..ad48dc971f9 100644 --- a/dev-tools/idea/.idea/vcs.xml +++ b/dev-tools/idea/.idea/vcs.xml @@ -1,5 +1,15 @@ + + + From 2e03681712e6a77cc9d53d3550a943001a6e4f8c Mon Sep 17 00:00:00 2001 From: Koji Sekiguchi Date: Mon, 10 Jan 2011 10:58:57 +0000 Subject: [PATCH 038/252] SOLR-2296: Upgrade Carrot2 binaries to version 3.4.2 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057149 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 2 +- solr/contrib/clustering/lib/carrot2-core-3.4.0.jar | 2 -- solr/contrib/clustering/lib/carrot2-core-3.4.2.jar | 2 ++ .../clustering/carrot2/LuceneLanguageModelFactory.java | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 solr/contrib/clustering/lib/carrot2-core-3.4.0.jar create mode 100644 solr/contrib/clustering/lib/carrot2-core-3.4.2.jar diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 7affd988920..cb1d6450d84 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -26,7 +26,7 @@ Versions of Major Components --------------------- Apache Lucene trunk Apache Tika 0.8-SNAPSHOT -Carrot2 3.1.0 +Carrot2 3.4.2 Velocity 1.6.4 and Velocity Tools 2.0 diff --git a/solr/contrib/clustering/lib/carrot2-core-3.4.0.jar b/solr/contrib/clustering/lib/carrot2-core-3.4.0.jar deleted file mode 100644 index a09b28ac477..00000000000 --- a/solr/contrib/clustering/lib/carrot2-core-3.4.0.jar +++ /dev/null @@ -1,2 +0,0 @@ -AnyObjectId[96c3bdbdaacd5289b0e654842e435689fbcf22e2] was removed in git history. -Apache SVN contains full history. \ No newline at end of file diff --git a/solr/contrib/clustering/lib/carrot2-core-3.4.2.jar b/solr/contrib/clustering/lib/carrot2-core-3.4.2.jar new file mode 100644 index 00000000000..6b8fdb5699c --- /dev/null +++ b/solr/contrib/clustering/lib/carrot2-core-3.4.2.jar @@ -0,0 +1,2 @@ +AnyObjectId[f872cbc8eec94f7d5b29a73f99cd13089848a3cd] was removed in git history. +Apache SVN contains full history. \ No newline at end of file diff --git a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java index d7b2ace1f6b..ddb3d59bce8 100644 --- a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java +++ b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java @@ -31,7 +31,7 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.carrot2.core.LanguageCode; import org.carrot2.text.analysis.ExtendedWhitespaceTokenizer; import org.carrot2.text.analysis.ITokenizer; -import org.carrot2.text.linguistic.BaseLanguageModelFactory; +import org.carrot2.text.linguistic.DefaultLanguageModelFactory; import org.carrot2.text.linguistic.IStemmer; import org.carrot2.text.linguistic.IdentityStemmer; import org.carrot2.text.util.MutableCharArray; @@ -62,7 +62,7 @@ import org.tartarus.snowball.ext.TurkishStemmer; * change, the changes can be made in this class. */ @Bindable(prefix = "DefaultLanguageModelFactory") -public class LuceneLanguageModelFactory extends BaseLanguageModelFactory { +public class LuceneLanguageModelFactory extends DefaultLanguageModelFactory { final static Logger logger = org.slf4j.LoggerFactory .getLogger(LuceneLanguageModelFactory.class); From db175cce712580d44194ba2e97ad3ca8b51af9f7 Mon Sep 17 00:00:00 2001 From: Koji Sekiguchi Date: Mon, 10 Jan 2011 14:51:13 +0000 Subject: [PATCH 039/252] SOLR-2310: getTimeElapsedSince() returns incorrect hour value when the elapse is over 60 hours git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057221 13f79535-47bb-0310-9956-ffa450edef68 --- solr/contrib/dataimporthandler/CHANGES.txt | 5 ++++- .../java/org/apache/solr/handler/dataimport/DocBuilder.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/solr/contrib/dataimporthandler/CHANGES.txt b/solr/contrib/dataimporthandler/CHANGES.txt index 83b022e194c..dcd0185895b 100644 --- a/solr/contrib/dataimporthandler/CHANGES.txt +++ b/solr/contrib/dataimporthandler/CHANGES.txt @@ -8,7 +8,7 @@ HTTP data sources quick and easy. $Id$ -================== 1.5.0-dev ================== +================== 4.0.0-dev ================== Upgrading from Solr 1.4 ---------------------- @@ -65,6 +65,9 @@ Bug Fixes * SOLR-1811: formatDate should use the current NOW value always (Sean Timm via noble) +* SOLR-2310: getTimeElapsedSince() returns incorrect hour value when the elapse is over 60 hours + (tom liu via koji) + Other Changes ---------------------- diff --git a/solr/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DocBuilder.java b/solr/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DocBuilder.java index 86afe4af433..e94ba8947f8 100644 --- a/solr/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DocBuilder.java +++ b/solr/contrib/dataimporthandler/src/main/java/org/apache/solr/handler/dataimport/DocBuilder.java @@ -949,7 +949,7 @@ public class DocBuilder { static String getTimeElapsedSince(long l) { l = System.currentTimeMillis() - l; - return (l / (60000 * 60)) % 60 + ":" + (l / 60000) % 60 + ":" + (l / 1000) + return (l / (60000 * 60)) + ":" + (l / 60000) % 60 + ":" + (l / 1000) % 60 + "." + l % 1000; } From 1df9242981e959fe7a07281b1a7e8304ba666b2d Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Mon, 10 Jan 2011 20:08:17 +0000 Subject: [PATCH 040/252] try (again) to stop false failures in this test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057340 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/test/org/apache/lucene/search/TestThreadSafe.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java b/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java index 048ad57ecdc..5a57d54b64b 100755 --- a/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java +++ b/lucene/src/test/org/apache/lucene/search/TestThreadSafe.java @@ -142,7 +142,7 @@ public class TestThreadSafe extends LuceneTestCase { buildDir(dir1, 15, 5, 2000); // do many small tests so the thread locals go away inbetween - int num = 100 * RANDOM_MULTIPLIER; + int num = 10 * RANDOM_MULTIPLIER; for (int i = 0; i < num; i++) { ir1 = IndexReader.open(dir1, false); doTest(10,10); From 52124d8ebfe4c7ee73caea0f10cf88feb68f5ded Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Tue, 11 Jan 2011 11:59:26 +0000 Subject: [PATCH 041/252] LUCENE-2831: cut over to AtomicReaderContext in Weight#scorer, Weight#explain & Filter#getDocIdSet git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057595 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/search/BooleanFilter.java | 8 +-- .../apache/lucene/search/ChainedFilter.java | 24 +++---- .../apache/lucene/search/DuplicateFilter.java | 4 +- .../search/FieldCacheRewriteMethod.java | 4 +- .../org/apache/lucene/search/TermsFilter.java | 4 +- .../apache/lucene/search/TermsFilterTest.java | 5 +- .../geohash/GeoHashDistanceFilter.java | 4 +- .../spatial/tier/CartesianShapeFilter.java | 4 +- .../spatial/tier/LatLongDistanceFilter.java | 4 +- .../lucene/spatial/tier/TestDistance.java | 3 +- .../builders/NumericRangeFilterBuilder.java | 4 +- .../TestNumericRangeFilterBuilder.java | 6 +- .../apache/lucene/index/BufferedDeletes.java | 7 +- .../apache/lucene/search/BooleanQuery.java | 6 +- .../lucene/search/CachingSpanFilter.java | 4 +- .../lucene/search/CachingWrapperFilter.java | 4 +- .../lucene/search/ConstantScoreQuery.java | 6 +- .../lucene/search/DisjunctionMaxQuery.java | 6 +- .../lucene/search/FieldCacheRangeFilter.java | 18 ++--- .../lucene/search/FieldCacheTermsFilter.java | 4 +- .../java/org/apache/lucene/search/Filter.java | 7 +- .../apache/lucene/search/FilteredQuery.java | 6 +- .../apache/lucene/search/IndexSearcher.java | 67 ++++++++----------- .../lucene/search/MatchAllDocsQuery.java | 6 +- .../lucene/search/MultiPhraseQuery.java | 6 +- .../search/MultiTermQueryWrapperFilter.java | 4 +- .../org/apache/lucene/search/PhraseQuery.java | 6 +- .../lucene/search/QueryWrapperFilter.java | 8 ++- .../apache/lucene/search/SpanQueryFilter.java | 4 +- .../org/apache/lucene/search/TermQuery.java | 19 +++++- .../java/org/apache/lucene/search/Weight.java | 22 ++---- .../search/function/CustomScoreQuery.java | 8 +-- .../search/function/ValueSourceQuery.java | 6 +- .../search/payloads/PayloadNearQuery.java | 4 +- .../search/payloads/PayloadTermQuery.java | 4 +- .../lucene/search/spans/SpanWeight.java | 6 +- .../org/apache/lucene/util/ReaderUtil.java | 15 +++++ .../search/CachingWrapperFilterHelper.java | 4 +- .../lucene/search/JustCompileSearch.java | 10 +-- .../org/apache/lucene/search/MockFilter.java | 4 +- .../org/apache/lucene/search/QueryUtils.java | 23 +++---- .../lucene/search/SingleDocTestFilter.java | 4 +- .../search/TestCachingWrapperFilter.java | 22 +++--- .../search/TestDisjunctionMaxQuery.java | 6 +- .../apache/lucene/search/TestDocIdSet.java | 4 +- .../lucene/search/TestFilteredQuery.java | 6 +- .../lucene/search/TestFilteredSearch.java | 3 +- .../search/TestNumericRangeQuery32.java | 8 ++- .../search/TestNumericRangeQuery64.java | 8 ++- .../apache/lucene/search/TestScorerPerf.java | 4 +- .../org/apache/lucene/search/TestSort.java | 4 +- .../apache/lucene/search/TestTermScorer.java | 15 +++-- .../search/spans/TestNearSpansOrdered.java | 7 +- .../PerSegmentSingleValuedFaceting.java | 16 ++--- .../org/apache/solr/schema/LatLonType.java | 6 +- .../java/org/apache/solr/search/DocSet.java | 4 +- .../solr/search/SolrConstantScoreQuery.java | 10 +-- .../org/apache/solr/search/SolrFilter.java | 3 +- .../apache/solr/search/SortedIntDocSet.java | 3 +- .../solr/search/function/BoostedQuery.java | 7 +- .../solr/search/function/FunctionQuery.java | 5 +- .../search/function/ScaleFloatFunction.java | 5 +- .../solr/search/function/ValueSource.java | 1 - .../org/apache/solr/search/TestDocSet.java | 17 +++-- .../test/org/apache/solr/search/TestSort.java | 4 +- 65 files changed, 276 insertions(+), 264 deletions(-) diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java index e3748774456..99a84b20bb7 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/BooleanFilter.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.ArrayList; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.OpenBitSetDISI; @@ -42,10 +42,10 @@ public class BooleanFilter extends Filter ArrayList notFilters = null; ArrayList mustFilters = null; - private DocIdSetIterator getDISI(ArrayList filters, int index, ReaderContext info) + private DocIdSetIterator getDISI(ArrayList filters, int index, AtomicReaderContext context) throws IOException { - return filters.get(index).getDocIdSet(info).iterator(); + return filters.get(index).getDocIdSet(context).iterator(); } /** @@ -53,7 +53,7 @@ public class BooleanFilter extends Filter * of the filters that have been added. */ @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { OpenBitSetDISI res = null; final IndexReader reader = context.reader; diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java index a8cc00caf5f..4041792f5af 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/ChainedFilter.java @@ -20,7 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; @@ -97,7 +97,7 @@ public class ChainedFilter extends Filter * {@link Filter#getDocIdSet}. */ @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException + public DocIdSet getDocIdSet(AtomicReaderContext context) 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. @@ -109,9 +109,9 @@ public class ChainedFilter extends Filter return getDocIdSet(context, DEFAULT, index); } - private DocIdSetIterator getDISI(Filter filter, ReaderContext info) + private DocIdSetIterator getDISI(Filter filter, AtomicReaderContext context) throws IOException { - DocIdSet docIdSet = filter.getDocIdSet(info); + DocIdSet docIdSet = filter.getDocIdSet(context); if (docIdSet == null) { return DocIdSet.EMPTY_DOCIDSET.iterator(); } else { @@ -124,10 +124,10 @@ public class ChainedFilter extends Filter } } - private OpenBitSetDISI initialResult(ReaderContext info, int logic, int[] index) + private OpenBitSetDISI initialResult(AtomicReaderContext context, int logic, int[] index) throws IOException { - IndexReader reader = info.reader; + IndexReader reader = context.reader; OpenBitSetDISI result; /** * First AND operation takes place against a completely false @@ -135,12 +135,12 @@ public class ChainedFilter extends Filter */ if (logic == AND) { - result = new OpenBitSetDISI(getDISI(chain[index[0]], info), reader.maxDoc()); + result = new OpenBitSetDISI(getDISI(chain[index[0]], context), reader.maxDoc()); ++index[0]; } else if (logic == ANDNOT) { - result = new OpenBitSetDISI(getDISI(chain[index[0]], info), reader.maxDoc()); + result = new OpenBitSetDISI(getDISI(chain[index[0]], context), reader.maxDoc()); result.flip(0,reader.maxDoc()); // NOTE: may set bits for deleted docs. ++index[0]; } @@ -157,13 +157,13 @@ public class ChainedFilter extends Filter * @param logic Logical operation * @return DocIdSet */ - private DocIdSet getDocIdSet(ReaderContext info, int logic, int[] index) + private DocIdSet getDocIdSet(AtomicReaderContext context, int logic, int[] index) throws IOException { - OpenBitSetDISI result = initialResult(info, logic, index); + OpenBitSetDISI result = initialResult(context, logic, index); for (; index[0] < chain.length; index[0]++) { - doChain(result, logic, chain[index[0]].getDocIdSet(info)); + doChain(result, logic, chain[index[0]].getDocIdSet(context)); } return result; } @@ -174,7 +174,7 @@ public class ChainedFilter extends Filter * @param logic Logical operation * @return DocIdSet */ - private DocIdSet getDocIdSet(ReaderContext info, int[] logic, int[] index) + private DocIdSet getDocIdSet(AtomicReaderContext info, int[] logic, int[] index) throws IOException { if (logic.length != chain.length) diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java index 5f2e3b1528f..3b0c8de8296 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/DuplicateFilter.java @@ -19,7 +19,7 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.TermsEnum; @@ -72,7 +72,7 @@ public class DuplicateFilter extends Filter } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { if(processingMode==PM_FAST_INVALIDATION) { diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java index 6dee395ab70..5e83c75bc9e 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.Comparator; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.BytesRef; @@ -109,7 +109,7 @@ public final class FieldCacheRewriteMethod extends MultiTermQuery.RewriteMethod * results. */ @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(context.reader, query.field); final OpenBitSet termSet = new OpenBitSet(fcsi.numOrd()); TermsEnum termsEnum = query.getTermsEnum(new Terms() { diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java index e1ab950ab0c..f5c48c90fb2 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/TermsFilter.java @@ -23,7 +23,7 @@ import java.util.Set; import java.util.TreeSet; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.Terms; @@ -58,7 +58,7 @@ public class TermsFilter extends Filter * @see org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader) */ @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { IndexReader reader = context.reader; OpenBitSet result=new OpenBitSet(reader.maxDoc()); Fields fields = reader.fields(); diff --git a/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java b/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java index 27d76cdb8df..dfe6f8b8f6e 100644 --- a/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java +++ b/lucene/contrib/queries/src/test/org/apache/lucene/search/TermsFilterTest.java @@ -21,7 +21,7 @@ import java.util.HashSet; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -60,7 +60,8 @@ public class TermsFilterTest extends LuceneTestCase { w.addDocument(doc); } IndexReader reader = new SlowMultiReaderWrapper(w.getReader()); - ReaderContext context = reader.getTopReaderContext(); + assertTrue(reader.getTopReaderContext().isAtomic); + AtomicReaderContext context = (AtomicReaderContext) reader.getTopReaderContext(); assertTrue(context.isAtomic); w.close(); diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java index 4f348b648d1..2751dbc9e34 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java @@ -19,7 +19,7 @@ package org.apache.lucene.spatial.geohash; import java.io.IOException; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.FieldCache.DocTerms; import org.apache.lucene.search.Filter; @@ -62,7 +62,7 @@ public class GeoHashDistanceFilter extends DistanceFilter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final DocTerms geoHashValues = FieldCache.DEFAULT.getTerms(context.reader, geoHashField); final BytesRef br = new BytesRef(); diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java index 07a833f3e2e..6ee8fbeb771 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java @@ -20,7 +20,7 @@ import java.io.IOException; import java.util.List; import org.apache.lucene.index.DocsEnum; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Filter; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; @@ -45,7 +45,7 @@ public class CartesianShapeFilter extends Filter { } @Override - public DocIdSet getDocIdSet(final ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(final AtomicReaderContext context) throws IOException { final Bits delDocs = context.reader.getDeletedDocs(); final List area = shape.getArea(); final int sz = area.size(); diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java index 58b475bca60..94c3bd86ba0 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java @@ -19,7 +19,7 @@ package org.apache.lucene.spatial.tier; import java.io.IOException; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FilteredDocIdSet; import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.Filter; @@ -65,7 +65,7 @@ public class LatLongDistanceFilter extends DistanceFilter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final double[] latIndex = FieldCache.DEFAULT.getDoubles(context.reader, latField); final double[] lngIndex = FieldCache.DEFAULT.getDoubles(context.reader, lngField); diff --git a/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java b/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java index f355fab632d..f63e6acbcf3 100644 --- a/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java +++ b/lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java @@ -29,6 +29,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.QueryWrapperFilter; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.store.Directory; @@ -102,7 +103,7 @@ public class TestDistance extends LuceneTestCase { LatLongDistanceFilter f = new LatLongDistanceFilter(new QueryWrapperFilter(new MatchAllDocsQuery()), lat, lng, 1.0, latField, lngField); - AtomicReaderContext[] leaves = r.getTopReaderContext().leaves(); + AtomicReaderContext[] leaves = ReaderUtil.leaves(r.getTopReaderContext()); for (int i = 0; i < leaves.length; i++) { f.getDocIdSet(leaves[i]); } diff --git a/lucene/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/builders/NumericRangeFilterBuilder.java b/lucene/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/builders/NumericRangeFilterBuilder.java index b6bea806dee..ea5f5741c34 100644 --- a/lucene/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/builders/NumericRangeFilterBuilder.java +++ b/lucene/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/builders/NumericRangeFilterBuilder.java @@ -19,7 +19,7 @@ package org.apache.lucene.xmlparser.builders; import java.io.IOException; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.Filter; import org.apache.lucene.search.NumericRangeFilter; @@ -157,7 +157,7 @@ public class NumericRangeFilterBuilder implements FilterBuilder { private static final long serialVersionUID = 1L; @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return null; } diff --git a/lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/builders/TestNumericRangeFilterBuilder.java b/lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/builders/TestNumericRangeFilterBuilder.java index 4105c014f27..028cc752b85 100644 --- a/lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/builders/TestNumericRangeFilterBuilder.java +++ b/lucene/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/builders/TestNumericRangeFilterBuilder.java @@ -28,7 +28,9 @@ import javax.xml.parsers.ParserConfigurationException; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.search.Filter; import org.apache.lucene.search.NumericRangeFilter; import org.apache.lucene.store.Directory; @@ -64,10 +66,10 @@ public class TestNumericRangeFilterBuilder extends LuceneTestCase { writer.commit(); try { - IndexReader reader = IndexReader.open(ramDir, true); + IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(ramDir, true)); try { - assertNull(filter.getDocIdSet(reader.getTopReaderContext())); + assertNull(filter.getDocIdSet((AtomicReaderContext) reader.getTopReaderContext())); } finally { diff --git a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java index 8b4032a6602..d41abb8af0d 100644 --- a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java +++ b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.Scorer; @@ -365,9 +365,8 @@ class BufferedDeletes { // Delete by query if (deletes.queries.size() > 0) { IndexSearcher searcher = new IndexSearcher(reader); - - final ReaderContext readerContext = searcher.getTopReaderContext(); - assert readerContext.isAtomic; + assert searcher.getTopReaderContext().isAtomic; + final AtomicReaderContext readerContext = (AtomicReaderContext) searcher.getTopReaderContext(); try { for (Entry entry : deletes.queries.entrySet()) { Query query = entry.getKey(); diff --git a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java index 65523a6da7d..65159d17569 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java @@ -18,7 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.search.BooleanClause.Occur; @@ -212,7 +212,7 @@ public class BooleanQuery extends Query implements Iterable { } @Override - public Explanation explain(ReaderContext context, int doc) + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { final int minShouldMatch = BooleanQuery.this.getMinimumNumberShouldMatch(); @@ -288,7 +288,7 @@ public class BooleanQuery extends Query implements Iterable { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { List required = new ArrayList(); List prohibited = new ArrayList(); diff --git a/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java b/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java index 1939406749e..b1a2fa80767 100644 --- a/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java +++ b/lucene/src/java/org/apache/lucene/search/CachingSpanFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.Bits; import java.io.IOException; @@ -61,7 +61,7 @@ public class CachingSpanFilter extends SpanFilter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { SpanFilterResult result = getCachedResult(context.reader); return result != null ? result.getDocIdSet() : null; } diff --git a/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java index 1fc5c9f8b80..1f865670b56 100644 --- a/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/CachingWrapperFilter.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.WeakHashMap; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.OpenBitSetDISI; import org.apache.lucene.util.Bits; @@ -195,7 +195,7 @@ public class CachingWrapperFilter extends Filter { int hitCount, missCount; @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final IndexReader reader = context.reader; final Object coreKey = reader.getCoreCacheKey(); final Object delCoreKey = reader.hasDeletions() ? reader.getDeletedDocs() : coreKey; diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index 10090e98ee9..c8b8c9da180 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -18,7 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; @@ -133,7 +133,7 @@ public class ConstantScoreQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { final DocIdSetIterator disi; if (filter != null) { assert query == null; @@ -157,7 +157,7 @@ public class ConstantScoreQuery extends Query { } @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { final Scorer cs = scorer(context, true, false); final boolean exists = (cs != null && cs.advance(doc) == doc); diff --git a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index 83f7764776f..f7a797eec20 100644 --- a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -23,7 +23,7 @@ import java.util.Iterator; import java.util.Set; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; /** @@ -142,7 +142,7 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /* Create the scorer used to score our associated DisjunctionMaxQuery */ @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { Scorer[] scorers = new Scorer[weights.size()]; int idx = 0; @@ -159,7 +159,7 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /* Explain the score we computed for doc */ @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { if (disjuncts.size() == 1) return weights.get(0).explain(context,doc); ComplexExplanation result = new ComplexExplanation(); float max = 0.0f, sum = 0.0f; diff --git a/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java b/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java index e0a03169285..9293e509608 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java +++ b/lucene/src/java/org/apache/lucene/search/FieldCacheRangeFilter.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.MultiFields; import org.apache.lucene.util.NumericUtils; import org.apache.lucene.util.Bits; @@ -74,7 +74,7 @@ public abstract class FieldCacheRangeFilter extends Filter { /** This method is implemented for each data type */ @Override - public abstract DocIdSet getDocIdSet(ReaderContext context) throws IOException; + public abstract DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException; /** * Creates a string range filter using {@link FieldCache#getTermsIndex}. This works with all @@ -84,7 +84,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newStringRange(String field, String lowerVal, String upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, null, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final FieldCache.DocTermsIndex fcsi = FieldCache.DEFAULT.getTermsIndex(context.reader, field); final BytesRef spare = new BytesRef(); final int lowerPoint = fcsi.binarySearchLookup(lowerVal == null ? null : new BytesRef(lowerVal), spare); @@ -153,7 +153,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newByteRange(String field, FieldCache.ByteParser parser, Byte lowerVal, Byte upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final byte inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { final byte i = lowerVal.byteValue(); @@ -204,7 +204,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newShortRange(String field, FieldCache.ShortParser parser, Short lowerVal, Short upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final short inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { short i = lowerVal.shortValue(); @@ -255,7 +255,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newIntRange(String field, FieldCache.IntParser parser, Integer lowerVal, Integer upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final int inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { int i = lowerVal.intValue(); @@ -306,7 +306,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newLongRange(String field, FieldCache.LongParser parser, Long lowerVal, Long upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final long inclusiveLowerPoint, inclusiveUpperPoint; if (lowerVal != null) { long i = lowerVal.longValue(); @@ -357,7 +357,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newFloatRange(String field, FieldCache.FloatParser parser, Float lowerVal, Float upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { // we transform the floating point numbers to sortable integers // using NumericUtils to easier find the next bigger/lower value final float inclusiveLowerPoint, inclusiveUpperPoint; @@ -412,7 +412,7 @@ public abstract class FieldCacheRangeFilter extends Filter { public static FieldCacheRangeFilter newDoubleRange(String field, FieldCache.DoubleParser parser, Double lowerVal, Double upperVal, boolean includeLower, boolean includeUpper) { return new FieldCacheRangeFilter(field, parser, lowerVal, upperVal, includeLower, includeUpper) { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { // we transform the floating point numbers to sortable integers // using NumericUtils to easier find the next bigger/lower value final double inclusiveLowerPoint, inclusiveUpperPoint; diff --git a/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java b/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java index 684b139e4cf..7c9099b6d2c 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java +++ b/lucene/src/java/org/apache/lucene/search/FieldCacheTermsFilter.java @@ -21,7 +21,7 @@ import java.io.IOException; import org.apache.lucene.index.DocsEnum; // javadoc @link import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.BytesRef; @@ -116,7 +116,7 @@ public class FieldCacheTermsFilter extends Filter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return new FieldCacheTermsFilterDocIdSet(getFieldCache().getTermsIndex(context.reader, field)); } diff --git a/lucene/src/java/org/apache/lucene/search/Filter.java b/lucene/src/java/org/apache/lucene/search/Filter.java index 2dea148e94e..f4404c71860 100644 --- a/lucene/src/java/org/apache/lucene/search/Filter.java +++ b/lucene/src/java/org/apache/lucene/search/Filter.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.DocIdBitSet; /** @@ -38,7 +38,7 @@ public abstract class Filter implements java.io.Serializable { * must refer to document IDs for that segment, not for * the top-level reader. * - * @param context a {@link ReaderContext} instance opened on the index currently + * @param context a {@link AtomicReaderContext} instance opened on the index currently * searched on. Note, it is likely that the provided reader info does not * represent the whole underlying index i.e. if the index has more than * one segment the given reader only represents a single segment. @@ -52,6 +52,5 @@ public abstract class Filter implements java.io.Serializable { * * @see DocIdBitSet */ - // TODO make this context an AtomicContext - public abstract DocIdSet getDocIdSet(ReaderContext context) throws IOException; + public abstract DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException; } diff --git a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java index f0b6001665f..20ba46fa3b6 100644 --- a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java +++ b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java @@ -18,7 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; @@ -82,7 +82,7 @@ extends Query { } @Override - public Explanation explain (ReaderContext ir, int i) throws IOException { + public Explanation explain (AtomicReaderContext ir, int i) throws IOException { Explanation inner = weight.explain (ir, i); if (getBoost()!=1) { Explanation preBoost = inner; @@ -112,7 +112,7 @@ extends Query { // return a filtering scorer @Override - public Scorer scorer(ReaderContext indexReader, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext indexReader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { final Scorer scorer = weight.scorer(indexReader, true, false); if (scorer == null) { diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 2fdff34ad13..0dd8dfb85e3 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -145,7 +145,7 @@ public class IndexSearcher { * @lucene.experimental */ public IndexSearcher(ReaderContext context) { - this(context, null); + this(context, (ExecutorService) null); } // convenience ctor for other IR based ctors @@ -159,14 +159,8 @@ public class IndexSearcher { this.executor = executor; this.closeReader = closeReader; this.readerContext = context; - if (context.isAtomic) { - assert context.leaves() == null : "AtomicReaderContext must not have any leaves"; - this.leafContexts = new AtomicReaderContext[] { (AtomicReaderContext) context }; - } else { - assert context.leaves() != null : "non-atomic top-level context must have leaves"; - this.leafContexts = context.leaves(); - } - + leafContexts = ReaderUtil.leaves(context); + if (executor == null) { subSearchers = null; } else { @@ -175,12 +169,25 @@ public class IndexSearcher { if (leafContexts[i].reader == context.reader) { subSearchers[i] = this; } else { - subSearchers[i] = new IndexSearcher(leafContexts[i].reader.getTopReaderContext()); // we need to get a TL context for sub searchers! + subSearchers[i] = new IndexSearcher(context, leafContexts[i]); } } } } - + + /* Ctor for concurrent sub-searchers searching only on a specific leaf of the given top-reader context + * - instead of searching over all leaves this searcher only searches a single leaf searcher slice. Hence, + * for scorer and filter this looks like an ordinary search in the hierarchy such that there is no difference + * between single and multi-threaded */ + private IndexSearcher(ReaderContext topLevel, AtomicReaderContext leaf) { + readerContext = topLevel; + reader = topLevel.reader; + leafContexts = new AtomicReaderContext[] {leaf}; + executor = null; + subSearchers = null; + closeReader = false; + } + /** Return the {@link IndexReader} this searches. */ public IndexReader getIndexReader() { return reader; @@ -365,7 +372,7 @@ public class IndexSearcher { for (int i = 0; i < subSearchers.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq, leafContexts[i].docBase)); + new SearcherCallableNoSort(lock, subSearchers[i], weight, filter, nDocs, hq)); } int totalHits = 0; @@ -434,7 +441,7 @@ public class IndexSearcher { final ExecutionHelper runner = new ExecutionHelper(executor); for (int i = 0; i < subSearchers.length; i++) { // search each sub runner.submit( - new MultiSearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort, leafContexts[i].docBase)); + new SearcherCallableWithSort(lock, subSearchers[i], weight, filter, nDocs, hq, sort)); } int totalHits = 0; float maxScore = Float.NEGATIVE_INFINITY; @@ -493,7 +500,7 @@ public class IndexSearcher { } } - private void searchWithFilter(ReaderContext context, Weight weight, + private void searchWithFilter(AtomicReaderContext context, Weight weight, final Filter filter, final Collector collector) throws IOException { assert filter != null; @@ -621,7 +628,7 @@ public class IndexSearcher { /** * A thread subclass for searching a single searchable */ - private static final class MultiSearcherCallableNoSort implements Callable { + private static final class SearcherCallableNoSort implements Callable { private final Lock lock; private final IndexSearcher searchable; @@ -629,17 +636,15 @@ public class IndexSearcher { private final Filter filter; private final int nDocs; private final HitQueue hq; - private final int docBase; - public MultiSearcherCallableNoSort(Lock lock, IndexSearcher searchable, Weight weight, - Filter filter, int nDocs, HitQueue hq, int docBase) { + public SearcherCallableNoSort(Lock lock, IndexSearcher searchable, Weight weight, + Filter filter, int nDocs, HitQueue hq) { this.lock = lock; this.searchable = searchable; this.weight = weight; this.filter = filter; this.nDocs = nDocs; this.hq = hq; - this.docBase = docBase; } public TopDocs call() throws IOException { @@ -647,7 +652,6 @@ public class IndexSearcher { final ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq final ScoreDoc scoreDoc = scoreDocs[j]; - scoreDoc.doc += docBase; // convert doc //it would be so nice if we had a thread-safe insert lock.lock(); try { @@ -665,7 +669,7 @@ public class IndexSearcher { /** * A thread subclass for searching a single searchable */ - private static final class MultiSearcherCallableWithSort implements Callable { + private static final class SearcherCallableWithSort implements Callable { private final Lock lock; private final IndexSearcher searchable; @@ -673,37 +677,21 @@ public class IndexSearcher { private final Filter filter; private final int nDocs; private final FieldDocSortedHitQueue hq; - private final int docBase; private final Sort sort; - public MultiSearcherCallableWithSort(Lock lock, IndexSearcher searchable, Weight weight, - Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort, int docBase) { + public SearcherCallableWithSort(Lock lock, IndexSearcher searchable, Weight weight, + Filter filter, int nDocs, FieldDocSortedHitQueue hq, Sort sort) { this.lock = lock; this.searchable = searchable; this.weight = weight; this.filter = filter; this.nDocs = nDocs; this.hq = hq; - this.docBase = docBase; this.sort = sort; } public TopFieldDocs call() throws IOException { final TopFieldDocs docs = searchable.search (weight, filter, nDocs, sort); - // If one of the Sort fields is FIELD_DOC, need to fix its values, so that - // it will break ties by doc Id properly. Otherwise, it will compare to - // 'relative' doc Ids, that belong to two different searchables. - for (int j = 0; j < docs.fields.length; j++) { - if (docs.fields[j].getType() == SortField.DOC) { - // iterate over the score docs and change their fields value - for (int j2 = 0; j2 < docs.scoreDocs.length; j2++) { - FieldDoc fd = (FieldDoc) docs.scoreDocs[j2]; - fd.fields[j] = Integer.valueOf(((Integer) fd.fields[j]).intValue() + docBase); - } - break; - } - } - lock.lock(); try { hq.setFields(docs.fields); @@ -714,7 +702,6 @@ public class IndexSearcher { final ScoreDoc[] scoreDocs = docs.scoreDocs; for (int j = 0; j < scoreDocs.length; j++) { // merge scoreDocs into hq final FieldDoc fieldDoc = (FieldDoc) scoreDocs[j]; - fieldDoc.doc += docBase; // convert doc //it would be so nice if we had a thread-safe insert lock.lock(); try { diff --git a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java index 38625194474..f3bad0cdc17 100644 --- a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java @@ -18,7 +18,7 @@ package org.apache.lucene.search; */ import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.Bits; @@ -127,13 +127,13 @@ public class MatchAllDocsQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new MatchAllScorer(context.reader, similarity, this, normsField != null ? context.reader.norms(normsField) : null); } @Override - public Explanation explain(ReaderContext context, int doc) { + public Explanation explain(AtomicReaderContext context, int doc) { // explain query weight Explanation queryExpl = new ComplexExplanation (true, getValue(), "MatchAllDocsQuery, product of:"); diff --git a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java index 42b2086ea3c..4aa6cfc914d 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.*; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -168,7 +168,7 @@ public class MultiPhraseQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { if (termArrays.size() == 0) // optimize zero-term case return null; final IndexReader reader = context.reader; @@ -233,7 +233,7 @@ public class MultiPhraseQuery extends Query { } @Override - public Explanation explain(ReaderContext context, int doc) + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); result.setDescription("weight("+getQuery()+" in "+doc+"), product of:"); diff --git a/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java index 6d591c8a984..8a6df063b83 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/MultiTermQueryWrapperFilter.java @@ -21,7 +21,7 @@ import java.io.IOException; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.DocsEnum; @@ -105,7 +105,7 @@ public class MultiTermQueryWrapperFilter extends Filte * results. */ @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final IndexReader reader = context.reader; final Fields fields = reader.fields(); if (fields == null) { diff --git a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java index 7142461ef25..c465f3cb023 100644 --- a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.Set; import java.util.ArrayList; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.IndexReader; @@ -175,7 +175,7 @@ public class PhraseQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { if (terms.size() == 0) // optimize zero-term case return null; final IndexReader reader = context.reader; @@ -221,7 +221,7 @@ public class PhraseQuery extends Query { } @Override - public Explanation explain(ReaderContext context, int doc) + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { Explanation result = new Explanation(); diff --git a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java index a2c2c29eaa1..31077e46683 100644 --- a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java @@ -18,7 +18,8 @@ package org.apache.lucene.search; */ import java.io.IOException; -import org.apache.lucene.index.IndexReader.ReaderContext; + +import org.apache.lucene.index.IndexReader.AtomicReaderContext; /** * Constrains search results to only match those which also match a provided @@ -46,9 +47,10 @@ public class QueryWrapperFilter extends Filter { } @Override - public DocIdSet getDocIdSet(final ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(final AtomicReaderContext context) throws IOException { // get a private context that is used to rewrite, createWeight and score eventually - final ReaderContext privateContext = context.reader.getTopReaderContext(); + assert context.reader.getTopReaderContext().isAtomic; + final AtomicReaderContext privateContext = (AtomicReaderContext) context.reader.getTopReaderContext(); final Weight weight = query.weight(new IndexSearcher(privateContext)); return new DocIdSet() { @Override diff --git a/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java b/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java index 68649be097a..6c12dac39b7 100644 --- a/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java +++ b/lucene/src/java/org/apache/lucene/search/SpanQueryFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.spans.SpanQuery; import org.apache.lucene.search.spans.Spans; import org.apache.lucene.util.OpenBitSet; @@ -53,7 +53,7 @@ public class SpanQueryFilter extends SpanFilter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { SpanFilterResult result = bitSpans(context.reader); return result.getDocIdSet(); } diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index bf8346cfb50..5ed96f8ddca 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -42,9 +42,11 @@ public class TermQuery extends Query { private float queryNorm; private float queryWeight; private IDFExplanation idfExp; + private transient ReaderContext weightContext; // only set if -ea for assert in scorer() public TermWeight(IndexSearcher searcher) throws IOException { + assert setWeightContext(searcher); this.similarity = getSimilarity(searcher); if (docFreq != -1) { idfExp = similarity.idfExplain(term, searcher, docFreq); @@ -77,7 +79,8 @@ public class TermQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + assert assertTopReaderContext(context); final IndexReader reader = context.reader; DocsEnum docs = reader.termDocsEnum(reader.getDeletedDocs(), term.field(), @@ -89,9 +92,21 @@ public class TermQuery extends Query { return new TermScorer(this, docs, similarity, reader.norms(term.field())); } + + private boolean assertTopReaderContext(ReaderContext context) { + while (context.parent != null) { + context = context.parent; + } + return weightContext == context; + } + + private boolean setWeightContext(IndexSearcher searcher) { + weightContext = searcher.getTopReaderContext(); + return true; + } @Override - public Explanation explain(ReaderContext context, int doc) + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { final IndexReader reader = context.reader; diff --git a/lucene/src/java/org/apache/lucene/search/Weight.java b/lucene/src/java/org/apache/lucene/search/Weight.java index 016904eb833..e649530e530 100644 --- a/lucene/src/java/org/apache/lucene/search/Weight.java +++ b/lucene/src/java/org/apache/lucene/search/Weight.java @@ -34,12 +34,9 @@ import org.apache.lucene.index.IndexReader.ReaderContext; * {@link IndexReader} dependent state should reside in the {@link Scorer}. *

    * Since {@link Weight} creates {@link Scorer} instances for a given - * {@link ReaderContext} ({@link #scorer(ReaderContext, boolean, boolean)}) + * {@link AtomicReaderContext} ({@link #scorer(AtomicReaderContext, boolean, boolean)}) * callers must maintain the relationship between the searcher's top-level - * {@link ReaderContext} and the context used to create a {@link Scorer}. A - * {@link ReaderContext} used to create a {@link Scorer} should be a leaf - * context ({@link AtomicReaderContext}) of the searcher's top-level context, - * otherwise the scorer's state will be undefined. + * {@link ReaderContext} and the context used to create a {@link Scorer}. *

    * A Weight is used in the following way: *

      @@ -52,10 +49,9 @@ import org.apache.lucene.index.IndexReader.ReaderContext; *
    1. The query normalization factor is passed to {@link #normalize(float)}. At * this point the weighting is complete. *
    2. A Scorer is constructed by - * {@link #scorer(ReaderContext,boolean,boolean)}. + * {@link #scorer(AtomicReaderContext,boolean,boolean)}. *
    * - * * @since 2.9 */ public abstract class Weight implements Serializable { @@ -68,7 +64,7 @@ public abstract class Weight implements Serializable { * @return an Explanation for the score * @throws IOException if an {@link IOException} occurs */ - public abstract Explanation explain(ReaderContext context, int doc) throws IOException; + public abstract Explanation explain(AtomicReaderContext context, int doc) throws IOException; /** The query that this concerns. */ public abstract Query getQuery(); @@ -90,12 +86,9 @@ public abstract class Weight implements Serializable { * in-order.
    * NOTE: null can be returned if no documents will be scored by this * query. - * NOTE: Calling this method with a {@link ReaderContext} that is not a - * leaf context ({@link AtomicReaderContext}) of the searcher's top-level context - * used to create this {@link Weight} instance can cause undefined behavior. * * @param context - * the {@link ReaderContext} for which to return the {@link Scorer}. + * the {@link AtomicReaderContext} for which to return the {@link Scorer}. * @param scoreDocsInOrder * specifies whether in-order scoring of documents is required. Note * that if set to false (i.e., out-of-order scoring is required), @@ -111,8 +104,7 @@ public abstract class Weight implements Serializable { * @return a {@link Scorer} which scores documents in/out-of order. * @throws IOException */ - // TODO make this context an AtomicContext if possible - public abstract Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, + public abstract Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException; /** The sum of squared weights of contained query clauses. */ @@ -122,7 +114,7 @@ public abstract class Weight implements Serializable { * Returns true iff this implementation scores docs only out of order. This * method is used in conjunction with {@link Collector}'s * {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and - * {@link #scorer(ReaderContext, boolean, boolean)} to + * {@link #scorer(AtomicReaderContext, boolean, boolean)} to * create a matching {@link Scorer} instance for a given {@link Collector}, or * vice versa. *

    diff --git a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java index ecea73df689..fd3bc3e81fb 100755 --- a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java @@ -22,7 +22,7 @@ import java.util.Set; import java.util.Arrays; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.ComplexExplanation; import org.apache.lucene.search.Explanation; @@ -240,7 +240,7 @@ public class CustomScoreQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { // Pass true for "scoresDocsInOrder", because we // require in-order scoring, even if caller does not, // since we call advance on the valSrcScorers. Pass @@ -258,12 +258,12 @@ public class CustomScoreQuery extends Query { } @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { Explanation explain = doExplain(context, doc); return explain == null ? new Explanation(0.0f, "no matching docs") : explain; } - private Explanation doExplain(ReaderContext info, int doc) throws IOException { + private Explanation doExplain(AtomicReaderContext info, int doc) throws IOException { Explanation subQueryExpl = subQueryWeight.explain(info, doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; diff --git a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java index 25af66e85d9..1a3f7706e67 100644 --- a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java @@ -19,7 +19,7 @@ package org.apache.lucene.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.*; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.Bits; @@ -99,13 +99,13 @@ public class ValueSourceQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new ValueSourceScorer(similarity, context.reader, this); } /*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */ @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { DocValues vals = valSrc.getValues(context.reader); float sc = queryWeight * vals.floatVal(doc); diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java index 1bb3b7a5f95..2504e7ed28b 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java @@ -17,7 +17,7 @@ package org.apache.lucene.search.payloads; * limitations under the License. */ -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Explanation; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.IndexSearcher; @@ -143,7 +143,7 @@ public class PayloadNearQuery extends SpanNearQuery { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new PayloadNearSpanScorer(query.getSpans(context.reader), this, similarity, context.reader.norms(query.getField())); diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java index 4aa29583473..048f3affa30 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java @@ -17,7 +17,7 @@ package org.apache.lucene.search.payloads; * limitations under the License. */ -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.search.IndexSearcher; @@ -74,7 +74,7 @@ public class PayloadTermQuery extends SpanTermQuery { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new PayloadTermSpanScorer((TermSpans) query.getSpans(context.reader), this, similarity, context.reader.norms(query.getField())); diff --git a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java index 6142ad42453..4b360cfb8ea 100644 --- a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java +++ b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java @@ -17,7 +17,7 @@ package org.apache.lucene.search.spans; * limitations under the License. */ -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.search.Explanation.IDFExplanation; @@ -72,13 +72,13 @@ public class SpanWeight extends Weight { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new SpanScorer(query.getSpans(context.reader), this, similarity, context.reader .norms(query.getField())); } @Override - public Explanation explain(ReaderContext context, int doc) + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { ComplexExplanation result = new ComplexExplanation(); diff --git a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java index 701cfee2368..e1533433c1b 100644 --- a/lucene/src/java/org/apache/lucene/util/ReaderUtil.java +++ b/lucene/src/java/org/apache/lucene/util/ReaderUtil.java @@ -213,6 +213,21 @@ public final class ReaderUtil { } + /** + * Returns the context's leaves or the context itself as the only element of + * the returned array. If the context's #leaves() method returns + * null the given context must be an instance of + * {@link AtomicReaderContext} + */ + public static AtomicReaderContext[] leaves(ReaderContext context) { + assert context != null && context.isTopLevel : "context must be non-null & top-level"; + final AtomicReaderContext[] leaves = context.leaves(); + if (leaves == null) { + assert context.isAtomic : "top-level context without leaves must be atomic"; + return new AtomicReaderContext[] { (AtomicReaderContext) context }; + } + return leaves; + } /** * Returns index of the searcher/reader for document n in the diff --git a/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java b/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java index 5acd441b18d..41872acd8bd 100644 --- a/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java +++ b/lucene/src/test/org/apache/lucene/search/CachingWrapperFilterHelper.java @@ -21,7 +21,7 @@ import java.io.IOException; import junit.framework.Assert; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; /** * A unit test helper class to test when the filter is getting cached and when it is not. @@ -42,7 +42,7 @@ public class CachingWrapperFilterHelper extends CachingWrapperFilter { } @Override - public synchronized DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public synchronized DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { final int saveMissCount = missCount; DocIdSet docIdSet = super.getDocIdSet(context); diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index f0488f5b7d4..2e43904b584 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -20,7 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.util.PriorityQueue; @@ -154,7 +154,7 @@ final class JustCompileSearch { // still added here in case someone will add abstract methods in the future. @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return null; } } @@ -283,7 +283,7 @@ final class JustCompileSearch { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return null; } } @@ -335,7 +335,7 @@ final class JustCompileSearch { static final class JustCompileWeight extends Weight { @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } @@ -360,7 +360,7 @@ final class JustCompileSearch { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/MockFilter.java b/lucene/src/test/org/apache/lucene/search/MockFilter.java index 1ac9207e9ef..1152db0f3d8 100644 --- a/lucene/src/test/org/apache/lucene/search/MockFilter.java +++ b/lucene/src/test/org/apache/lucene/search/MockFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.DocIdBitSet; import java.util.BitSet; @@ -25,7 +25,7 @@ public class MockFilter extends Filter { private boolean wasCalled; @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { wasCalled = true; return new DocIdBitSet(new BitSet()); } diff --git a/lucene/src/test/org/apache/lucene/search/QueryUtils.java b/lucene/src/test/org/apache/lucene/search/QueryUtils.java index fd52b748a74..27dda23ce40 100644 --- a/lucene/src/test/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test/org/apache/lucene/search/QueryUtils.java @@ -13,13 +13,13 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; import org.apache.lucene.store.Directory; import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.ReaderUtil; import static org.apache.lucene.util.LuceneTestCase.TEST_VERSION_CURRENT; @@ -213,21 +213,14 @@ public class QueryUtils { } } - private static AtomicReaderContext[] getLeaves(IndexSearcher searcher) { - ReaderContext topLevelReaderContext = searcher.getTopReaderContext(); - if (topLevelReaderContext.isAtomic) { - return new AtomicReaderContext[] {(AtomicReaderContext) topLevelReaderContext}; - } else { - return topLevelReaderContext.leaves(); - } - } + /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc * and ensure a hitcollector receives same docs and scores */ public static void checkSkipTo(final Query q, final IndexSearcher s) throws IOException { //System.out.println("Checking "+q); - final AtomicReaderContext[] context = getLeaves(s); + final AtomicReaderContext[] context = ReaderUtil.leaves(s.getTopReaderContext()); if (q.weight(s).scoresDocsOutOfOrder()) return; // in this case order of skipTo() might differ from that of next(). final int skip_op = 0; @@ -317,7 +310,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -342,7 +335,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer(previousReader.getTopReaderContext() , true, false); + Scorer scorer = w.scorer((AtomicReaderContext)previousReader.getTopReaderContext() , true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -357,7 +350,7 @@ public class QueryUtils { final float maxDiff = 1e-3f; final int lastDoc[] = {-1}; final IndexReader lastReader[] = {null}; - final ReaderContext[] context = getLeaves(s); + final AtomicReaderContext[] context = ReaderUtil.leaves(s.getTopReaderContext()); s.search(q,new Collector() { private Scorer scorer; private int leafPtr; @@ -399,7 +392,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -422,7 +415,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer(indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); diff --git a/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java b/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java index 2625cda5b67..a33a6c178a2 100644 --- a/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java +++ b/lucene/src/test/org/apache/lucene/search/SingleDocTestFilter.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.DocIdBitSet; import java.util.BitSet; @@ -31,7 +31,7 @@ public class SingleDocTestFilter extends Filter { } @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { BitSet bits = new BitSet(context.reader.maxDoc()); bits.set(doc); return new DocIdBitSet(bits); diff --git a/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java b/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java index a38fe553a26..36c6dfeeef8 100644 --- a/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java +++ b/lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java @@ -24,7 +24,6 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.SerialMergeScheduler; import org.apache.lucene.index.SlowMultiReaderWrapper; @@ -41,8 +40,8 @@ public class TestCachingWrapperFilter extends LuceneTestCase { RandomIndexWriter writer = new RandomIndexWriter(random, dir); writer.close(); - IndexReader reader = IndexReader.open(dir, true); - ReaderContext context = reader.getTopReaderContext(); + IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(dir, true)); + AtomicReaderContext context = (AtomicReaderContext) reader.getTopReaderContext(); MockFilter filter = new MockFilter(); CachingWrapperFilter cacher = new CachingWrapperFilter(filter); @@ -67,12 +66,12 @@ public class TestCachingWrapperFilter extends LuceneTestCase { RandomIndexWriter writer = new RandomIndexWriter(random, dir); writer.close(); - IndexReader reader = IndexReader.open(dir, true); - ReaderContext context = reader.getTopReaderContext(); + IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(dir, true)); + AtomicReaderContext context = (AtomicReaderContext) reader.getTopReaderContext(); final Filter filter = new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { return null; } }; @@ -90,12 +89,12 @@ public class TestCachingWrapperFilter extends LuceneTestCase { RandomIndexWriter writer = new RandomIndexWriter(random, dir); writer.close(); - IndexReader reader = IndexReader.open(dir, true); - ReaderContext context = reader.getTopReaderContext(); + IndexReader reader = new SlowMultiReaderWrapper(IndexReader.open(dir, true)); + AtomicReaderContext context = (AtomicReaderContext) reader.getTopReaderContext(); final Filter filter = new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { return new DocIdSet() { @Override public DocIdSetIterator iterator() { @@ -114,7 +113,8 @@ public class TestCachingWrapperFilter extends LuceneTestCase { } private static void assertDocIdSetCacheable(IndexReader reader, Filter filter, boolean shouldCacheable) throws IOException { - ReaderContext context = reader.getTopReaderContext(); + assertTrue(reader.getTopReaderContext().isAtomic); + AtomicReaderContext context = (AtomicReaderContext) reader.getTopReaderContext(); final CachingWrapperFilter cacher = new CachingWrapperFilter(filter); final DocIdSet originalSet = filter.getDocIdSet(context); final DocIdSet cachedSet = cacher.getDocIdSet(context); @@ -145,7 +145,7 @@ public class TestCachingWrapperFilter extends LuceneTestCase { // a openbitset filter is always cacheable assertDocIdSetCacheable(reader, new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { return new OpenBitSet(); } }, true); diff --git a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java index aa7b9faaff5..595c18c9762 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java @@ -22,11 +22,11 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.store.Directory; import java.text.DecimalFormat; @@ -168,7 +168,7 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { QueryUtils.check(random, dq, s); assertTrue(s.getTopReaderContext().isAtomic); final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer(s.getTopReaderContext(), true, false); + final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), true, false); final boolean skipOk = ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS; if (skipOk) { fail("firsttime skipTo found a match? ... " @@ -183,7 +183,7 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { assertTrue(s.getTopReaderContext().isAtomic); QueryUtils.check(random, dq, s); final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer(s.getTopReaderContext(), true, false); + final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), true, false); assertTrue("firsttime skipTo found no match", ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS); assertEquals("found wrong docid", "d4", r.document(ds.docID()).get("id")); diff --git a/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java b/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java index 5ff89d5c888..6ca1192b25c 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java +++ b/lucene/src/test/org/apache/lucene/search/TestDocIdSet.java @@ -28,7 +28,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field.Index; import org.apache.lucene.document.Field.Store; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -115,7 +115,7 @@ public class TestDocIdSet extends LuceneTestCase { // Now search w/ a Filter which returns a null DocIdSet Filter f = new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return null; } }; diff --git a/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java b/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java index dd1655ad2a0..bca34a1f594 100644 --- a/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestFilteredQuery.java @@ -20,7 +20,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.search.BooleanClause.Occur; @@ -88,7 +88,7 @@ public class TestFilteredQuery extends LuceneTestCase { private static Filter newStaticFilterB() { return new Filter() { @Override - public DocIdSet getDocIdSet (ReaderContext context) { + public DocIdSet getDocIdSet (AtomicReaderContext context) { BitSet bitset = new BitSet(5); bitset.set (1); bitset.set (3); @@ -159,7 +159,7 @@ public class TestFilteredQuery extends LuceneTestCase { private static Filter newStaticFilterA() { return new Filter() { @Override - public DocIdSet getDocIdSet (ReaderContext context) { + public DocIdSet getDocIdSet (AtomicReaderContext context) { BitSet bitset = new BitSet(5); bitset.set(0, 5); return new DocIdBitSet(bitset); diff --git a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java index a4b02fa9592..365f2317b36 100644 --- a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java +++ b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java @@ -25,7 +25,6 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; @@ -97,7 +96,7 @@ public class TestFilteredSearch extends LuceneTestCase { } @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { assert context.isAtomic; final OpenBitSet set = new OpenBitSet(); int docBase = ((AtomicReaderContext)context).docBase; diff --git a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java index f4b330e8fe9..18b1ded0a24 100644 --- a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java +++ b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery32.java @@ -22,6 +22,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericField; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MultiFields; import org.apache.lucene.index.RandomIndexWriter; @@ -176,14 +177,15 @@ public class TestNumericRangeQuery32 extends LuceneTestCase { @Test public void testInverseRange() throws Exception { + AtomicReaderContext context = (AtomicReaderContext) new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext(); NumericRangeFilter f = NumericRangeFilter.newIntRange("field8", 8, 1000, -1000, true, true); - assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(context)); f = NumericRangeFilter.newIntRange("field8", 8, Integer.MAX_VALUE, null, false, false); assertSame("A exclusive range starting with Integer.MAX_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(context)); f = NumericRangeFilter.newIntRange("field8", 8, null, Integer.MIN_VALUE, false, false); assertSame("A exclusive range ending with Integer.MIN_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(context)); } @Test diff --git a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java index 2e5c3e8b256..27aebfce451 100644 --- a/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java +++ b/lucene/src/test/org/apache/lucene/search/TestNumericRangeQuery64.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.SlowMultiReaderWrapper; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.store.Directory; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.LuceneTestCase; @@ -181,15 +182,16 @@ public class TestNumericRangeQuery64 extends LuceneTestCase { @Test public void testInverseRange() throws Exception { + AtomicReaderContext context = (AtomicReaderContext) new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext(); NumericRangeFilter f = NumericRangeFilter.newLongRange("field8", 8, 1000L, -1000L, true, true); assertSame("A inverse range should return the EMPTY_DOCIDSET instance", DocIdSet.EMPTY_DOCIDSET, - f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + f.getDocIdSet(context)); f = NumericRangeFilter.newLongRange("field8", 8, Long.MAX_VALUE, null, false, false); assertSame("A exclusive range starting with Long.MAX_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(context)); f = NumericRangeFilter.newLongRange("field8", 8, null, Long.MIN_VALUE, false, false); assertSame("A exclusive range ending with Long.MIN_VALUE should return the EMPTY_DOCIDSET instance", - DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(new SlowMultiReaderWrapper(searcher.getIndexReader()).getTopReaderContext())); + DocIdSet.EMPTY_DOCIDSET, f.getDocIdSet(context)); } @Test diff --git a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java index 364b452ce23..55c4042eca0 100755 --- a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java +++ b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java @@ -7,7 +7,7 @@ import java.util.BitSet; import java.io.IOException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.IndexWriterConfig.OpenMode; @@ -142,7 +142,7 @@ public class TestScorerPerf extends LuceneTestCase { final BitSet rnd = sets[random.nextInt(sets.length)]; Query q = new ConstantScoreQuery(new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) { + public DocIdSet getDocIdSet(AtomicReaderContext context) { return new DocIdBitSet(rnd); } }); diff --git a/lucene/src/test/org/apache/lucene/search/TestSort.java b/lucene/src/test/org/apache/lucene/search/TestSort.java index b0889f21332..32b58632374 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSort.java +++ b/lucene/src/test/org/apache/lucene/search/TestSort.java @@ -34,7 +34,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; @@ -688,7 +688,7 @@ public class TestSort extends LuceneTestCase implements Serializable { // a filter that only allows through the first hit Filter filt = new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { BitSet bs = new BitSet(context.reader.maxDoc()); bs.set(0, context.reader.maxDoc()); bs.set(docs1.scoreDocs[0].doc); diff --git a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java index 7265ada5b1c..139df5077eb 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java @@ -28,7 +28,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.SlowMultiReaderWrapper; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.store.Directory; public class TestTermScorer extends LuceneTestCase { @@ -71,8 +71,8 @@ public class TestTermScorer extends LuceneTestCase { TermQuery termQuery = new TermQuery(allTerm); Weight weight = termQuery.weight(indexSearcher); - - Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); + assertTrue(indexSearcher.getTopReaderContext().isAtomic); + Scorer ts = weight.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, true); // we have 2 documents with the term all in them, one document for all the // other values final List docs = new ArrayList(); @@ -132,8 +132,8 @@ public class TestTermScorer extends LuceneTestCase { TermQuery termQuery = new TermQuery(allTerm); Weight weight = termQuery.weight(indexSearcher); - - Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); + assertTrue(indexSearcher.getTopReaderContext().isAtomic); + Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), true, true); assertTrue("next did not return a doc", ts.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); assertTrue("score is not correct", ts.score() == 1.6931472f); @@ -150,8 +150,9 @@ public class TestTermScorer extends LuceneTestCase { TermQuery termQuery = new TermQuery(allTerm); Weight weight = termQuery.weight(indexSearcher); - - Scorer ts = weight.scorer(indexSearcher.getTopReaderContext(), true, true); + assertTrue(indexSearcher.getTopReaderContext().isAtomic); + + Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), true, true); assertTrue("Didn't skip", ts.advance(3) != DocIdSetIterator.NO_MORE_DOCS); // The next doc should be doc 5 assertTrue("doc should be number 5", ts.docID() == 5); diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java index fc3fb442bab..e5497e470f7 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java @@ -21,6 +21,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; @@ -168,7 +169,8 @@ public class TestNearSpansOrdered extends LuceneTestCase { public void testSpanNearScorerSkipTo1() throws Exception { SpanNearQuery q = makeQuery(); Weight w = q.weight(searcher); - Scorer s = w.scorer(searcher.getTopReaderContext(), true, false); + assertTrue(searcher.getTopReaderContext().isAtomic); + Scorer s = w.scorer((AtomicReaderContext) searcher.getTopReaderContext(), true, false); assertEquals(1, s.advance(1)); } /** @@ -177,7 +179,8 @@ public class TestNearSpansOrdered extends LuceneTestCase { */ public void testSpanNearScorerExplain() throws Exception { SpanNearQuery q = makeQuery(); - Explanation e = q.weight(searcher).explain(searcher.getTopReaderContext(), 1); + assertTrue(searcher.getTopReaderContext().isAtomic); + Explanation e = q.weight(searcher).explain((AtomicReaderContext) searcher.getTopReaderContext(), 1); assertTrue("Scorer explanation value for doc#1 isn't positive: " + e.toString(), 0.0f < e.getValue()); diff --git a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java index 8743072d5da..30f99a6f0a6 100755 --- a/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java +++ b/solr/src/java/org/apache/solr/request/PerSegmentSingleValuedFaceting.java @@ -1,8 +1,6 @@ package org.apache.solr.request; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; @@ -10,6 +8,7 @@ import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.Filter; import org.apache.lucene.util.PriorityQueue; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.packed.Direct16; import org.apache.lucene.util.packed.Direct32; import org.apache.lucene.util.packed.Direct8; @@ -19,7 +18,6 @@ import org.apache.solr.common.params.FacetParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.schema.FieldType; import org.apache.solr.search.DocSet; -import org.apache.solr.search.SolrIndexReader; import org.apache.solr.search.SolrIndexSearcher; import org.apache.solr.util.BoundedTreeSet; import org.apache.solr.util.ByteUtils; @@ -70,7 +68,7 @@ class PerSegmentSingleValuedFaceting { // reuse the translation logic to go from top level set to per-segment set baseSet = docs.getTopFilter(); - final AtomicReaderContext[] leaves = searcher.getTopReaderContext().leaves(); + final AtomicReaderContext[] leaves = ReaderUtil.leaves(searcher.getTopReaderContext()); // The list of pending tasks that aren't immediately submitted // TODO: Is there a completion service, or a delegating executor that can // limit the number of concurrent tasks submitted to a bigger executor? @@ -209,9 +207,9 @@ class PerSegmentSingleValuedFaceting { } class SegFacet { - ReaderContext info; - SegFacet(ReaderContext info) { - this.info = info; + AtomicReaderContext context; + SegFacet(AtomicReaderContext context) { + this.context = context; } FieldCache.DocTermsIndex si; @@ -225,7 +223,7 @@ class PerSegmentSingleValuedFaceting { BytesRef tempBR = new BytesRef(); void countTerms() throws IOException { - si = FieldCache.DEFAULT.getTermsIndex(info.reader, fieldName); + si = FieldCache.DEFAULT.getTermsIndex(context.reader, fieldName); // SolrCore.log.info("reader= " + reader + " FC=" + System.identityHashCode(si)); if (prefix!=null) { @@ -247,7 +245,7 @@ class PerSegmentSingleValuedFaceting { // count collection array only needs to be as big as the number of terms we are // going to collect counts for. final int[] counts = this.counts = new int[nTerms]; - DocIdSet idSet = baseSet.getDocIdSet(info); + DocIdSet idSet = baseSet.getDocIdSet(context); DocIdSetIterator iter = idSet.iterator(); diff --git a/solr/src/java/org/apache/solr/schema/LatLonType.java b/solr/src/java/org/apache/solr/schema/LatLonType.java index 75694f7eaa9..2e35dcf72db 100644 --- a/solr/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/src/java/org/apache/solr/schema/LatLonType.java @@ -19,7 +19,7 @@ package org.apache.solr.schema; import org.apache.lucene.document.Field; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.MultiFields; import org.apache.lucene.search.*; import org.apache.lucene.spatial.DistanceUtils; @@ -371,12 +371,12 @@ class SpatialDistanceQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new SpatialScorer(getSimilarity(searcher), context.reader, this); } @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { return ((SpatialScorer)scorer(context, true, true)).explain(doc); } } diff --git a/solr/src/java/org/apache/solr/search/DocSet.java b/solr/src/java/org/apache/solr/search/DocSet.java index 59b3286c98a..e4482ac0c73 100644 --- a/solr/src/java/org/apache/solr/search/DocSet.java +++ b/solr/src/java/org/apache/solr/search/DocSet.java @@ -23,7 +23,7 @@ import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.Filter; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; @@ -247,7 +247,7 @@ abstract class DocSetBase implements DocSet { return new Filter() { @Override - public DocIdSet getDocIdSet(ReaderContext ctx) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext ctx) throws IOException { IndexReader.AtomicReaderContext context = (IndexReader.AtomicReaderContext)ctx; // TODO: remove after lucene migration IndexReader reader = ctx.reader; diff --git a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java index 0c5179e3d8e..fd63bb92fb9 100755 --- a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java +++ b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java @@ -2,7 +2,7 @@ package org.apache.solr.search; import org.apache.lucene.search.*; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.search.function.ValueSource; import org.apache.solr.common.SolrException; @@ -90,12 +90,12 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new ConstantScorer(similarity, context, this); } @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { ConstantScorer cs = new ConstantScorer(similarity, context, this); boolean exists = cs.docIdSetIterator.advance(doc) == doc; @@ -124,10 +124,10 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery { final float theScore; int doc = -1; - public ConstantScorer(Similarity similarity, ReaderContext info, ConstantWeight w) throws IOException { + public ConstantScorer(Similarity similarity, AtomicReaderContext context, ConstantWeight w) throws IOException { super(similarity); theScore = w.getValue(); - DocIdSet docIdSet = filter instanceof SolrFilter ? ((SolrFilter)filter).getDocIdSet(w.context, info) : filter.getDocIdSet(info); + DocIdSet docIdSet = filter instanceof SolrFilter ? ((SolrFilter)filter).getDocIdSet(w.context, context) : filter.getDocIdSet(context); if (docIdSet == null) { docIdSetIterator = DocIdSet.EMPTY_DOCIDSET.iterator(); } else { diff --git a/solr/src/java/org/apache/solr/search/SolrFilter.java b/solr/src/java/org/apache/solr/search/SolrFilter.java index 91009320b3b..1eddff4ff43 100644 --- a/solr/src/java/org/apache/solr/search/SolrFilter.java +++ b/solr/src/java/org/apache/solr/search/SolrFilter.java @@ -21,6 +21,7 @@ import org.apache.lucene.search.Filter; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import java.util.Map; @@ -41,7 +42,7 @@ public abstract class SolrFilter extends Filter { public abstract DocIdSet getDocIdSet(Map context, ReaderContext readerContext) throws IOException; @Override - public DocIdSet getDocIdSet(ReaderContext context) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext context) throws IOException { return getDocIdSet(null, context); } } diff --git a/solr/src/java/org/apache/solr/search/SortedIntDocSet.java b/solr/src/java/org/apache/solr/search/SortedIntDocSet.java index 052bac50ef6..07a62d3e041 100755 --- a/solr/src/java/org/apache/solr/search/SortedIntDocSet.java +++ b/solr/src/java/org/apache/solr/search/SortedIntDocSet.java @@ -22,7 +22,6 @@ import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; @@ -553,7 +552,7 @@ public class SortedIntDocSet extends DocSetBase { int lastEndIdx = 0; @Override - public DocIdSet getDocIdSet(ReaderContext contextX) throws IOException { + public DocIdSet getDocIdSet(AtomicReaderContext contextX) throws IOException { AtomicReaderContext context = (AtomicReaderContext)contextX; // TODO: remove after lucene migration IndexReader reader = context.reader; diff --git a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java index 963a776d3a0..645f3805cb8 100755 --- a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -19,9 +19,8 @@ package org.apache.solr.search.function; import org.apache.lucene.search.*; import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.ToStringUtils; -import org.apache.solr.search.SolrIndexReader; import java.io.IOException; import java.util.Set; @@ -92,7 +91,7 @@ public class BoostedQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { Scorer subQueryScorer = qWeight.scorer(context, true, false); if(subQueryScorer == null) { return null; @@ -101,7 +100,7 @@ public class BoostedQuery extends Query { } @Override - public Explanation explain(ReaderContext readerContext, int doc) throws IOException { + public Explanation explain(AtomicReaderContext readerContext, int doc) throws IOException { Explanation subQueryExpl = qWeight.explain(readerContext,doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; diff --git a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java index 1a6ad49bb6e..dc0f644995e 100644 --- a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java +++ b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.*; import org.apache.lucene.index.MultiFields; @@ -94,12 +95,12 @@ public class FunctionQuery extends Query { } @Override - public Scorer scorer(ReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { return new AllScorer(getSimilarity(searcher), context, this); } @Override - public Explanation explain(ReaderContext context, int doc) throws IOException { + public Explanation explain(AtomicReaderContext context, int doc) throws IOException { return ((AllScorer)scorer(context, true, true)).explain(doc); } } diff --git a/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java b/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java index 74875bedbfc..da746d6a2a0 100755 --- a/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/ScaleFloatFunction.java @@ -20,7 +20,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; -import org.apache.solr.search.SolrIndexReader; +import org.apache.lucene.util.ReaderUtil; import java.io.IOException; import java.util.Map; @@ -59,8 +59,7 @@ public class ScaleFloatFunction extends ValueSource { private ScaleInfo createScaleInfo(Map context, IndexReader reader) throws IOException { IndexReader.ReaderContext ctx = ValueSource.readerToContext(context, reader); while (ctx.parent != null) ctx = ctx.parent; - AtomicReaderContext[] leaves = ctx.leaves(); - if (ctx == null) leaves = new AtomicReaderContext[] {(AtomicReaderContext)ctx}; + final AtomicReaderContext[] leaves = ReaderUtil.leaves(ctx); float minVal = Float.POSITIVE_INFINITY; float maxVal = Float.NEGATIVE_INFINITY; diff --git a/solr/src/java/org/apache/solr/search/function/ValueSource.java b/solr/src/java/org/apache/solr/search/function/ValueSource.java index daaffd65504..80f61f6018d 100644 --- a/solr/src/java/org/apache/solr/search/function/ValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/ValueSource.java @@ -27,7 +27,6 @@ import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.SortField; import org.apache.lucene.util.Bits; import org.apache.lucene.index.MultiFields; -import org.apache.solr.common.SolrException; import java.io.IOException; import java.io.Serializable; diff --git a/solr/src/test/org/apache/solr/search/TestDocSet.java b/solr/src/test/org/apache/solr/search/TestDocSet.java index 8a87ac5d72b..25eda5c9259 100644 --- a/solr/src/test/org/apache/solr/search/TestDocSet.java +++ b/solr/src/test/org/apache/solr/search/TestDocSet.java @@ -24,8 +24,10 @@ import java.io.IOException; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.OpenBitSetIterator; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.FilterIndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.MultiReader; import org.apache.lucene.search.Filter; @@ -424,18 +426,19 @@ public class TestDocSet extends LuceneTestCase { DocIdSet db; // first test in-sequence sub readers - for (ReaderContext readerInfo : topLevelContext.leaves()) { - da = fa.getDocIdSet(readerInfo); - db = fb.getDocIdSet(readerInfo); + for (AtomicReaderContext readerContext : ReaderUtil.leaves(topLevelContext)) { + da = fa.getDocIdSet(readerContext); + db = fb.getDocIdSet(readerContext); doTestIteratorEqual(da, db); } - int nReaders = topLevelContext.leaves().length; + AtomicReaderContext[] leaves = ReaderUtil.leaves(topLevelContext); + int nReaders = leaves.length; // now test out-of-sequence sub readers for (int i=0; i Date: Tue, 11 Jan 2011 13:16:19 +0000 Subject: [PATCH 042/252] removed redundant cast git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057612 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/test/org/apache/lucene/search/TestFilteredSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java index 365f2317b36..6070ad8e7cb 100644 --- a/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java +++ b/lucene/src/test/org/apache/lucene/search/TestFilteredSearch.java @@ -99,7 +99,7 @@ public class TestFilteredSearch extends LuceneTestCase { public DocIdSet getDocIdSet(AtomicReaderContext context) { assert context.isAtomic; final OpenBitSet set = new OpenBitSet(); - int docBase = ((AtomicReaderContext)context).docBase; + int docBase = context.docBase; final int limit = docBase+context.reader.maxDoc(); for (;index < docs.length; index++) { final int docId = docs[index]; From 6c9656b49b32f5d5c57c58a9b5b06725c7b244d6 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Tue, 11 Jan 2011 20:20:10 +0000 Subject: [PATCH 043/252] update eclipse configuration for carrot2 upgrade git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057836 13f79535-47bb-0310-9956-ffa450edef68 --- dev-tools/eclipse/dot.classpath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-tools/eclipse/dot.classpath b/dev-tools/eclipse/dot.classpath index eb7e0ee8094..244d5b440fd 100644 --- a/dev-tools/eclipse/dot.classpath +++ b/dev-tools/eclipse/dot.classpath @@ -119,7 +119,7 @@ - + From e46f6dfc9ab43a1256a458e15e9e483ea405e6cc Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Tue, 11 Jan 2011 22:32:09 +0000 Subject: [PATCH 044/252] LUCENE-2857: fix various problems w/ PulsingCodec git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1057897 13f79535-47bb-0310-9956-ffa450edef68 --- .../store/instantiated/TestIndicesEquals.java | 28 ++ .../lucene/index/codecs/PostingsConsumer.java | 9 +- .../index/codecs/PrefixCodedTermsReader.java | 2 +- .../apache/lucene/index/codecs/TermState.java | 2 +- .../pulsing/PulsingPostingsReaderImpl.java | 404 ++++++++++-------- .../pulsing/PulsingPostingsWriterImpl.java | 292 ++++++------- .../codecs/sep/SepPostingsReaderImpl.java | 4 +- .../standard/StandardPostingsReader.java | 7 +- .../lucene/store/ByteArrayDataInput.java | 56 +++ .../apache/lucene/index/TestIndexReader.java | 1 + .../apache/lucene/index/TestNRTThreads.java | 1 + .../codecs/mockrandom/MockRandomCodec.java | 10 +- 12 files changed, 480 insertions(+), 336 deletions(-) create mode 100644 lucene/src/java/org/apache/lucene/store/ByteArrayDataInput.java diff --git a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java index a698abd52dd..3d5c247cb7f 100644 --- a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java +++ b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java @@ -91,6 +91,10 @@ public class TestIndicesEquals extends LuceneTestCase { // create dir data IndexWriter indexWriter = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer())); + indexWriter.setInfoStream(VERBOSE ? System.out : null); + if (VERBOSE) { + System.out.println("TEST: make test index"); + } for (int i = 0; i < 500; i++) { Document document = new Document(); assembleDocument(document, i); @@ -320,6 +324,9 @@ public class TestIndicesEquals extends LuceneTestCase { protected void testEquals(Directory aprioriIndex, InstantiatedIndex testIndex) throws Exception { + if (VERBOSE) { + System.out.println("TEST: testEquals"); + } testTermDocsSomeMore(aprioriIndex, testIndex); IndexReader aprioriReader = IndexReader.open(aprioriIndex, false); @@ -401,6 +408,9 @@ public class TestIndicesEquals extends LuceneTestCase { String aprioriField; while((aprioriField = aprioriFieldsEnum.next()) != null) { String testField = testFieldsEnum.next(); + if (VERBOSE) { + System.out.println("TEST: verify field=" + testField); + } assertEquals(aprioriField, testField); TermsEnum aprioriTermEnum = aprioriFieldsEnum.terms(); @@ -409,6 +419,9 @@ public class TestIndicesEquals extends LuceneTestCase { BytesRef aprioriText; while((aprioriText = aprioriTermEnum.next()) != null) { assertEquals(aprioriText, testTermEnum.next()); + if (VERBOSE) { + System.out.println("TEST: verify term=" + aprioriText.utf8ToString()); + } assertTrue(aprioriTermEnum.docFreq() == testTermEnum.docFreq()); @@ -434,6 +447,10 @@ public class TestIndicesEquals extends LuceneTestCase { assertEquals(DocsEnum.NO_MORE_DOCS, testTermDocs.nextDoc()); break; } + if (VERBOSE) { + System.out.println("TEST: verify doc=" + aprioriTermDocs.docID()); + } + assertTrue(testTermDocs.nextDoc() != DocsEnum.NO_MORE_DOCS); assertEquals(aprioriTermDocs.docID(), testTermDocs.docID()); @@ -445,12 +462,19 @@ public class TestIndicesEquals extends LuceneTestCase { DocsAndPositionsEnum aprioriTermPositions = aprioriTermEnum.docsAndPositions(MultiFields.getDeletedDocs(aprioriReader), null); DocsAndPositionsEnum testTermPositions = testTermEnum.docsAndPositions(MultiFields.getDeletedDocs(testReader), null); + if (VERBOSE) { + System.out.println("TEST: enum1=" + aprioriTermPositions + " enum2=" + testTermPositions); + } if (aprioriTermPositions != null) { for (int docIndex = 0; docIndex < aprioriReader.maxDoc(); docIndex++) { boolean hasNext = aprioriTermPositions.nextDoc() != DocsEnum.NO_MORE_DOCS; if (hasNext) { assertTrue(testTermPositions.nextDoc() != DocsEnum.NO_MORE_DOCS); + + if (VERBOSE) { + System.out.println("TEST: verify doc=" + aprioriTermPositions.docID()); + } assertEquals(aprioriTermPositions.freq(), testTermPositions.freq()); @@ -458,6 +482,10 @@ public class TestIndicesEquals extends LuceneTestCase { int aprioriPos = aprioriTermPositions.nextPosition(); int testPos = testTermPositions.nextPosition(); + if (VERBOSE) { + System.out.println("TEST: verify pos=" + aprioriPos); + } + assertEquals(aprioriPos, testPos); assertEquals(aprioriTermPositions.hasPayload(), testTermPositions.hasPayload()); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PostingsConsumer.java b/lucene/src/java/org/apache/lucene/index/codecs/PostingsConsumer.java index a6bd46fe82a..94a9edc65fb 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PostingsConsumer.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PostingsConsumer.java @@ -30,9 +30,9 @@ import org.apache.lucene.util.BytesRef; public abstract class PostingsConsumer { - /** Adds a new doc in this term. Return null if this - * consumer doesn't need to see the positions for this - * doc. */ + /** Adds a new doc in this term. If this field omits term + * freqs & positions then termDocFreq should be ignored, + * and, finishDoc will not be called. */ public abstract void startDoc(int docID, int termDocFreq) throws IOException; public static class PostingsMergeState { @@ -49,7 +49,8 @@ public abstract class PostingsConsumer { public abstract void addPosition(int position, BytesRef payload) throws IOException; /** Called when we are done adding positions & payloads - * for each doc */ + * for each doc. Not called when the field omits term + * freq and positions. */ public abstract void finishDoc() throws IOException; /** Default merge impl: append documents, mapping around diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java index e4b7ec9bfff..053af472512 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java @@ -356,7 +356,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { if (useCache) { cachedState = termsCache.get(fieldTerm); if (cachedState != null) { - state.copy(cachedState); + state.copyFrom(cachedState); seekPending = true; positioned = false; bytesReader.term.copy(term); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/TermState.java b/lucene/src/java/org/apache/lucene/index/codecs/TermState.java index df437f54dd8..ec423269a10 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/TermState.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/TermState.java @@ -33,7 +33,7 @@ public class TermState implements Cloneable { public long filePointer; // fp into the terms dict primary file (_X.tis) public int docFreq; // how many docs have this term - public void copy(TermState other) { + public void copyFrom(TermState other) { ord = other.ord; filePointer = other.filePointer; docFreq = other.docFreq; diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java index 4914b36059a..d2bc02a69f9 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java @@ -19,14 +19,14 @@ package org.apache.lucene.index.codecs.pulsing; import java.io.IOException; +import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.FieldInfo; -import org.apache.lucene.index.DocsAndPositionsEnum; -import org.apache.lucene.index.codecs.TermState; import org.apache.lucene.index.codecs.PostingsReaderBase; -import org.apache.lucene.index.codecs.pulsing.PulsingPostingsWriterImpl.Document; -import org.apache.lucene.index.codecs.pulsing.PulsingPostingsWriterImpl.Position; +import org.apache.lucene.index.codecs.TermState; +import org.apache.lucene.store.ByteArrayDataInput; import org.apache.lucene.store.IndexInput; +import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; @@ -43,7 +43,7 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { // Fallback reader for non-pulsed terms: final PostingsReaderBase wrappedPostingsReader; - int maxPulsingDocFreq; + int maxPositions; public PulsingPostingsReaderImpl(PostingsReaderBase wrappedPostingsReader) throws IOException { this.wrappedPostingsReader = wrappedPostingsReader; @@ -53,38 +53,50 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { public void init(IndexInput termsIn) throws IOException { CodecUtil.checkHeader(termsIn, PulsingPostingsWriterImpl.CODEC, PulsingPostingsWriterImpl.VERSION_START, PulsingPostingsWriterImpl.VERSION_START); - maxPulsingDocFreq = termsIn.readVInt(); wrappedPostingsReader.init(termsIn); } private static class PulsingTermState extends TermState { - private Document docs[]; + private byte[] postings; + private int postingsSize; // -1 if this term was not inlined private TermState wrappedTermState; private boolean pendingIndexTerm; + @Override public Object clone() { PulsingTermState clone; clone = (PulsingTermState) super.clone(); - clone.docs = docs.clone(); - for(int i=0;i>> 1; // shift off low bit + if ((code & 1) != 0) { // if low bit is set + freq = 1; // freq is one + } else { + freq = postings.readVInt(); // else read freq + } + + // Skip positions + if (storePayloads) { + int payloadLength = -1; + for(int pos=0;pos>> 1; // shift off low bit + if ((code & 1) != 0) { // if low bit is set + freq = 1; // freq is one } else { - doc = state.docs[nextRead++]; - if (skipDocs == null || !skipDocs.get(doc.docID)) { - nextPosRead = 0; - return doc.docID; - } + freq = postings.readVInt(); // else read freq + } + posPending = freq; + + if (skipDocs == null || !skipDocs.get(docID)) { + //System.out.println(" return docID=" + docID + " freq=" + freq); + position = 0; + return docID; } } } @Override public int freq() { - return doc.numPositions; + return freq; } @Override public int docID() { - return doc.docID; + return docID; } @Override @@ -351,22 +375,68 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { } @Override - public int nextPosition() { - assert nextPosRead < doc.numPositions; - pos = doc.positions[nextPosRead++]; - payloadRetrieved = false; - return pos.pos; + public int nextPosition() throws IOException { + //System.out.println("PR d&p nextPosition posPending=" + posPending + " vs freq=" + freq); + + assert posPending > 0; + posPending--; + + if (storePayloads) { + if (!payloadRetrieved) { + //System.out.println("PR skip payload=" + payloadLength); + postings.skipBytes(payloadLength); + } + final int code = postings.readVInt(); + //System.out.println("PR code=" + code); + if ((code & 1) != 0) { + payloadLength = postings.readVInt(); + //System.out.println("PR new payload len=" + payloadLength); + } + position += code >> 1; + payloadRetrieved = false; + } else { + position += postings.readVInt(); + } + + //System.out.println("PR d&p nextPos return pos=" + position + " this=" + this); + return position; + } + + private void skipPositions() throws IOException { + while(posPending != 0) { + nextPosition(); + } + if (storePayloads && !payloadRetrieved) { + //System.out.println(" skip payload len=" + payloadLength); + postings.skipBytes(payloadLength); + payloadRetrieved = true; + } } @Override public boolean hasPayload() { - return !payloadRetrieved && pos.payload != null && pos.payload.length > 0; + return storePayloads && !payloadRetrieved && payloadLength > 0; } @Override - public BytesRef getPayload() { + public BytesRef getPayload() throws IOException { + //System.out.println("PR getPayload payloadLength=" + payloadLength + " this=" + this); + if (payloadRetrieved) { + throw new IOException("Either no payload exists at this term position or an attempt was made to load it more than once."); + } payloadRetrieved = true; - return pos.payload; + if (payloadLength > 0) { + if (payload == null) { + payload = new BytesRef(payloadLength); + } else { + payload.grow(payloadLength); + } + postings.readBytes(payload.bytes, 0, payloadLength); + payload.length = payloadLength; + return payload; + } else { + return null; + } } } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java index f18637d29ad..d8e67a2bc43 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java @@ -20,12 +20,11 @@ package org.apache.lucene.index.codecs.pulsing; import java.io.IOException; import org.apache.lucene.index.FieldInfo; -import org.apache.lucene.util.CodecUtil; import org.apache.lucene.index.codecs.PostingsWriterBase; import org.apache.lucene.store.IndexOutput; -import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.store.RAMOutputStream; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.RamUsageEstimator; +import org.apache.lucene.util.CodecUtil; // TODO: we now pulse entirely according to docFreq of the // term; it might be better to eg pulse by "net bytes used" @@ -44,67 +43,21 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { final static int VERSION_CURRENT = VERSION_START; - IndexOutput termsOut; + private IndexOutput termsOut; - boolean omitTF; - boolean storePayloads; + private boolean omitTF; + private boolean storePayloads; - // Starts a new term - FieldInfo fieldInfo; + // one entry per position + private final Position[] pending; + private int pendingCount = 0; // -1 once we've hit too many positions + private Position currentDoc; // first Position entry of current doc - /** @lucene.experimental */ - public static class Document { - int docID; - int termDocFreq; - int numPositions; - Position[] positions; - Document() { - positions = new Position[1]; - positions[0] = new Position(); - } - - @Override - public Object clone() { - Document doc = new Document(); - doc.docID = docID; - doc.termDocFreq = termDocFreq; - doc.numPositions = numPositions; - doc.positions = new Position[positions.length]; - for(int i = 0; i < positions.length; i++) { - doc.positions[i] = (Position) positions[i].clone(); - } - - return doc; - } - - void reallocPositions(int minSize) { - final Position[] newArray = new Position[ArrayUtil.oversize(minSize, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; - System.arraycopy(positions, 0, newArray, 0, positions.length); - for(int i=positions.length;i maxPulsingDocFreq docs - - static class Position { + private static final class Position { BytesRef payload; + int termFreq; // only incremented on first position for a given doc int pos; - - @Override - public Object clone() { - Position position = new Position(); - position.pos = pos; - if (payload != null) { - position.payload = new BytesRef(payload); - } - return position; - } + int docID; } // TODO: -- lazy init this? ie, if every single term @@ -112,18 +65,19 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { // Fallback writer for non-pulsed terms: final PostingsWriterBase wrappedPostingsWriter; - /** If docFreq <= maxPulsingDocFreq, its postings are + /** If the total number of positions (summed across all docs + * for this term) is <= maxPositions, then the postings are * inlined into terms dict */ - public PulsingPostingsWriterImpl(int maxPulsingDocFreq, PostingsWriterBase wrappedPostingsWriter) throws IOException { + public PulsingPostingsWriterImpl(int maxPositions, PostingsWriterBase wrappedPostingsWriter) throws IOException { super(); - pendingDocs = new Document[maxPulsingDocFreq]; - for(int i=0;i= the cutoff: this.wrappedPostingsWriter = wrappedPostingsWriter; } @@ -131,14 +85,13 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { public void start(IndexOutput termsOut) throws IOException { this.termsOut = termsOut; CodecUtil.writeHeader(termsOut, CODEC, VERSION_CURRENT); - termsOut.writeVInt(pendingDocs.length); wrappedPostingsWriter.start(termsOut); } @Override public void startTerm() { - assert pendingDocCount == 0; - pulsed = false; + //System.out.println("PW startTerm"); + assert pendingCount == 0; } // TODO: -- should we NOT reuse across fields? would @@ -148,7 +101,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { // our parent calls setField whenever the field changes @Override public void setField(FieldInfo fieldInfo) { - this.fieldInfo = fieldInfo; + //System.out.println("PW field=" + fieldInfo.name); omitTF = fieldInfo.omitTermFreqAndPositions; storePayloads = fieldInfo.storePayloads; wrappedPostingsWriter.setField(fieldInfo); @@ -156,65 +109,47 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { @Override public void startDoc(int docID, int termDocFreq) throws IOException { - assert docID >= 0: "got docID=" + docID; - - if (!pulsed && pendingDocCount == pendingDocs.length) { - - // OK we just crossed the threshold, this term should - // now be written with our wrapped codec: - wrappedPostingsWriter.startTerm(); - - // Flush all buffered docs - for(int i=0;i 0) { if (pos.payload == null) { pos.payload = new BytesRef(payload); @@ -229,86 +164,137 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { @Override public void finishDoc() throws IOException { - assert omitTF || currentDoc.numPositions == currentDoc.termDocFreq; - if (pulsed) { + //System.out.println("PW finishDoc"); + if (pendingCount == -1) { wrappedPostingsWriter.finishDoc(); } } - boolean pendingIsIndexTerm; + private boolean pendingIsIndexTerm; - int pulsedCount; - int nonPulsedCount; + private final RAMOutputStream buffer = new RAMOutputStream(); /** Called when we are done adding docs to this term */ @Override public void finishTerm(int docCount, boolean isIndexTerm) throws IOException { + //System.out.println("PW finishTerm docCount=" + docCount); - assert docCount > 0; + assert pendingCount > 0 || pendingCount == -1; pendingIsIndexTerm |= isIndexTerm; - if (pulsed) { + if (pendingCount == -1) { + termsOut.writeByte((byte) 0); wrappedPostingsWriter.finishTerm(docCount, pendingIsIndexTerm); pendingIsIndexTerm = false; - pulsedCount++; } else { - nonPulsedCount++; - // OK, there were few enough occurrences for this + + // There were few enough total occurrences for this // term, so we fully inline our postings data into // terms dict, now: - int lastDocID = 0; - for(int i=0;i doc.docID; + wrappedPostingsWriter.finishDoc(); + doc = pos; + wrappedPostingsWriter.startDoc(doc.docID, doc.termFreq); + } + wrappedPostingsWriter.addPosition(pos.pos, pos.payload); + } + //wrappedPostingsWriter.finishDoc(); + } else { + for(Position doc : pending) { + wrappedPostingsWriter.startDoc(doc.docID, 0); + } + } + pendingCount = -1; + } } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java index 342d2fa8bcd..d3a35c5bc75 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java @@ -141,8 +141,8 @@ public class SepPostingsReaderImpl extends PostingsReaderBase { return other; } - public void copy(TermState _other) { - super.copy(_other); + public void copyFrom(TermState _other) { + super.copyFrom(_other); SepTermState other = (SepTermState) _other; docIndex.set(other.docIndex); } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java index eed6b0e6735..10ec9d8b20f 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java @@ -90,12 +90,12 @@ public class StandardPostingsReader extends PostingsReaderBase { public Object clone() { DocTermState other = new DocTermState(); - other.copy(this); + other.copyFrom(this); return other; } - public void copy(TermState _other) { - super.copy(_other); + public void copyFrom(TermState _other) { + super.copyFrom(_other); DocTermState other = (DocTermState) _other; freqOffset = other.freqOffset; proxOffset = other.proxOffset; @@ -785,6 +785,7 @@ public class StandardPostingsReader extends PostingsReaderBase { if (payloadLength > payload.bytes.length) { payload.grow(payloadLength); } + proxIn.readBytes(payload.bytes, 0, payloadLength); payload.length = payloadLength; payloadPending = false; diff --git a/lucene/src/java/org/apache/lucene/store/ByteArrayDataInput.java b/lucene/src/java/org/apache/lucene/store/ByteArrayDataInput.java new file mode 100644 index 00000000000..23cbd4a09a3 --- /dev/null +++ b/lucene/src/java/org/apache/lucene/store/ByteArrayDataInput.java @@ -0,0 +1,56 @@ +package org.apache.lucene.store; + +/** + * 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. + */ + +/** @lucene.experimental */ +public final class ByteArrayDataInput extends DataInput { + + private byte[] bytes; + private int pos; + + // TODO: allow BytesRef (slice) too + public ByteArrayDataInput(byte[] bytes) { + this.bytes = bytes; + } + + public void reset(byte[] bytes) { + this.bytes = bytes; + pos = 0; + } + + public boolean eof() { + return pos == bytes.length; + } + + public void skipBytes(int count) { + pos += count; + } + + // NOTE: AIOOBE not EOF if you read too much + @Override + public byte readByte() { + return bytes[pos++]; + } + + // NOTE: AIOOBE not EOF if you read too much + @Override + public void readBytes(byte[] b, int offset, int len) { + System.arraycopy(bytes, pos, b, offset, len); + pos += len; + } +} diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java index d3a3db8b691..a82e5285522 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java @@ -329,6 +329,7 @@ public class TestIndexReader extends LuceneTestCase // add 100 documents with term : aaa writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer())); + writer.setInfoStream(VERBOSE ? System.out : null); for (int i = 0; i < 100; i++) { addDoc(writer, searchTerm.text()); } diff --git a/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java b/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java index af0cde305c8..d9bd3a4a922 100644 --- a/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java +++ b/lucene/src/test/org/apache/lucene/index/TestNRTThreads.java @@ -349,6 +349,7 @@ public class TestNRTThreads extends LuceneTestCase { assertEquals("index=" + writer.segString() + " addCount=" + addCount + " delCount=" + delCount, addCount.get() - delCount.get(), writer.numDocs()); writer.close(false); + _TestUtil.checkIndex(dir); dir.close(); _TestUtil.rmDir(tempDir); docs.close(); diff --git a/lucene/src/test/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java b/lucene/src/test/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java index b12a78a1031..c17509c8f8d 100644 --- a/lucene/src/test/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java +++ b/lucene/src/test/org/apache/lucene/index/codecs/mockrandom/MockRandomCodec.java @@ -108,11 +108,11 @@ public class MockRandomCodec extends Codec { } if (random.nextBoolean()) { - final int freqCutoff = _TestUtil.nextInt(random, 1, 20); + final int totTFCutoff = _TestUtil.nextInt(random, 1, 20); if (LuceneTestCase.VERBOSE) { - System.out.println("MockRandomCodec: pulsing postings with freqCutoff=" + freqCutoff); + System.out.println("MockRandomCodec: pulsing postings with totTFCutoff=" + totTFCutoff); } - postingsWriter = new PulsingPostingsWriterImpl(freqCutoff, postingsWriter); + postingsWriter = new PulsingPostingsWriterImpl(totTFCutoff, postingsWriter); } final TermsIndexWriterBase indexWriter; @@ -218,9 +218,9 @@ public class MockRandomCodec extends Codec { } if (random.nextBoolean()) { - final int freqCutoff = _TestUtil.nextInt(random, 1, 20); + final int totTFCutoff = _TestUtil.nextInt(random, 1, 20); if (LuceneTestCase.VERBOSE) { - System.out.println("MockRandomCodec: reading pulsing postings with freqCutoff=" + freqCutoff); + System.out.println("MockRandomCodec: reading pulsing postings with totTFCutoff=" + totTFCutoff); } postingsReader = new PulsingPostingsReaderImpl(postingsReader); } From e79fcaec7cd8e8708110b89bcdc388a42e2f5353 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 08:22:12 +0000 Subject: [PATCH 045/252] LUCENE-2831: Cut over Collector#setNextReader & FieldComparator#setNextReader to AtomicReaderContext git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058019 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 8 ++- .../org/apache/lucene/demo/SearchFiles.java | 5 +- .../highlight/HighlighterPhraseTest.java | 5 +- .../store/instantiated/TestRealTime.java | 4 +- .../lucli/src/java/lucli/LuceneMethods.java | 3 +- .../lucene/index/memory/MemoryIndex.java | 3 +- .../lucene/index/TestFieldNormModifier.java | 7 ++- .../lucene/misc/TestLengthNormModifier.java | 5 +- .../surround/query/BooleanQueryTst.java | 4 +- .../tier/DistanceFieldComparatorSource.java | 20 +++---- .../lucene/swing/models/ListSearcher.java | 3 +- .../org/apache/lucene/wordnet/SynExpand.java | 5 +- .../org/apache/lucene/wordnet/SynLookup.java | 7 ++- .../apache/lucene/search/BooleanScorer.java | 4 +- .../org/apache/lucene/search/Collector.java | 22 +++---- .../lucene/search/ConstantScoreQuery.java | 4 +- .../apache/lucene/search/FieldComparator.java | 58 +++++++++---------- .../apache/lucene/search/IndexSearcher.java | 4 +- .../apache/lucene/search/MultiCollector.java | 6 +- .../search/PositiveScoresOnlyCollector.java | 6 +- .../lucene/search/TimeLimitingCollector.java | 8 +-- .../lucene/search/TopFieldCollector.java | 14 ++--- .../lucene/search/TopScoreDocCollector.java | 6 +- .../lucene/search/TotalHitCountCollector.java | 4 +- .../org/apache/lucene/index/TestOmitTf.java | 3 +- .../org/apache/lucene/search/CheckHits.java | 9 +-- .../lucene/search/JustCompileSearch.java | 6 +- .../lucene/search/MultiCollectorTest.java | 8 +-- .../org/apache/lucene/search/QueryUtils.java | 14 ++--- .../lucene/search/TestConstantScoreQuery.java | 3 +- .../apache/lucene/search/TestDocBoost.java | 5 +- .../search/TestElevationComparator.java | 5 +- .../search/TestMultiTermConstantScore.java | 5 +- .../TestScoreCachingWrappingScorer.java | 4 +- .../apache/lucene/search/TestScorerPerf.java | 5 +- .../org/apache/lucene/search/TestSetNorm.java | 5 +- .../apache/lucene/search/TestSimilarity.java | 11 ++-- .../org/apache/lucene/search/TestSort.java | 4 +- .../lucene/search/TestSubScorerFreqs.java | 5 +- .../apache/lucene/search/TestTermScorer.java | 4 +- .../search/TestTimeLimitingCollector.java | 5 +- .../lucene/search/TestTopDocsCollector.java | 5 +- .../handler/component/QueryComponent.java | 31 +++++----- .../component/QueryElevationComponent.java | 5 +- .../handler/component/TermsComponent.java | 5 +- .../apache/solr/schema/RandomSortField.java | 7 ++- .../solr/search/DocSetHitCollector.java | 12 ++-- .../java/org/apache/solr/search/Grouping.java | 31 +++++----- .../MissingStringLastComparatorSource.java | 9 +-- .../apache/solr/search/SolrIndexSearcher.java | 39 ++++++------- .../solr/search/function/ValueSource.java | 4 +- .../org/apache/solr/update/UpdateHandler.java | 4 +- .../org/apache/solr/search/TestDocSet.java | 5 +- .../apache/solr/search/TestIndexSearcher.java | 47 ++++++++------- .../test/org/apache/solr/search/TestSort.java | 7 +-- .../solr/update/DirectUpdateHandlerTest.java | 11 +--- 56 files changed, 278 insertions(+), 260 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 7ca14de759b..888ed11b991 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -128,8 +128,8 @@ Changes in backwards compatibility policy ParallelMultiSearcher into IndexSearcher as an optional ExecutorServiced passed to its ctor. (Mike McCandless) -* LUCENE-2837: Changed Weight#scorer, Weight#explain & Filter#getDocIdSet to - operate on a ReaderContext instead of directly on IndexReader to enable +* LUCENE-2831: Changed Weight#scorer, Weight#explain & Filter#getDocIdSet to + operate on a AtomicReaderContext instead of directly on IndexReader to enable searches to be aware of IndexSearcher's context. (Simon Willnauer) * LUCENE-2839: Scorer#score(Collector,int,int) is now public because it is @@ -188,6 +188,10 @@ API Changes * LUCENE-2778: RAMDirectory now exposes newRAMFile() which allows to override and return a different RAMFile implementation. (Shai Erera) + +* LUCENE-2831: Weight#scorer, Weight#explain, Filter#getDocIdSet, + Collector#setNextReader & FieldComparator#setNextReader now expect an + AtomicReaderContext instead of an IndexReader. (Simon Willnauer) New features diff --git a/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java b/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java index 422e23497d7..6a300459995 100644 --- a/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java +++ b/lucene/contrib/demo/src/java/org/apache/lucene/demo/SearchFiles.java @@ -28,6 +28,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.Collector; import org.apache.lucene.search.IndexSearcher; @@ -160,9 +161,9 @@ public class SearchFiles { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { - this.docBase = docBase; + this.docBase = context.docBase; } @Override diff --git a/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterPhraseTest.java b/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterPhraseTest.java index 31752349dd2..1f60e6ea5c5 100644 --- a/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterPhraseTest.java +++ b/lucene/contrib/highlighter/src/test/org/apache/lucene/search/highlight/HighlighterPhraseTest.java @@ -36,6 +36,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.TermPositionVector; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.PhraseQuery; @@ -133,9 +134,9 @@ public class HighlighterPhraseTest extends LuceneTestCase { } @Override - public void setNextReader(IndexReader indexreader, int i) + public void setNextReader(AtomicReaderContext context) throws IOException { - this.baseDoc = i; + this.baseDoc = context.docBase; } @Override diff --git a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java index 4e7c59f9e6a..383cd807caf 100644 --- a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java +++ b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestRealTime.java @@ -20,8 +20,8 @@ import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.Scorer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.util.LuceneTestCase; /** @@ -67,7 +67,7 @@ public class TestRealTime extends LuceneTestCase { @Override public void setScorer(Scorer scorer) {} @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; } @Override diff --git a/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java b/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java index 9aca8ee3f27..266297b1f3b 100644 --- a/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java +++ b/lucene/contrib/lucli/src/java/lucli/LuceneMethods.java @@ -41,6 +41,7 @@ import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Fields; @@ -232,7 +233,7 @@ class LuceneMethods { } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; diff --git a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index f342c4f640f..07af85cb557 100644 --- a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -38,6 +38,7 @@ import org.apache.lucene.document.Document; import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.FieldsEnum; @@ -443,7 +444,7 @@ public class MemoryIndex implements Serializable { } @Override - public void setNextReader(IndexReader reader, int docBase) { } + public void setNextReader(AtomicReaderContext context) { } }); float score = scores[0]; return score; diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java index 8066ea4e399..bdc386cefcd 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java @@ -23,6 +23,7 @@ import java.util.Arrays; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.IndexSearcher; @@ -122,7 +123,7 @@ public class TestFieldNormModifier extends LuceneTestCase { scores[doc + docBase] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override @@ -157,7 +158,7 @@ public class TestFieldNormModifier extends LuceneTestCase { scores[doc + docBase] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override @@ -209,7 +210,7 @@ public class TestFieldNormModifier extends LuceneTestCase { scores[doc + docBase] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java index cb424b451d3..7646bd1d531 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java @@ -25,6 +25,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.FieldNormModifier; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.MultiNorms; import org.apache.lucene.index.Term; @@ -139,7 +140,7 @@ public class TestLengthNormModifier extends LuceneTestCase { scores[doc + docBase] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override @@ -181,7 +182,7 @@ public class TestLengthNormModifier extends LuceneTestCase { scores[doc + docBase] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override diff --git a/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java b/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java index c89127cde9d..325db2637e1 100644 --- a/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java +++ b/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java @@ -19,7 +19,7 @@ package org.apache.lucene.queryParser.surround.query; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Collector; import org.apache.lucene.search.Scorer; @@ -77,7 +77,7 @@ public class BooleanQueryTst { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { this.docBase = docBase; } diff --git a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java index 262916a9c68..dec1f88b14c 100644 --- a/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java +++ b/lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFieldComparatorSource.java @@ -19,7 +19,7 @@ package org.apache.lucene.spatial.tier; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Filter; import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparatorSource; @@ -108,16 +108,14 @@ public class DistanceFieldComparatorSource extends FieldComparatorSource { } - @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) - throws IOException { - - // each reader in a segmented base - // has an offset based on the maxDocs of previous readers - offset = docBase; - - return this; - } + @Override + public FieldComparator setNextReader(AtomicReaderContext context) + throws IOException { + // each reader in a segmented base + // has an offset based on the maxDocs of previous readers + offset = context.docBase; + return this; + } @Override public Comparable value(int slot) { diff --git a/lucene/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java b/lucene/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java index 611b063baef..e8d2b7765c0 100644 --- a/lucene/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java +++ b/lucene/contrib/swing/src/java/org/apache/lucene/swing/models/ListSearcher.java @@ -32,6 +32,7 @@ import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.search.Collector; import org.apache.lucene.search.IndexSearcher; @@ -192,7 +193,7 @@ public class ListSearcher extends AbstractListModel { } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; diff --git a/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java b/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java index 908cfd66eff..646abf73dbd 100755 --- a/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java +++ b/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynExpand.java @@ -33,6 +33,7 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Collector; @@ -160,9 +161,9 @@ public final class SynExpand { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { - this.reader = reader; + this.reader = context.reader; } @Override diff --git a/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java b/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java index 066df71ba02..4cc4836cc5b 100644 --- a/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java +++ b/lucene/contrib/wordnet/src/java/org/apache/lucene/wordnet/SynLookup.java @@ -32,6 +32,7 @@ import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.Collector; @@ -59,7 +60,7 @@ public class SynLookup { } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; @@ -169,9 +170,9 @@ public class SynLookup { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { - this.reader = reader; + this.reader = context.reader; } @Override diff --git a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java index 6374e89f98b..7b244b4eb3a 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanScorer.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanScorer.java @@ -20,7 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import java.util.List; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.BooleanClause.Occur; /* Description from Doug Cutting (excerpted from @@ -92,7 +92,7 @@ final class BooleanScorer extends Scorer { } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { // not needed by this implementation } diff --git a/lucene/src/java/org/apache/lucene/search/Collector.java b/lucene/src/java/org/apache/lucene/search/Collector.java index 57d7b061e2d..b64abce0f4b 100644 --- a/lucene/src/java/org/apache/lucene/search/Collector.java +++ b/lucene/src/java/org/apache/lucene/search/Collector.java @@ -19,7 +19,8 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; /** *

    Expert: Collectors are primarily meant to be used to @@ -98,8 +99,8 @@ import org.apache.lucene.index.IndexReader; * bits.set(doc + docBase); * } * - * public void setNextReader(IndexReader reader, int docBase) { - * this.docBase = docBase; + * public void setNextReader(AtomicReaderContext context) { + * this.docBase = context.docBase; * } * }); * @@ -143,17 +144,16 @@ public abstract class Collector { public abstract void collect(int doc) throws IOException; /** - * Called before collecting from each IndexReader. All doc ids in - * {@link #collect(int)} will correspond to reader. + * Called before collecting from each {@link AtomicReaderContext}. All doc ids in + * {@link #collect(int)} will correspond to {@link ReaderContext#reader}. * - * Add docBase to the current IndexReaders internal document id to re-base ids - * in {@link #collect(int)}. + * Add {@link AtomicReaderContext#docBase} to the current {@link ReaderContext#reader}'s + * internal document id to re-base ids in {@link #collect(int)}. * - * @param reader - * next IndexReader - * @param docBase + * @param context + * next atomic reader context */ - public abstract void setNextReader(IndexReader reader, int docBase) throws IOException; + public abstract void setNextReader(AtomicReaderContext context) throws IOException; /** * Return true if this collector does not diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index c8b8c9da180..dcbb0ecb204 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -222,8 +222,8 @@ public class ConstantScoreQuery extends Query { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - collector.setNextReader(reader, docBase); + public void setNextReader(AtomicReaderContext context) throws IOException { + collector.setNextReader(context); } @Override diff --git a/lucene/src/java/org/apache/lucene/search/FieldComparator.java b/lucene/src/java/org/apache/lucene/search/FieldComparator.java index de8c59d8408..54bc20ba95a 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldComparator.java +++ b/lucene/src/java/org/apache/lucene/search/FieldComparator.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.text.Collator; import java.util.Locale; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldCache.DocTermsIndex; import org.apache.lucene.search.FieldCache.DocTerms; import org.apache.lucene.search.cache.ByteValuesCreator; @@ -82,7 +82,7 @@ import org.apache.lucene.util.packed.PackedInts; * priority queue. The {@link FieldValueHitQueue} * calls this method when a new hit is competitive. * - *

  22. {@link #setNextReader} Invoked + *
  23. {@link #setNextReader(AtomicReaderContext)} Invoked * when the search is switching to the next segment. * You may need to update internal state of the * comparator, for example retrieving new values from @@ -150,19 +150,18 @@ public abstract class FieldComparator { public abstract void copy(int slot, int doc) throws IOException; /** - * Set a new Reader. All subsequent docIDs are relative to + * Set a new {@link AtomicReaderContext}. All subsequent docIDs are relative to * the current reader (you must add docBase if you need to * map it to a top-level docID). * - * @param reader current reader - * @param docBase docBase of this reader + * @param context current reader context * @return the comparator to use for this segment; most * comparators can just return "this" to reuse the same * comparator across segments * @throws IOException * @throws IOException */ - public abstract FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException; + public abstract FieldComparator setNextReader(AtomicReaderContext context) throws IOException; /** Sets the Scorer to use in case a document's score is * needed. @@ -242,8 +241,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup(FieldCache.DEFAULT.getBytes(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup(FieldCache.DEFAULT.getBytes(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -314,8 +313,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup(FieldCache.DEFAULT.getDoubles(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup(FieldCache.DEFAULT.getDoubles(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -388,8 +387,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup(FieldCache.DEFAULT.getFloats(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup(FieldCache.DEFAULT.getFloats(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -444,8 +443,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup( FieldCache.DEFAULT.getShorts(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup( FieldCache.DEFAULT.getShorts(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -522,8 +521,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup(FieldCache.DEFAULT.getInts(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup(FieldCache.DEFAULT.getInts(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -597,8 +596,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - setup(FieldCache.DEFAULT.getLongs(reader, creator.field, creator)); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + setup(FieldCache.DEFAULT.getLongs(context.reader, creator.field, creator)); docValues = cached.values; return this; } @@ -648,7 +647,7 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) { + public FieldComparator setNextReader(AtomicReaderContext context) { return this; } @@ -700,11 +699,11 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) { + public FieldComparator setNextReader(AtomicReaderContext context) { // TODO: can we "map" our docIDs to the current // reader? saves having to then subtract on every // compare call - this.docBase = docBase; + this.docBase = context.docBase; return this; } @@ -781,8 +780,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - currentDocTerms = FieldCache.DEFAULT.getTerms(reader, field); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + currentDocTerms = FieldCache.DEFAULT.getTerms(context.reader, field); return this; } @@ -876,8 +875,8 @@ public abstract class FieldComparator { abstract class PerSegmentComparator extends FieldComparator { @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - return TermOrdValComparator.this.setNextReader(reader, docBase); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + return TermOrdValComparator.this.setNextReader(context); } @Override @@ -1142,8 +1141,9 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - termsIndex = FieldCache.DEFAULT.getTermsIndex(reader, field); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + final int docBase = context.docBase; + termsIndex = FieldCache.DEFAULT.getTermsIndex(context.reader, field); final PackedInts.Reader docToOrd = termsIndex.getDocToOrd(); FieldComparator perSegComp; if (docToOrd instanceof Direct8) { @@ -1257,8 +1257,8 @@ public abstract class FieldComparator { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - docTerms = FieldCache.DEFAULT.getTerms(reader, field); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + docTerms = FieldCache.DEFAULT.getTerms(context.reader, field); return this; } diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 0dd8dfb85e3..9bd72d426db 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -486,7 +486,7 @@ public class IndexSearcher { // always use single thread: if (filter == null) { for (int i = 0; i < leafContexts.length; i++) { // search each subreader - collector.setNextReader(leafContexts[i].reader, leafContexts[i].docBase); + collector.setNextReader(leafContexts[i]); Scorer scorer = weight.scorer(leafContexts[i], !collector.acceptsDocsOutOfOrder(), true); if (scorer != null) { scorer.score(collector); @@ -494,7 +494,7 @@ public class IndexSearcher { } } else { for (int i = 0; i < leafContexts.length; i++) { // search each subreader - collector.setNextReader(leafContexts[i].reader, leafContexts[i].docBase); + collector.setNextReader(leafContexts[i]); searchWithFilter(leafContexts[i], weight, filter, collector); } } diff --git a/lucene/src/java/org/apache/lucene/search/MultiCollector.java b/lucene/src/java/org/apache/lucene/search/MultiCollector.java index ee79f549b0b..08e08403d33 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiCollector.java +++ b/lucene/src/java/org/apache/lucene/search/MultiCollector.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.Scorer; @@ -108,9 +108,9 @@ public class MultiCollector extends Collector { } @Override - public void setNextReader(IndexReader reader, int o) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { for (Collector c : collectors) { - c.setNextReader(reader, o); + c.setNextReader(context); } } diff --git a/lucene/src/java/org/apache/lucene/search/PositiveScoresOnlyCollector.java b/lucene/src/java/org/apache/lucene/search/PositiveScoresOnlyCollector.java index 2dd47bcbfe1..1e7cca99fa8 100644 --- a/lucene/src/java/org/apache/lucene/search/PositiveScoresOnlyCollector.java +++ b/lucene/src/java/org/apache/lucene/search/PositiveScoresOnlyCollector.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; /** * A {@link Collector} implementation which wraps another @@ -43,8 +43,8 @@ public class PositiveScoresOnlyCollector extends Collector { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - c.setNextReader(reader, docBase); + public void setNextReader(AtomicReaderContext context) throws IOException { + c.setNextReader(context); } @Override diff --git a/lucene/src/java/org/apache/lucene/search/TimeLimitingCollector.java b/lucene/src/java/org/apache/lucene/search/TimeLimitingCollector.java index 405f1a09901..63ad23d9d6c 100644 --- a/lucene/src/java/org/apache/lucene/search/TimeLimitingCollector.java +++ b/lucene/src/java/org/apache/lucene/search/TimeLimitingCollector.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.ThreadInterruptedException; /** @@ -213,9 +213,9 @@ public class TimeLimitingCollector extends Collector { } @Override - public void setNextReader(IndexReader reader, int base) throws IOException { - collector.setNextReader(reader, base); - this.docBase = base; + public void setNextReader(AtomicReaderContext context) throws IOException { + collector.setNextReader(context); + this.docBase = context.docBase; } @Override diff --git a/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java index 7c78274bb84..05e178d3115 100644 --- a/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java +++ b/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldValueHitQueue.Entry; import org.apache.lucene.util.PriorityQueue; @@ -92,9 +92,9 @@ public abstract class TopFieldCollector extends TopDocsCollector { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - this.docBase = docBase; - queue.setComparator(0, comparator.setNextReader(reader, docBase)); + public void setNextReader(AtomicReaderContext context) throws IOException { + this.docBase = context.docBase; + queue.setComparator(0, comparator.setNextReader(context)); comparator = queue.firstComparator; } @@ -447,10 +447,10 @@ public abstract class TopFieldCollector extends TopDocsCollector { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - this.docBase = docBase; + public void setNextReader(AtomicReaderContext context) throws IOException { + this.docBase = context.docBase; for (int i = 0; i < comparators.length; i++) { - queue.setComparator(i, comparators[i].setNextReader(reader, docBase)); + queue.setComparator(i, comparators[i].setNextReader(context)); } } diff --git a/lucene/src/java/org/apache/lucene/search/TopScoreDocCollector.java b/lucene/src/java/org/apache/lucene/search/TopScoreDocCollector.java index 08a6897065a..d8f317592c1 100644 --- a/lucene/src/java/org/apache/lucene/search/TopScoreDocCollector.java +++ b/lucene/src/java/org/apache/lucene/search/TopScoreDocCollector.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; /** * A {@link Collector} implementation that collects the top-scoring hits, @@ -155,8 +155,8 @@ public abstract class TopScoreDocCollector extends TopDocsCollector { } @Override - public void setNextReader(IndexReader reader, int base) { - docBase = base; + public void setNextReader(AtomicReaderContext context) { + docBase = context.docBase; } @Override diff --git a/lucene/src/java/org/apache/lucene/search/TotalHitCountCollector.java b/lucene/src/java/org/apache/lucene/search/TotalHitCountCollector.java index 444fa67f942..533d69c65d3 100644 --- a/lucene/src/java/org/apache/lucene/search/TotalHitCountCollector.java +++ b/lucene/src/java/org/apache/lucene/search/TotalHitCountCollector.java @@ -17,7 +17,7 @@ package org.apache.lucene.search; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; /** * Just counts the total number of hits. @@ -38,7 +38,7 @@ public class TotalHitCountCollector extends Collector { totalHits++; } - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { } public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java index 78b96dc5d32..21968df695b 100644 --- a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java +++ b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java @@ -26,6 +26,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.store.Directory; @@ -414,7 +415,7 @@ public class TestOmitTf extends LuceneTestCase { public static int getSum() { return sum; } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { this.docBase = docBase; } @Override diff --git a/lucene/src/test/org/apache/lucene/search/CheckHits.java b/lucene/src/test/org/apache/lucene/search/CheckHits.java index dedd91949b6..fbfa0de093e 100644 --- a/lucene/src/test/org/apache/lucene/search/CheckHits.java +++ b/lucene/src/test/org/apache/lucene/search/CheckHits.java @@ -25,6 +25,7 @@ import java.util.Random; import junit.framework.Assert; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.store.Directory; public class CheckHits { @@ -120,8 +121,8 @@ public class CheckHits { bag.add(Integer.valueOf(doc + base)); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { @@ -483,8 +484,8 @@ public class CheckHits { verifyExplanation(d,doc,scorer.score(),deep,exp); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index 2e43904b584..f932e39bbe2 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -44,7 +44,7 @@ final class JustCompileSearch { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } @@ -127,7 +127,7 @@ final class JustCompileSearch { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } @@ -300,7 +300,7 @@ final class JustCompileSearch { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/MultiCollectorTest.java b/lucene/src/test/org/apache/lucene/search/MultiCollectorTest.java index ae988c04ad2..a87135214ea 100644 --- a/lucene/src/test/org/apache/lucene/search/MultiCollectorTest.java +++ b/lucene/src/test/org/apache/lucene/search/MultiCollectorTest.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Collector; import org.apache.lucene.search.Scorer; import org.apache.lucene.util.LuceneTestCase; @@ -46,7 +46,7 @@ public class MultiCollectorTest extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { setNextReaderCalled = true; } @@ -73,7 +73,7 @@ public class MultiCollectorTest extends LuceneTestCase { assertTrue(c instanceof MultiCollector); assertTrue(c.acceptsDocsOutOfOrder()); c.collect(1); - c.setNextReader(null, 0); + c.setNextReader(null); c.setScorer(null); } @@ -95,7 +95,7 @@ public class MultiCollectorTest extends LuceneTestCase { Collector c = MultiCollector.wrap(dcs); assertTrue(c.acceptsDocsOutOfOrder()); c.collect(1); - c.setNextReader(null, 0); + c.setNextReader(null); c.setScorer(null); for (DummyCollector dc : dcs) { diff --git a/lucene/src/test/org/apache/lucene/search/QueryUtils.java b/lucene/src/test/org/apache/lucene/search/QueryUtils.java index 27dda23ce40..1b3002211b7 100644 --- a/lucene/src/test/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test/org/apache/lucene/search/QueryUtils.java @@ -220,7 +220,7 @@ public class QueryUtils { */ public static void checkSkipTo(final Query q, final IndexSearcher s) throws IOException { //System.out.println("Checking "+q); - final AtomicReaderContext[] context = ReaderUtil.leaves(s.getTopReaderContext()); + final AtomicReaderContext[] readerContextArray = ReaderUtil.leaves(s.getTopReaderContext()); if (q.weight(s).scoresDocsOutOfOrder()) return; // in this case order of skipTo() might differ from that of next(). final int skip_op = 0; @@ -265,7 +265,7 @@ public class QueryUtils { try { if (scorer == null) { Weight w = q.weight(s); - scorer = w.scorer(context[leafPtr], true, false); + scorer = w.scorer(readerContextArray[leafPtr], true, false); } int op = order[(opidx[0]++) % order.length]; @@ -303,7 +303,7 @@ public class QueryUtils { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { // confirm that skipping beyond the last doc, on the // previous reader, hits NO_MORE_DOCS if (lastReader[0] != null) { @@ -317,8 +317,8 @@ public class QueryUtils { } leafPtr++; } - lastReader[0] = reader; - assert context[leafPtr].reader == reader; + lastReader[0] = context.reader; + assert readerContextArray[leafPtr].reader == context.reader; this.scorer = null; lastDoc[0] = -1; } @@ -385,7 +385,7 @@ public class QueryUtils { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { // confirm that skipping beyond the last doc, on the // previous reader, hits NO_MORE_DOCS if (lastReader[0] != null) { @@ -400,7 +400,7 @@ public class QueryUtils { leafPtr++; } - lastReader[0] = reader; + lastReader[0] = context.reader; lastDoc[0] = -1; } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestConstantScoreQuery.java b/lucene/src/test/org/apache/lucene/search/TestConstantScoreQuery.java index 874fc7f3a14..5849d57354f 100644 --- a/lucene/src/test/org/apache/lucene/search/TestConstantScoreQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestConstantScoreQuery.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -68,7 +69,7 @@ public class TestConstantScoreQuery extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) { + public void setNextReader(AtomicReaderContext context) { } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestDocBoost.java b/lucene/src/test/org/apache/lucene/search/TestDocBoost.java index 2555896ac1d..c222d632bbd 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDocBoost.java +++ b/lucene/src/test/org/apache/lucene/search/TestDocBoost.java @@ -22,6 +22,7 @@ import java.io.IOException; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.document.*; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -77,8 +78,8 @@ public class TestDocBoost extends LuceneTestCase { scores[doc + base] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/TestElevationComparator.java b/lucene/src/test/org/apache/lucene/search/TestElevationComparator.java index a99d2d0122b..a9eab85cc97 100644 --- a/lucene/src/test/org/apache/lucene/search/TestElevationComparator.java +++ b/lucene/src/test/org/apache/lucene/search/TestElevationComparator.java @@ -21,6 +21,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldValueHitQueue.Entry; import org.apache.lucene.store.*; import org.apache.lucene.util.LuceneTestCase; @@ -177,8 +178,8 @@ class ElevationComparatorSource extends FieldComparatorSource { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - idIndex = FieldCache.DEFAULT.getTermsIndex(reader, fieldname); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + idIndex = FieldCache.DEFAULT.getTermsIndex(context.reader, fieldname); return this; } diff --git a/lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java b/lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java index 7fc8ea6a799..f62d29620ae 100644 --- a/lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java +++ b/lucene/src/test/org/apache/lucene/search/TestMultiTermConstantScore.java @@ -22,6 +22,7 @@ import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -197,8 +198,8 @@ public class TestMultiTermConstantScore extends BaseTestRangeFilter { assertEquals("score for doc " + (doc + base) + " was not correct", 1.0f, scorer.score()); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java b/lucene/src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java index 69ae819c73d..a6ba9f61079 100644 --- a/lucene/src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestScoreCachingWrappingScorer.java @@ -19,7 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.LuceneTestCase; public class TestScoreCachingWrappingScorer extends LuceneTestCase { @@ -76,7 +76,7 @@ public class TestScoreCachingWrappingScorer extends LuceneTestCase { ++idx; } - @Override public void setNextReader(IndexReader reader, int docBase) + @Override public void setNextReader(AtomicReaderContext context) throws IOException { } diff --git a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java index 55c4042eca0..1fc436f8b3b 100755 --- a/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java +++ b/lucene/src/test/org/apache/lucene/search/TestScorerPerf.java @@ -6,7 +6,6 @@ import org.apache.lucene.util.LuceneTestCase; import java.util.BitSet; import java.io.IOException; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; @@ -110,8 +109,8 @@ public class TestScorerPerf extends LuceneTestCase { public int getSum() { return sum; } @Override - public void setNextReader(IndexReader reader, int base) { - docBase = base; + public void setNextReader(AtomicReaderContext context) { + docBase = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/TestSetNorm.java b/lucene/src/test/org/apache/lucene/search/TestSetNorm.java index a117ee30c6b..b730fce8a91 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSetNorm.java +++ b/lucene/src/test/org/apache/lucene/search/TestSetNorm.java @@ -23,6 +23,7 @@ import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.*; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -74,8 +75,8 @@ public class TestSetNorm extends LuceneTestCase { scores[doc + base] = scorer.score(); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/TestSimilarity.java b/lucene/src/test/org/apache/lucene/search/TestSimilarity.java index fd459103777..c425ef504f6 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSimilarity.java +++ b/lucene/src/test/org/apache/lucene/search/TestSimilarity.java @@ -23,6 +23,7 @@ import java.util.Collection; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; @@ -94,7 +95,7 @@ public class TestSimilarity extends LuceneTestCase { assertEquals(1.0f, scorer.score()); } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; @@ -118,8 +119,8 @@ public class TestSimilarity extends LuceneTestCase { assertEquals((float)doc+base+1, scorer.score()); } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { @@ -144,7 +145,7 @@ public class TestSimilarity extends LuceneTestCase { assertEquals(1.0f, scorer.score()); } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; @@ -165,7 +166,7 @@ public class TestSimilarity extends LuceneTestCase { assertEquals(2.0f, scorer.score()); } @Override - public void setNextReader(IndexReader reader, int docBase) {} + public void setNextReader(AtomicReaderContext context) {} @Override public boolean acceptsDocsOutOfOrder() { return true; diff --git a/lucene/src/test/org/apache/lucene/search/TestSort.java b/lucene/src/test/org/apache/lucene/search/TestSort.java index 32b58632374..9a5db0d1053 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSort.java +++ b/lucene/src/test/org/apache/lucene/search/TestSort.java @@ -506,8 +506,8 @@ public class TestSort extends LuceneTestCase implements Serializable { } @Override - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - docValues = FieldCache.DEFAULT.getInts(reader, "parser", new FieldCache.IntParser() { + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + docValues = FieldCache.DEFAULT.getInts(context.reader, "parser", new FieldCache.IntParser() { public final int parseInt(final BytesRef term) { return (term.bytes[term.offset]-'A') * 123456; } diff --git a/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java b/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java index 4c2b05cb8fa..c5a3369f563 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java +++ b/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import org.apache.lucene.document.*; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.*; import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.Scorer.ScorerVisitor; @@ -126,10 +127,10 @@ public class TestSubScorerFreqs extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { this.docBase = docBase; - other.setNextReader(reader, docBase); + other.setNextReader(context); } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java index 139df5077eb..05c34758f56 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java @@ -98,8 +98,8 @@ public class TestTermScorer extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) { - base = docBase; + public void setNextReader(AtomicReaderContext context) { + base = context.docBase; } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java b/lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java index 53d2deaa6b2..d31fd21d05e 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java +++ b/lucene/src/test/org/apache/lucene/search/TestTimeLimitingCollector.java @@ -24,6 +24,7 @@ import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.search.TimeLimitingCollector.TimeExceededException; @@ -339,8 +340,8 @@ public class TestTimeLimitingCollector extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int base) { - docBase = base; + public void setNextReader(AtomicReaderContext context) { + docBase = context.docBase; } @Override diff --git a/lucene/src/test/org/apache/lucene/search/TestTopDocsCollector.java b/lucene/src/test/org/apache/lucene/search/TestTopDocsCollector.java index 348dfc30166..21164680661 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTopDocsCollector.java +++ b/lucene/src/test/org/apache/lucene/search/TestTopDocsCollector.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -60,9 +61,9 @@ public class TestTopDocsCollector extends LuceneTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) + public void setNextReader(AtomicReaderContext context) throws IOException { - base = docBase; + base = context.docBase; } @Override diff --git a/solr/src/java/org/apache/solr/handler/component/QueryComponent.java b/solr/src/java/org/apache/solr/handler/component/QueryComponent.java index b5e133ec58b..18bbf49deec 100644 --- a/solr/src/java/org/apache/solr/handler/component/QueryComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/QueryComponent.java @@ -18,10 +18,13 @@ package org.apache.solr.handler.component; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.*; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.ReaderUtil; import org.apache.solr.cloud.CloudDescriptor; import org.apache.solr.cloud.ZkController; import org.apache.solr.common.SolrDocument; @@ -444,23 +447,21 @@ public class QueryComponent extends SearchComponent SortField[] sortFields = sort==null ? new SortField[]{SortField.FIELD_SCORE} : sort.getSort(); NamedList sortVals = new NamedList(); // order is important for the sort fields Field field = new Field("dummy", "", Field.Store.YES, Field.Index.NO); // a dummy Field - - SolrIndexReader reader = searcher.getReader(); - SolrIndexReader[] readers = reader.getLeafReaders(); - SolrIndexReader subReader = reader; - if (readers.length==1) { + ReaderContext topReaderContext = searcher.getTopReaderContext(); + AtomicReaderContext[] leaves = ReaderUtil.leaves(topReaderContext); + AtomicReaderContext currentLeaf = null; + if (leaves.length==1) { // if there is a single segment, use that subReader and avoid looking up each time - subReader = readers[0]; - readers=null; + currentLeaf = leaves[0]; + leaves=null; } - int[] offsets = reader.getLeafOffsets(); for (SortField sortField: sortFields) { int type = sortField.getType(); if (type==SortField.SCORE || type==SortField.DOC) continue; FieldComparator comparator = null; - FieldComparator comparators[] = (readers==null) ? null : new FieldComparator[readers.length]; + FieldComparator comparators[] = (leaves==null) ? null : new FieldComparator[leaves.length]; String fieldname = sortField.getField(); FieldType ft = fieldname==null ? null : req.getSchema().getFieldTypeNoEx(fieldname); @@ -469,26 +470,24 @@ public class QueryComponent extends SearchComponent ArrayList vals = new ArrayList(docList.size()); DocIterator it = rb.getResults().docList.iterator(); - int offset = 0; int idx = 0; while(it.hasNext()) { int doc = it.nextDoc(); - if (readers != null) { - idx = SolrIndexReader.readerIndex(doc, offsets); - subReader = readers[idx]; - offset = offsets[idx]; + if (leaves != null) { + idx = ReaderUtil.subIndex(doc, leaves); + currentLeaf = leaves[idx]; comparator = comparators[idx]; } if (comparator == null) { comparator = sortField.getComparator(1,0); - comparator = comparator.setNextReader(subReader, offset); + comparator = comparator.setNextReader(currentLeaf); if (comparators != null) comparators[idx] = comparator; } - doc -= offset; // adjust for what segment this is in + doc -= currentLeaf.docBase; // adjust for what segment this is in comparator.copy(0, doc); Object val = comparator.value(0); diff --git a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java index 00eeb73c7a0..65061e231b0 100644 --- a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java @@ -43,6 +43,7 @@ import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.util.StringHelper; @@ -503,8 +504,8 @@ class ElevationComparatorSource extends FieldComparatorSource { values[slot] = docVal(doc); } - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - idIndex = FieldCache.DEFAULT.getTermsIndex(reader, fieldname); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + idIndex = FieldCache.DEFAULT.getTermsIndex(context.reader, fieldname); return this; } diff --git a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java index ee2e51f1f51..9fc48b352bb 100644 --- a/solr/src/java/org/apache/solr/handler/component/TermsComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/TermsComponent.java @@ -27,7 +27,6 @@ import org.apache.solr.common.util.StrUtils; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.StrField; import org.apache.solr.request.SimpleFacets.CountPair; -import org.apache.solr.search.SolrIndexReader; import org.apache.solr.util.BoundedTreeSet; import org.apache.solr.client.solrj.response.TermsResponse; @@ -103,8 +102,8 @@ public class TermsComponent extends SearchComponent { boolean raw = params.getBool(TermsParams.TERMS_RAW, false); - SolrIndexReader sr = rb.req.getSearcher().getReader(); - Fields lfields = MultiFields.getFields(sr); + final IndexReader indexReader = rb.req.getSearcher().getTopReaderContext().reader; + Fields lfields = MultiFields.getFields(indexReader); for (String field : fields) { NamedList fieldTerms = new NamedList(); diff --git a/solr/src/java/org/apache/solr/schema/RandomSortField.java b/solr/src/java/org/apache/solr/schema/RandomSortField.java index 1a2891f8ecc..848e8206f9d 100644 --- a/solr/src/java/org/apache/solr/schema/RandomSortField.java +++ b/solr/src/java/org/apache/solr/schema/RandomSortField.java @@ -22,6 +22,7 @@ import java.util.Map; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; @@ -89,7 +90,7 @@ public class RandomSortField extends FieldType { // we use the top-level reader. return fieldName.hashCode() + base + (int)top.getVersion(); } - + @Override public SortField getSortField(SchemaField field, boolean reverse) { return new SortField(field.getName(), randomComparatorSource, reverse); @@ -127,8 +128,8 @@ public class RandomSortField extends FieldType { values[slot] = hash(doc+seed); } - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - seed = getSeed(fieldname, reader); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + seed = getSeed(fieldname, context.reader); return this; } diff --git a/solr/src/java/org/apache/solr/search/DocSetHitCollector.java b/solr/src/java/org/apache/solr/search/DocSetHitCollector.java index ad32295e169..c0067a74380 100644 --- a/solr/src/java/org/apache/solr/search/DocSetHitCollector.java +++ b/solr/src/java/org/apache/solr/search/DocSetHitCollector.java @@ -20,7 +20,7 @@ package org.apache.solr.search; import org.apache.lucene.search.Collector; import org.apache.lucene.search.Scorer; import org.apache.lucene.util.OpenBitSet; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; @@ -80,8 +80,8 @@ class DocSetCollector extends Collector { public void setScorer(Scorer scorer) throws IOException { } - public void setNextReader(IndexReader reader, int docBase) throws IOException { - this.base = docBase; + public void setNextReader(AtomicReaderContext context) throws IOException { + this.base = context.docBase; } public boolean acceptsDocsOutOfOrder() { @@ -135,8 +135,8 @@ class DocSetDelegateCollector extends DocSetCollector { collector.setScorer(scorer); } - public void setNextReader(IndexReader reader, int docBase) throws IOException { - collector.setNextReader(reader, docBase); - this.base = docBase; + public void setNextReader(AtomicReaderContext context) throws IOException { + collector.setNextReader(context); + this.base = context.docBase; } } diff --git a/solr/src/java/org/apache/solr/search/Grouping.java b/solr/src/java/org/apache/solr/search/Grouping.java index c46d25ea4b5..bc7e858c2ac 100755 --- a/solr/src/java/org/apache/solr/search/Grouping.java +++ b/solr/src/java/org/apache/solr/search/Grouping.java @@ -17,7 +17,7 @@ package org.apache.solr.search; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; import org.apache.lucene.util.BytesRef; import org.apache.solr.common.util.NamedList; @@ -457,14 +457,15 @@ class FilterCollector extends GroupCollector { @Override public void collect(int doc) throws IOException { matches++; - if (filter.exists(doc + docBase)) + if (filter.exists(doc + docBase)) { collector.collect(doc); + } } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - this.docBase = docBase; - collector.setNextReader(reader, docBase); + public void setNextReader(AtomicReaderContext context) throws IOException { + docBase = context.docBase; + collector.setNextReader(context); } @Override @@ -685,13 +686,13 @@ class TopGroupCollector extends GroupCollector { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - this.docBase = docBase; - docValues = vs.getValues(context, reader); + public void setNextReader(AtomicReaderContext readerContext) throws IOException { + this.docBase = readerContext.docBase; + docValues = vs.getValues(context, readerContext.reader); filler = docValues.getValueFiller(); mval = filler.getValue(); for (int i=0; i topscore[0]) topscore[0]=score; } - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { } public boolean acceptsDocsOutOfOrder() { return true; @@ -1249,7 +1248,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { float score = scorer.score(); if (score > topscore[0]) topscore[0]=score; } - public void setNextReader(IndexReader reader, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext context) throws IOException { } public boolean acceptsDocsOutOfOrder() { return false; @@ -1570,21 +1569,21 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { int base=0; int end=0; int readerIndex = -1; - SolrIndexReader r=null; + + AtomicReaderContext leaf = null; - - while(iter.hasNext()) { + for (int i = 0; i < leafContexts.length; i++) { int doc = iter.nextDoc(); while (doc>=end) { - r = reader.getLeafReaders()[++readerIndex]; - base = reader.getLeafOffsets()[readerIndex]; - end = base + r.maxDoc(); - topCollector.setNextReader(r, base); + leaf = leafContexts[i++]; + base = leaf.docBase; + end = base + leaf.reader.maxDoc(); + topCollector.setNextReader(leaf); // we should never need to set the scorer given the settings for the collector } topCollector.collect(doc-base); } - + TopDocs topDocs = topCollector.topDocs(0, nDocs); int nDocsReturned = topDocs.scoreDocs.length; diff --git a/solr/src/java/org/apache/solr/search/function/ValueSource.java b/solr/src/java/org/apache/solr/search/function/ValueSource.java index 80f61f6018d..9c1ac9724c3 100644 --- a/solr/src/java/org/apache/solr/search/function/ValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/ValueSource.java @@ -187,8 +187,8 @@ public abstract class ValueSource implements Serializable { values[slot] = docVals.doubleVal(doc); } - public FieldComparator setNextReader(IndexReader reader, int docBase) throws IOException { - docVals = getValues(Collections.emptyMap(), reader); + public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { + docVals = getValues(Collections.emptyMap(), context.reader); return this; } diff --git a/solr/src/java/org/apache/solr/update/UpdateHandler.java b/solr/src/java/org/apache/solr/update/UpdateHandler.java index 4280b77f37a..72377f2eaf1 100644 --- a/solr/src/java/org/apache/solr/update/UpdateHandler.java +++ b/solr/src/java/org/apache/solr/update/UpdateHandler.java @@ -18,7 +18,7 @@ package org.apache.solr.update; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -167,7 +167,7 @@ public abstract class UpdateHandler implements SolrInfoMBean { } @Override - public void setNextReader(IndexReader arg0, int docBase) throws IOException { + public void setNextReader(AtomicReaderContext arg0) throws IOException { this.docBase = docBase; } diff --git a/solr/src/test/org/apache/solr/search/TestDocSet.java b/solr/src/test/org/apache/solr/search/TestDocSet.java index 25eda5c9259..1e8d1377ee8 100644 --- a/solr/src/test/org/apache/solr/search/TestDocSet.java +++ b/solr/src/test/org/apache/solr/search/TestDocSet.java @@ -406,7 +406,7 @@ public class TestDocSet extends LuceneTestCase { } } - public void doFilterTest(SolrIndexReader reader) throws IOException { + public void doFilterTest(IndexReader reader) throws IOException { ReaderContext topLevelContext = reader.getTopReaderContext(); OpenBitSet bs = getRandomSet(reader.maxDoc(), rand.nextInt(reader.maxDoc()+1)); DocSet a = new BitDocSet(bs); @@ -450,8 +450,7 @@ public class TestDocSet extends LuceneTestCase { for (int i=0; i<5000; i++) { IndexReader r = dummyMultiReader(maxSeg, maxDoc); - SolrIndexReader sir = new SolrIndexReader(r, null, 0); - doFilterTest(sir); + doFilterTest(r); } } } diff --git a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java index 4ecd72df623..0b5e114c257 100755 --- a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java +++ b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java @@ -16,6 +16,9 @@ */ package org.apache.solr.search; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.util.ReaderUtil; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.schema.SchemaField; @@ -38,12 +41,12 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { ValueSource vs = sf.getType().getValueSource(sf, null); Map context = ValueSource.newContext(sqr.getSearcher()); vs.createWeight(context, sqr.getSearcher()); - SolrIndexReader sr = sqr.getSearcher().getReader(); - int idx = SolrIndexReader.readerIndex(doc, sr.getLeafOffsets()); - int base = sr.getLeafOffsets()[idx]; - SolrIndexReader sub = sr.getLeafReaders()[idx]; - DocValues vals = vs.getValues(context, sub); - return vals.strVal(doc-base); + ReaderContext topReaderContext = sqr.getSearcher().getTopReaderContext(); + AtomicReaderContext[] leaves = ReaderUtil.leaves(topReaderContext); + int idx = ReaderUtil.subIndex(doc, leaves); + AtomicReaderContext leaf = leaves[idx]; + DocValues vals = vs.getValues(context, leaf.reader); + return vals.strVal(doc-leaf.docBase); } public void testReopen() throws Exception { @@ -53,7 +56,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { assertU(commit()); SolrQueryRequest sr1 = req("q","foo"); - SolrIndexReader r1 = sr1.getSearcher().getReader(); + ReaderContext rCtx1 = sr1.getSearcher().getTopReaderContext(); String sval1 = getStringVal(sr1, "v_s",0); assertEquals("string1", sval1); @@ -63,33 +66,33 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { assertU(commit()); SolrQueryRequest sr2 = req("q","foo"); - SolrIndexReader r2 = sr2.getSearcher().getReader(); + ReaderContext rCtx2 = sr2.getSearcher().getTopReaderContext(); // make sure the readers share the first segment // Didn't work w/ older versions of lucene2.9 going from segment -> multi - assertEquals(r1.getLeafReaders()[0], r2.getLeafReaders()[0]); + assertEquals(ReaderUtil.leaves(rCtx1)[0].reader, ReaderUtil.leaves(rCtx2)[0].reader); assertU(adoc("id","5", "v_f","3.14159")); assertU(adoc("id","6", "v_f","8983", "v_s","string6")); assertU(commit()); SolrQueryRequest sr3 = req("q","foo"); - SolrIndexReader r3 = sr3.getSearcher().getReader(); + ReaderContext rCtx3 = sr3.getSearcher().getTopReaderContext(); // make sure the readers share segments // assertEquals(r1.getLeafReaders()[0], r3.getLeafReaders()[0]); - assertEquals(r2.getLeafReaders()[0], r3.getLeafReaders()[0]); - assertEquals(r2.getLeafReaders()[1], r3.getLeafReaders()[1]); + assertEquals(ReaderUtil.leaves(rCtx2)[0].reader, ReaderUtil.leaves(rCtx3)[0].reader); + assertEquals(ReaderUtil.leaves(rCtx2)[1].reader, ReaderUtil.leaves(rCtx3)[1].reader); sr1.close(); sr2.close(); // should currently be 1, but this could change depending on future index management - int baseRefCount = r3.getRefCount(); + int baseRefCount = rCtx3.reader.getRefCount(); assertEquals(1, baseRefCount); assertU(commit()); SolrQueryRequest sr4 = req("q","foo"); - SolrIndexReader r4 = sr4.getSearcher().getReader(); + ReaderContext rCtx4 = sr4.getSearcher().getTopReaderContext(); // force an index change so the registered searcher won't be the one we are testing (and // then we should be able to test the refCount going all the way to 0 @@ -97,23 +100,23 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { assertU(commit()); // test that reader didn't change (according to equals at least... which uses the wrapped reader) - assertEquals(r3,r4); - assertEquals(baseRefCount+1, r4.getRefCount()); + assertEquals(rCtx3.reader, rCtx4.reader); + assertEquals(baseRefCount+1, rCtx4.reader.getRefCount()); sr3.close(); - assertEquals(baseRefCount, r4.getRefCount()); + assertEquals(baseRefCount, rCtx4.reader.getRefCount()); sr4.close(); - assertEquals(baseRefCount-1, r4.getRefCount()); + assertEquals(baseRefCount-1, rCtx4.reader.getRefCount()); SolrQueryRequest sr5 = req("q","foo"); - SolrIndexReader r5 = sr5.getSearcher().getReader(); + ReaderContext rCtx5 = sr5.getSearcher().getTopReaderContext(); assertU(delI("1")); assertU(commit()); SolrQueryRequest sr6 = req("q","foo"); - SolrIndexReader r6 = sr6.getSearcher().getReader(); - assertEquals(1, r6.getLeafReaders()[0].numDocs()); // only a single doc left in the first segment - assertTrue( !r5.getLeafReaders()[0].equals(r6.getLeafReaders()[0]) ); // readers now different + ReaderContext rCtx6 = sr6.getSearcher().getTopReaderContext(); + assertEquals(1, ReaderUtil.leaves(rCtx6)[0].reader.numDocs()); // only a single doc left in the first segment + assertTrue( !ReaderUtil.leaves(rCtx5)[0].reader.equals(ReaderUtil.leaves(rCtx6)[0].reader) ); // readers now different sr5.close(); sr6.close(); diff --git a/solr/src/test/org/apache/solr/search/TestSort.java b/solr/src/test/org/apache/solr/search/TestSort.java index c4b0c1450c7..2fe21743973 100755 --- a/solr/src/test/org/apache/solr/search/TestSort.java +++ b/solr/src/test/org/apache/solr/search/TestSort.java @@ -20,7 +20,6 @@ package org.apache.solr.search; import org.apache.lucene.analysis.core.SimpleAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; -import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; @@ -160,9 +159,9 @@ public class TestSort extends AbstractSolrTestCase { } @Override - public void setNextReader(IndexReader reader, int docBase) throws IOException { - topCollector.setNextReader(reader,docBase); - this.docBase = docBase; + public void setNextReader(AtomicReaderContext context) throws IOException { + topCollector.setNextReader(context); + docBase = context.docBase; } @Override diff --git a/solr/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java b/solr/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java index dbe1c512ae0..242ea064b3d 100644 --- a/solr/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java +++ b/solr/src/test/org/apache/solr/update/DirectUpdateHandlerTest.java @@ -20,18 +20,13 @@ package org.apache.solr.update; import java.util.HashMap; import java.util.Map; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.IndexReader; import org.apache.solr.SolrTestCaseJ4; -import org.apache.solr.common.SolrException; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.MapSolrParams; import org.apache.solr.core.SolrCore; import org.apache.solr.request.LocalSolrQueryRequest; import org.apache.solr.request.SolrQueryRequest; -import org.apache.solr.search.SolrIndexReader; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -243,7 +238,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 { assertU(commit()); SolrQueryRequest sr = req("q","foo"); - SolrIndexReader r = sr.getSearcher().getReader(); + IndexReader r = sr.getSearcher().getTopReaderContext().reader; assertTrue(r.maxDoc() > r.numDocs()); // should have deletions assertFalse(r.getTopReaderContext().isAtomic); // more than 1 segment sr.close(); @@ -251,7 +246,7 @@ public class DirectUpdateHandlerTest extends SolrTestCaseJ4 { assertU(commit("expungeDeletes","true")); sr = req("q","foo"); - r = sr.getSearcher().getReader(); + r = sr.getSearcher().getTopReaderContext().reader; assertEquals(r.maxDoc(), r.numDocs()); // no deletions assertEquals(4,r.maxDoc()); // no dups assertFalse(r.getTopReaderContext().isAtomic); //still more than 1 segment From 76c3de6ece2a981e4461fb8ece43ed8b54a9f760 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 11:15:07 +0000 Subject: [PATCH 046/252] fixed wrong self assignments for 'docBase' in Collector subclasses introduced in rev. 1058019 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058076 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/lucene/index/TestFieldNormModifier.java | 6 +++--- .../test/org/apache/lucene/misc/TestLengthNormModifier.java | 4 ++-- .../lucene/queryParser/surround/query/BooleanQueryTst.java | 2 +- .../java/org/apache/lucene/search/TopFieldCollector.java | 2 +- lucene/src/test/org/apache/lucene/index/TestOmitTf.java | 2 +- .../test/org/apache/lucene/search/TestSubScorerFreqs.java | 2 +- solr/src/java/org/apache/solr/update/UpdateHandler.java | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java index bdc386cefcd..345e86c4092 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/index/TestFieldNormModifier.java @@ -124,7 +124,7 @@ public class TestFieldNormModifier extends LuceneTestCase { } @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public void setScorer(Scorer scorer) throws IOException { @@ -159,7 +159,7 @@ public class TestFieldNormModifier extends LuceneTestCase { } @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public void setScorer(Scorer scorer) throws IOException { @@ -211,7 +211,7 @@ public class TestFieldNormModifier extends LuceneTestCase { } @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public void setScorer(Scorer scorer) throws IOException { diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java index 7646bd1d531..06fb554c632 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestLengthNormModifier.java @@ -141,7 +141,7 @@ public class TestLengthNormModifier extends LuceneTestCase { } @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public void setScorer(Scorer scorer) throws IOException { @@ -183,7 +183,7 @@ public class TestLengthNormModifier extends LuceneTestCase { } @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public void setScorer(Scorer scorer) throws IOException { diff --git a/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java b/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java index 325db2637e1..bba9321f3b4 100644 --- a/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java +++ b/lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/surround/query/BooleanQueryTst.java @@ -78,7 +78,7 @@ public class BooleanQueryTst { @Override public void setNextReader(AtomicReaderContext context) throws IOException { - this.docBase = docBase; + docBase = context.docBase; } @Override diff --git a/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java index 05e178d3115..bc10124e90c 100644 --- a/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java +++ b/lucene/src/java/org/apache/lucene/search/TopFieldCollector.java @@ -448,7 +448,7 @@ public abstract class TopFieldCollector extends TopDocsCollector { @Override public void setNextReader(AtomicReaderContext context) throws IOException { - this.docBase = context.docBase; + docBase = context.docBase; for (int i = 0; i < comparators.length; i++) { queue.setComparator(i, comparators[i].setNextReader(context)); } diff --git a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java index 21968df695b..be29150b09a 100644 --- a/lucene/src/test/org/apache/lucene/index/TestOmitTf.java +++ b/lucene/src/test/org/apache/lucene/index/TestOmitTf.java @@ -416,7 +416,7 @@ public class TestOmitTf extends LuceneTestCase { @Override public void setNextReader(AtomicReaderContext context) { - this.docBase = docBase; + docBase = context.docBase; } @Override public boolean acceptsDocsOutOfOrder() { diff --git a/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java b/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java index c5a3369f563..ada6dc1ffd4 100644 --- a/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java +++ b/lucene/src/test/org/apache/lucene/search/TestSubScorerFreqs.java @@ -129,7 +129,7 @@ public class TestSubScorerFreqs extends LuceneTestCase { @Override public void setNextReader(AtomicReaderContext context) throws IOException { - this.docBase = docBase; + docBase = context.docBase; other.setNextReader(context); } diff --git a/solr/src/java/org/apache/solr/update/UpdateHandler.java b/solr/src/java/org/apache/solr/update/UpdateHandler.java index 72377f2eaf1..7e06a2739fe 100644 --- a/solr/src/java/org/apache/solr/update/UpdateHandler.java +++ b/solr/src/java/org/apache/solr/update/UpdateHandler.java @@ -167,8 +167,8 @@ public abstract class UpdateHandler implements SolrInfoMBean { } @Override - public void setNextReader(AtomicReaderContext arg0) throws IOException { - this.docBase = docBase; + public void setNextReader(AtomicReaderContext context) throws IOException { + docBase = context.docBase; } @Override From 121b79e7e5108db636cec1782b5436c2191ad4c8 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 13:27:38 +0000 Subject: [PATCH 047/252] fixed testcase which failed with -Dtests.multiplier > 1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058131 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/spelling/SpellPossibilityIteratorTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/solr/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java b/solr/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java index 34a950950c3..1cb7b040307 100644 --- a/solr/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java +++ b/solr/src/test/org/apache/solr/spelling/SpellPossibilityIteratorTest.java @@ -22,16 +22,16 @@ import java.util.Map; import org.apache.lucene.analysis.Token; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.spelling.PossibilityIterator; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; public class SpellPossibilityIteratorTest extends SolrTestCaseJ4 { private static Map> suggestions = new LinkedHashMap>(); - @BeforeClass - public static void beforeClass() throws Exception { - + @Before + public void setUp() throws Exception { + super.setUp(); suggestions.clear(); LinkedHashMap AYE = new LinkedHashMap(); @@ -72,7 +72,7 @@ public class SpellPossibilityIteratorTest extends SolrTestCaseJ4 { suggestions.put(new Token("BEE", 0, 2), BEE); suggestions.put(new Token("CEE", 0, 2), CEE); } - + @Test public void testSpellPossibilityIterator() throws Exception { PossibilityIterator iter = new PossibilityIterator(suggestions); From 84af9e5b5e8c1db70677e194cdf8c50861363ff8 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 13:44:22 +0000 Subject: [PATCH 048/252] fixed testcase which failed with -Dtests.multiplier > 1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058138 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/solr/handler/TestReplicationHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solr/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/src/test/org/apache/solr/handler/TestReplicationHandler.java index a7670bd464b..addd3d445e1 100644 --- a/solr/src/test/org/apache/solr/handler/TestReplicationHandler.java +++ b/solr/src/test/org/apache/solr/handler/TestReplicationHandler.java @@ -520,7 +520,6 @@ public class TestReplicationHandler extends SolrTestCaseJ4 { @Test public void testBackup() throws Exception { - masterJetty.stop(); copyFile(getFile(CONF_DIR + "solrconfig-master1.xml"), new File(master.getConfDir(), "solrconfig.xml")); @@ -620,6 +619,7 @@ public class TestReplicationHandler extends SolrTestCaseJ4 { assertEquals(nDocs, hits.totalHits); searcher.close(); dir.close(); + AbstractSolrTestCase.recurseDelete(snapDir); // clean up the snap dir } /* character copy of file using UTF-8 */ From 466530addfc478c7aaf0448a5b60fdc196f92009 Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Wed, 12 Jan 2011 14:29:33 +0000 Subject: [PATCH 049/252] LUCENE-2860: port to trunk git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058155 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 +- .../org/apache/lucene/index/SegmentInfo.java | 44 ++++++++++------- .../apache/lucene/index/TestSegmentInfo.java | 48 +++++++++++++++++++ 3 files changed, 77 insertions(+), 18 deletions(-) create mode 100644 lucene/src/test/org/apache/lucene/index/TestSegmentInfo.java diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 888ed11b991..c0573de7544 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -379,7 +379,8 @@ Bug fixes to a mutable reference to the IndexWriters SegmentInfos. (Simon Willnauer, Earwin Burrfoot) - +* LUCENE-2860: Fixed SegmentInfo.sizeInBytes to factor includeDocStores when it + decides whether to return the cached computed size or not. (Shai Erera) ======================= Lucene 3.x (not yet released) ======================= diff --git a/lucene/src/java/org/apache/lucene/index/SegmentInfo.java b/lucene/src/java/org/apache/lucene/index/SegmentInfo.java index ff621277dd2..2c91efc636b 100644 --- a/lucene/src/java/org/apache/lucene/index/SegmentInfo.java +++ b/lucene/src/java/org/apache/lucene/index/SegmentInfo.java @@ -68,7 +68,8 @@ public final class SegmentInfo { private List files; // cached list of files that this segment uses // in the Directory - long sizeInBytes = -1; // total byte size of all of our files (computed on demand) + private long sizeInBytesNoStore = -1; // total byte size of all but the store files (computed on demand) + private long sizeInBytesWithStore = -1; // total byte size of all of our files (computed on demand) private int docStoreOffset; // if this segment shares stored fields & vectors, this // offset is where in that file this segment's docs begin @@ -217,26 +218,34 @@ public final class SegmentInfo { } } } - - /** Returns total size in bytes of all of files used by - * this segment. */ + + /** + * Returns total size in bytes of all of files used by this segment (if + * {@code includeDocStores} is true), or the size of all files except the + * store files otherwise. + */ public long sizeInBytes(boolean includeDocStores) throws IOException { - if (sizeInBytes == -1) { - List files = files(); - final int size = files.size(); - sizeInBytes = 0; - for(int i=0;i Date: Wed, 12 Jan 2011 15:20:22 +0000 Subject: [PATCH 051/252] SOLR-2282: revert the previous commit git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058180 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/handler/clustering/AbstractClusteringTestCase.java | 2 +- .../{solr => solr-clustering}/conf/mapping-ISOLatin1Accent.txt | 0 .../test/resources/{solr => solr-clustering}/conf/protwords.txt | 0 .../test/resources/{solr => solr-clustering}/conf/schema.xml | 0 .../resources/{solr => solr-clustering}/conf/solrconfig.xml | 0 .../test/resources/{solr => solr-clustering}/conf/spellings.txt | 0 .../test/resources/{solr => solr-clustering}/conf/stopwords.txt | 0 .../test/resources/{solr => solr-clustering}/conf/synonyms.txt | 0 8 files changed, 1 insertion(+), 1 deletion(-) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/mapping-ISOLatin1Accent.txt (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/protwords.txt (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/schema.xml (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/solrconfig.xml (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/spellings.txt (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/stopwords.txt (100%) rename solr/contrib/clustering/src/test/resources/{solr => solr-clustering}/conf/synonyms.txt (100%) diff --git a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/AbstractClusteringTestCase.java b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/AbstractClusteringTestCase.java index 6c4f42ee581..c4fec5e0a53 100644 --- a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/AbstractClusteringTestCase.java +++ b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/AbstractClusteringTestCase.java @@ -28,7 +28,7 @@ public abstract class AbstractClusteringTestCase extends SolrTestCaseJ4 { @BeforeClass public static void beforeClass() throws Exception { - initCore("solrconfig.xml", "schema.xml", "solr"); + initCore("solrconfig.xml", "schema.xml", "solr-clustering"); numberOfDocs = 0; for (String[] doc : DOCUMENTS) { assertNull(h.validateUpdate(adoc("id", Integer.toString(numberOfDocs), "url", doc[0], "title", doc[1], "snippet", doc[2]))); diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/mapping-ISOLatin1Accent.txt b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/mapping-ISOLatin1Accent.txt similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/mapping-ISOLatin1Accent.txt rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/mapping-ISOLatin1Accent.txt diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/protwords.txt b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/protwords.txt similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/protwords.txt rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/protwords.txt diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/schema.xml b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/schema.xml similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/schema.xml rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/schema.xml diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/solrconfig.xml b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/solrconfig.xml similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/solrconfig.xml rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/solrconfig.xml diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/spellings.txt b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/spellings.txt similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/spellings.txt rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/spellings.txt diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/stopwords.txt b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/stopwords.txt similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/stopwords.txt rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/stopwords.txt diff --git a/solr/contrib/clustering/src/test/resources/solr/conf/synonyms.txt b/solr/contrib/clustering/src/test/resources/solr-clustering/conf/synonyms.txt similarity index 100% rename from solr/contrib/clustering/src/test/resources/solr/conf/synonyms.txt rename to solr/contrib/clustering/src/test/resources/solr-clustering/conf/synonyms.txt From a04fe4c9a9a54edbdd9ef5ba691db8c3a11ed574 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 16:10:14 +0000 Subject: [PATCH 052/252] fixed testcase which failed with -Dtests.multiplier > 1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058214 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/cloud/AbstractZkTestCase.java | 17 +++++++++++++++++ .../org/apache/solr/cloud/ZkControllerTest.java | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/solr/src/test/org/apache/solr/cloud/AbstractZkTestCase.java b/solr/src/test/org/apache/solr/cloud/AbstractZkTestCase.java index e67436e2b24..31721ed2782 100644 --- a/solr/src/test/org/apache/solr/cloud/AbstractZkTestCase.java +++ b/solr/src/test/org/apache/solr/cloud/AbstractZkTestCase.java @@ -19,6 +19,7 @@ package org.apache.solr.cloud; import java.io.File; import java.io.IOException; +import java.util.List; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.cloud.SolrZkClient; @@ -126,4 +127,20 @@ public abstract class AbstractZkTestCase extends SolrTestCaseJ4 { zkClient.makePath("/solr"); zkClient.close(); } + + static void tryCleanSolrZkNode(String zkHost) throws Exception { + tryCleanPath(zkHost, "/solr"); + } + + static void tryCleanPath(String zkHost, String path) throws Exception { + SolrZkClient zkClient = new SolrZkClient(zkHost, TIMEOUT); + if (zkClient.exists(path)) { + List children = zkClient.getChildren(path, null); + for (String string : children) { + tryCleanPath(zkHost, path+"/"+string); + } + zkClient.delete(path, -1); + } + zkClient.close(); + } } diff --git a/solr/src/test/org/apache/solr/cloud/ZkControllerTest.java b/solr/src/test/org/apache/solr/cloud/ZkControllerTest.java index 785ea206c90..4cbbd9e062d 100644 --- a/solr/src/test/org/apache/solr/cloud/ZkControllerTest.java +++ b/solr/src/test/org/apache/solr/cloud/ZkControllerTest.java @@ -71,7 +71,7 @@ public class ZkControllerTest extends SolrTestCaseJ4 { try { server = new ZkTestServer(zkDir); server.run(); - + AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost()); AbstractZkTestCase.makeSolrZkNode(server.getZkHost()); zkClient = new SolrZkClient(server.getZkAddress(), TIMEOUT); From 6076f10d426c40b2905e91c5c8ea7d30dfc82f72 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 12 Jan 2011 19:25:24 +0000 Subject: [PATCH 053/252] report the basics of the environment when a test fails git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058284 13f79535-47bb-0310-9956-ffa450edef68 --- .../test/org/apache/lucene/util/LuceneTestCase.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java index f133f6ad0c4..ea2751406ee 100644 --- a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java @@ -1014,6 +1014,16 @@ public abstract class LuceneTestCase extends Assert { System.err.println("NOTE: reproduce with: ant test -Dtestcase=" + getClass().getSimpleName() + " -Dtestmethod=" + getName() + " -Dtests.seed=" + new TwoLongs(staticSeed, seed) + reproduceWithExtraParams()); + System.err.println("NOTE: " + System.getProperty("os.name") + " " + + System.getProperty("os.version") + " " + + System.getProperty("os.arch") + "/" + + System.getProperty("java.vendor") + " " + + System.getProperty("java.version") + " " + + (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") + "/" + + "cpus=" + Runtime.getRuntime().availableProcessors() + "," + + "threads=" + Thread.activeCount() + "," + + "free=" + Runtime.getRuntime().freeMemory() + "," + + "total=" + Runtime.getRuntime().totalMemory()); } // extra params that were overridden needed to reproduce the command From e3a854a1a37b3b1cf19a33475970705565be6e7a Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Wed, 12 Jan 2011 19:42:03 +0000 Subject: [PATCH 054/252] take 2: only report environment info once, even if multiple methods fail git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058288 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/util/LuceneTestCase.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java index ea2751406ee..80d99537fe4 100644 --- a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java @@ -390,6 +390,16 @@ public abstract class LuceneTestCase extends Assert { if (testsFailed) { System.err.println("NOTE: all tests run in this JVM:"); System.err.println(Arrays.toString(testClassesRun.toArray())); + System.err.println("NOTE: " + System.getProperty("os.name") + " " + + System.getProperty("os.version") + " " + + System.getProperty("os.arch") + "/" + + System.getProperty("java.vendor") + " " + + System.getProperty("java.version") + " " + + (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") + "/" + + "cpus=" + Runtime.getRuntime().availableProcessors() + "," + + "threads=" + Thread.activeCount() + "," + + "free=" + Runtime.getRuntime().freeMemory() + "," + + "total=" + Runtime.getRuntime().totalMemory()); } } @@ -1014,16 +1024,6 @@ public abstract class LuceneTestCase extends Assert { System.err.println("NOTE: reproduce with: ant test -Dtestcase=" + getClass().getSimpleName() + " -Dtestmethod=" + getName() + " -Dtests.seed=" + new TwoLongs(staticSeed, seed) + reproduceWithExtraParams()); - System.err.println("NOTE: " + System.getProperty("os.name") + " " - + System.getProperty("os.version") + " " - + System.getProperty("os.arch") + "/" - + System.getProperty("java.vendor") + " " - + System.getProperty("java.version") + " " - + (Constants.JRE_IS_64BIT ? "(64-bit)" : "(32-bit)") + "/" - + "cpus=" + Runtime.getRuntime().availableProcessors() + "," - + "threads=" + Thread.activeCount() + "," - + "free=" + Runtime.getRuntime().freeMemory() + "," - + "total=" + Runtime.getRuntime().totalMemory()); } // extra params that were overridden needed to reproduce the command From 72a78bb9395bf0b20410d372656f4fdb5eb5fa8d Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 12 Jan 2011 21:36:01 +0000 Subject: [PATCH 055/252] add verbosity for tests git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058324 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/test/org/apache/lucene/util/LuceneTestCase.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java index 80d99537fe4..8989142f80c 100644 --- a/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java +++ b/lucene/src/test/org/apache/lucene/util/LuceneTestCase.java @@ -1117,8 +1117,15 @@ public abstract class LuceneTestCase extends Assert { @Override protected void runChild(FrameworkMethod arg0, RunNotifier arg1) { - for (int i = 0; i < TEST_ITER; i++) + if (VERBOSE) { + System.out.println("\nNOTE: running test " + arg0.getName()); + } + for (int i = 0; i < TEST_ITER; i++) { + if (VERBOSE && TEST_ITER > 1) { + System.out.println("\nNOTE: running iter=" + (1+i) + " of " + TEST_ITER); + } super.runChild(arg0, arg1); + } } public LuceneTestCaseRunner(Class clazz) throws InitializationError { From 3df2f89d6c08e648b51d48c2b0ef01227683089f Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 12 Jan 2011 21:36:49 +0000 Subject: [PATCH 056/252] add verbosity to pulsing codec git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058327 13f79535-47bb-0310-9956-ffa450edef68 --- .../index/codecs/pulsing/PulsingPostingsWriterImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java index d8e67a2bc43..32f647d0adf 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java @@ -101,8 +101,8 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { // our parent calls setField whenever the field changes @Override public void setField(FieldInfo fieldInfo) { - //System.out.println("PW field=" + fieldInfo.name); omitTF = fieldInfo.omitTermFreqAndPositions; + //System.out.println("PW field=" + fieldInfo.name + " omitTF=" + omitTF); storePayloads = fieldInfo.storePayloads; wrappedPostingsWriter.setField(fieldInfo); } @@ -114,6 +114,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { if (pendingCount == pending.length) { push(); + //System.out.println("PW: wrapped.finishDoc"); wrappedPostingsWriter.finishDoc(); } @@ -269,7 +270,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { // Pushes pending positions to the wrapped codec private void push() throws IOException { - //System.out.println("PW now push @ " + pendingCount); + //System.out.println("PW now push @ " + pendingCount + " wrapped=" + wrappedPostingsWriter); assert pendingCount == pending.length; wrappedPostingsWriter.startTerm(); @@ -280,13 +281,17 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { for(Position pos : pending) { if (doc == null) { doc = pos; + //System.out.println("PW: wrapped.startDoc docID=" + doc.docID + " tf=" + doc.termFreq); wrappedPostingsWriter.startDoc(doc.docID, doc.termFreq); } else if (doc.docID != pos.docID) { assert pos.docID > doc.docID; + //System.out.println("PW: wrapped.finishDoc"); wrappedPostingsWriter.finishDoc(); doc = pos; + //System.out.println("PW: wrapped.startDoc docID=" + doc.docID + " tf=" + doc.termFreq); wrappedPostingsWriter.startDoc(doc.docID, doc.termFreq); } + //System.out.println("PW: wrapped.addPos pos=" + pos.pos); wrappedPostingsWriter.addPosition(pos.pos, pos.payload); } //wrappedPostingsWriter.finishDoc(); From eacfb5d6362143226c6c873fa6981b6213619c2a Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Wed, 12 Jan 2011 21:38:51 +0000 Subject: [PATCH 057/252] LUCENE-2694: Make MTQ rewrite + weight/scorer single pass git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058328 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 5 + .../instantiated/InstantiatedTermsEnum.java | 22 ++- .../lucene/index/memory/MemoryIndex.java | 21 ++- .../apache/lucene/index/BufferedDeletes.java | 1 - .../lucene/index/FilterIndexReader.java | 15 +- .../org/apache/lucene/index/IndexReader.java | 41 +++++ .../org/apache/lucene/index/MultiReader.java | 1 - .../apache/lucene/index/MultiTermsEnum.java | 7 - .../org/apache/lucene/index/OrdTermState.java | 33 ++++ .../org/apache/lucene/index/TermState.java | 47 ++++++ .../java/org/apache/lucene/index/Terms.java | 48 +++++- .../org/apache/lucene/index/TermsEnum.java | 67 ++++++-- .../index/codecs/PostingsReaderBase.java | 8 +- ...rmState.java => PrefixCodedTermState.java} | 37 ++--- .../index/codecs/PrefixCodedTermsReader.java | 75 +++++---- .../index/codecs/preflex/PreFlexFields.java | 6 +- .../pulsing/PulsingPostingsReaderImpl.java | 18 +-- .../codecs/sep/SepPostingsReaderImpl.java | 16 +- .../simpletext/SimpleTextFieldsReader.java | 9 +- .../standard/StandardPostingsReader.java | 34 ++-- .../search/ConstantScoreAutoRewrite.java | 63 +++++++- .../lucene/search/FilteredTermsEnum.java | 21 ++- .../apache/lucene/search/FuzzyTermsEnum.java | 15 +- .../apache/lucene/search/MultiTermQuery.java | 9 +- .../apache/lucene/search/ScoringRewrite.java | 35 +++-- .../lucene/search/TermCollectingRewrite.java | 33 ++-- .../org/apache/lucene/search/TermQuery.java | 82 +++++++--- .../apache/lucene/search/TopTermsRewrite.java | 30 ++-- .../search/cache/DocTermsIndexCreator.java | 21 ++- .../spans/SpanMultiTermQueryWrapper.java | 5 +- .../lucene/util/PerReaderTermState.java | 148 ++++++++++++++++++ .../org/apache/lucene/TestExternalCodecs.java | 5 +- .../org/apache/lucene/search/QueryUtils.java | 2 - .../lucene/util/automaton/fst/TestFSTs.java | 1 + .../apache/solr/request/UnInvertedField.java | 4 - 35 files changed, 756 insertions(+), 229 deletions(-) create mode 100644 lucene/src/java/org/apache/lucene/index/OrdTermState.java create mode 100644 lucene/src/java/org/apache/lucene/index/TermState.java rename lucene/src/java/org/apache/lucene/index/codecs/{TermState.java => PrefixCodedTermState.java} (54%) create mode 100644 lucene/src/java/org/apache/lucene/util/PerReaderTermState.java diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index c0573de7544..05b9e5c963c 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -359,6 +359,11 @@ Optimizations not seek backwards when a sub-range has no terms. It now only seeks when the current term is less than the next sub-range's lower end. (Uwe Schindler, Mike McCandless) + +* LUCENE-2694: Optimize MultiTermQuery to be single pass for Term lookups. + MultiTermQuery now stores TermState per leaf reader during rewrite to re- + seek the term dictionary in TermQuery / TermWeight. + (Simon Willnauer, Mike McCandless, Robert Muir) Documentation diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java index d5301529f37..0dd4ffc2803 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java @@ -18,10 +18,15 @@ package org.apache.lucene.store.instantiated; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.index.OrdTermState; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; +import org.apache.lucene.index.codecs.PrefixCodedTermState; + +import java.io.IOException; import java.util.Arrays; import java.util.Comparator; @@ -90,10 +95,6 @@ public class InstantiatedTermsEnum extends TermsEnum { } } - @Override - public void cacheCurrentTerm() { - } - @Override public BytesRef term() { return br; @@ -129,5 +130,18 @@ public class InstantiatedTermsEnum extends TermsEnum { public Comparator getComparator() { return BytesRef.getUTF8SortedAsUnicodeComparator(); } + + @Override + public TermState termState() throws IOException { + final OrdTermState state = new OrdTermState(); + state.ord = upto - start; + return state; + } + + @Override + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + assert state != null && state instanceof OrdTermState; + return seek(((OrdTermState)state).ord); // just use the ord for simplicity + } } diff --git a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index 07af85cb557..08e880bfe99 100644 --- a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -39,6 +39,8 @@ import org.apache.lucene.document.FieldSelector; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.OrdTermState; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.FieldsEnum; @@ -883,10 +885,6 @@ public class MemoryIndex implements Serializable { return br; } - @Override - public void cacheCurrentTerm() { - } - @Override public long ord() { return termUpto; @@ -917,8 +915,21 @@ public class MemoryIndex implements Serializable { public Comparator getComparator() { return BytesRef.getUTF8SortedAsUnicodeComparator(); } - } + @Override + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + assert state != null; + return this.seek(((OrdTermState)state).ord); + } + + @Override + public TermState termState() throws IOException { + OrdTermState ts = new OrdTermState(); + ts.ord = termUpto; + return ts; + } + } + private class MemoryDocsEnum extends DocsEnum { private ArrayIntList positions; private boolean hasNext; diff --git a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java index d41abb8af0d..936d9fd01f7 100644 --- a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java +++ b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java @@ -372,7 +372,6 @@ class BufferedDeletes { Query query = entry.getKey(); int limit = entry.getValue().intValue(); Weight weight = query.weight(searcher); - Scorer scorer = weight.scorer(readerContext, true, false); if (scorer != null) { while(true) { diff --git a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java index aa18fcdb51f..8246fe4894d 100644 --- a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java @@ -130,11 +130,6 @@ public class FilterIndexReader extends IndexReader { return in.seek(text, useCache); } - @Override - public void cacheCurrentTerm() throws IOException { - in.cacheCurrentTerm(); - } - @Override public SeekStatus seek(long ord) throws IOException { return in.seek(ord); @@ -174,6 +169,16 @@ public class FilterIndexReader extends IndexReader { public Comparator getComparator() throws IOException { return in.getComparator(); } + + @Override + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + return in.seek(term, state); + } + + @Override + public TermState termState() throws IOException { + return in.termState(); + } } /** Base class for filtering {@link DocsEnum} implementations. */ diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index fb09bbc5917..6a23da780fc 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -1070,6 +1070,47 @@ public abstract class IndexReader implements Cloneable,Closeable { return null; } } + + /** + * Returns {@link DocsEnum} for the specified field and + * {@link TermState}. This may return null, if either the field or the term + * does not exists or the {@link TermState} is invalid for the underlying + * implementation.*/ + public DocsEnum termDocsEnum(Bits skipDocs, String field, BytesRef term, TermState state) throws IOException { + assert state != null; + assert field != null; + final Fields fields = fields(); + if (fields == null) { + return null; + } + final Terms terms = fields.terms(field); + if (terms != null) { + return terms.docs(skipDocs, term, state, null); + } else { + return null; + } + } + + /** + * Returns {@link DocsAndPositionsEnum} for the specified field and + * {@link TermState}. This may return null, if either the field or the term + * does not exists, the {@link TermState} is invalid for the underlying + * implementation, or positions were not stored for this term.*/ + public DocsAndPositionsEnum termPositionsEnum(Bits skipDocs, String field, BytesRef term, TermState state) throws IOException { + assert state != null; + assert field != null; + final Fields fields = fields(); + if (fields == null) { + return null; + } + final Terms terms = fields.terms(field); + if (terms != null) { + return terms.docsAndPositions(skipDocs, term, state, null); + } else { + return null; + } + } + /** Deletes the document numbered docNum. Once a document is * deleted it will not appear in TermDocs or TermPositions enumerations. diff --git a/lucene/src/java/org/apache/lucene/index/MultiReader.java b/lucene/src/java/org/apache/lucene/index/MultiReader.java index a519eeb6197..37328d1314a 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiReader.java +++ b/lucene/src/java/org/apache/lucene/index/MultiReader.java @@ -19,7 +19,6 @@ package org.apache.lucene.index; import java.io.IOException; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import org.apache.lucene.document.Document; diff --git a/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java b/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java index 02e21b17ffc..1f4794f3f9f 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java @@ -90,13 +90,6 @@ public final class MultiTermsEnum extends TermsEnum { return current; } - @Override - public void cacheCurrentTerm() throws IOException { - for(int i=0;i getComparator() { return termComp; diff --git a/lucene/src/java/org/apache/lucene/index/OrdTermState.java b/lucene/src/java/org/apache/lucene/index/OrdTermState.java new file mode 100644 index 00000000000..57c965796f0 --- /dev/null +++ b/lucene/src/java/org/apache/lucene/index/OrdTermState.java @@ -0,0 +1,33 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +/** + * An ordinal based {@link TermState} + * + * @lucene.experimental + */ +public class OrdTermState extends TermState { + public long ord; + + @Override + public void copyFrom(TermState other) { + assert other instanceof OrdTermState : "can not copy from " + other.getClass().getName(); + this.ord = ((OrdTermState) other).ord; + } +} diff --git a/lucene/src/java/org/apache/lucene/index/TermState.java b/lucene/src/java/org/apache/lucene/index/TermState.java new file mode 100644 index 00000000000..3279366b589 --- /dev/null +++ b/lucene/src/java/org/apache/lucene/index/TermState.java @@ -0,0 +1,47 @@ +package org.apache.lucene.index; + +/** + * 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. + */ + +/** + * Encapsulates all required internal state to position the associated + * {@link TermsEnum} without re-seeking. + * + * @see TermsEnum#seek(org.apache.lucene.util.BytesRef, TermState) + * @see TermsEnum#termState() + * @lucene.experimental + */ +public abstract class TermState implements Cloneable { + + /** + * Copies the content of the given {@link TermState} to this instance + * + * @param other + * the TermState to copy + */ + public abstract void copyFrom(TermState other); + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException cnse) { + // should not happen + throw new RuntimeException(cnse); + } + } +} \ No newline at end of file diff --git a/lucene/src/java/org/apache/lucene/index/Terms.java b/lucene/src/java/org/apache/lucene/index/Terms.java index 362476754f6..f562618d02a 100644 --- a/lucene/src/java/org/apache/lucene/index/Terms.java +++ b/lucene/src/java/org/apache/lucene/index/Terms.java @@ -80,11 +80,57 @@ public abstract class Terms { } } + /** + * Expert: Get {@link DocsEnum} for the specified {@link TermState}. + * This method may return null if the term does not exist. + * + * @see TermsEnum#termState() + * @see TermsEnum#seek(BytesRef, TermState) */ + public DocsEnum docs(Bits skipDocs, BytesRef term, TermState termState, DocsEnum reuse) throws IOException { + final TermsEnum termsEnum = getThreadTermsEnum(); + if (termsEnum.seek(term, termState) == TermsEnum.SeekStatus.FOUND) { + return termsEnum.docs(skipDocs, reuse); + } else { + return null; + } + } + + /** + * Get {@link DocsEnum} for the specified {@link TermState}. This + * method will may return null if the term does not exists, or positions were + * not indexed. + * + * @see TermsEnum#termState() + * @see TermsEnum#seek(BytesRef, TermState) */ + public DocsAndPositionsEnum docsAndPositions(Bits skipDocs, BytesRef term, TermState termState, DocsAndPositionsEnum reuse) throws IOException { + final TermsEnum termsEnum = getThreadTermsEnum(); + if (termsEnum.seek(term, termState) == TermsEnum.SeekStatus.FOUND) { + return termsEnum.docsAndPositions(skipDocs, reuse); + } else { + return null; + } + } + public long getUniqueTermCount() throws IOException { throw new UnsupportedOperationException("this reader does not implement getUniqueTermCount()"); } - protected TermsEnum getThreadTermsEnum() throws IOException { + /** + * Returns a thread-private {@link TermsEnum} instance. Obtaining + * {@link TermsEnum} from this method might be more efficient than using + * {@link #iterator()} directly since this method doesn't necessarily create a + * new {@link TermsEnum} instance. + *

    + * NOTE: {@link TermsEnum} instances obtained from this method must not be + * shared across threads. The enum should only be used within a local context + * where other threads can't access it. + * + * @return a thread-private {@link TermsEnum} instance + * @throws IOException + * if an IOException occurs + * @lucene.internal + */ + public TermsEnum getThreadTermsEnum() throws IOException { TermsEnum termsEnum = threadEnums.get(); if (termsEnum == null) { termsEnum = iterator(); diff --git a/lucene/src/java/org/apache/lucene/index/TermsEnum.java b/lucene/src/java/org/apache/lucene/index/TermsEnum.java index 9901a966d2b..a7df0118544 100644 --- a/lucene/src/java/org/apache/lucene/index/TermsEnum.java +++ b/lucene/src/java/org/apache/lucene/index/TermsEnum.java @@ -73,7 +73,34 @@ public abstract class TermsEnum { * may be before or after the current ord. See {@link * #seek(BytesRef)}. */ public abstract SeekStatus seek(long ord) throws IOException; - + + /** + * Expert: Seeks a specific position by {@link TermState} previously obtained + * from {@link #termState()}. Callers should maintain the {@link TermState} to + * use this method. Low-level implementations may position the TermsEnum + * without re-seeking the term dictionary. + *

    + * Seeking by {@link TermState} should only be used iff the enu the state was + * obtained from and the enum the state is used for seeking are obtained from + * the same {@link IndexReader}, otherwise a {@link #seek(BytesRef, TermState)} call can + * leave the enum in undefined state. + *

    + * NOTE: Using this method with an incompatible {@link TermState} might leave + * this {@link TermsEnum} in undefined state. On a segment level + * {@link TermState} instances are compatible only iff the source and the + * target {@link TermsEnum} operate on the same field. If operating on segment + * level, TermState instances must not be used across segments. + *

    + * NOTE: A seek by {@link TermState} might not restore the + * {@link AttributeSource}'s state. {@link AttributeSource} states must be + * maintained separately if this method is used. + * @param term the term the TermState corresponds to + * @param state the {@link TermState} + * */ + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + return seek(term); + } + /** Increments the enumeration to the next element. * Returns the resulting term, or null if the end was * hit. The returned BytesRef may be re-used across calls @@ -98,7 +125,7 @@ public abstract class TermsEnum { * first time, after next() returns null or seek returns * {@link SeekStatus#END}.*/ public abstract int docFreq(); - + /** Get {@link DocsEnum} for the current term. Do not * call this before calling {@link #next} or {@link * #seek} for the first time. This method will not @@ -116,6 +143,25 @@ public abstract class TermsEnum { * the postings by this codec. */ public abstract DocsAndPositionsEnum docsAndPositions(Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException; + /** + * Expert: Returns the TermsEnums internal state to position the TermsEnum + * without re-seeking the term dictionary. + *

    + * NOTE: A seek by {@link TermState} might not capture the + * {@link AttributeSource}'s state. Callers must maintain the + * {@link AttributeSource} states separately + * + * @see TermState + * @see #seek(BytesRef, TermState) + */ + public TermState termState() throws IOException { + return new TermState() { + @Override + public void copyFrom(TermState other) { + } + }; + } + /** Return the {@link BytesRef} Comparator used to sort * terms provided by the iterator. This may return * null if there are no terms. Callers may invoke this @@ -123,10 +169,6 @@ public abstract class TermsEnum { * instance & reuse it. */ public abstract Comparator getComparator() throws IOException; - /** Optional optimization hint: informs the codec that the - * current term is likely to be re-seek'd-to soon. */ - public abstract void cacheCurrentTerm() throws IOException; - /** An empty TermsEnum for quickly returning an empty instance e.g. * in {@link org.apache.lucene.search.MultiTermQuery} *

    Please note: This enum should be unmodifiable, @@ -141,9 +183,6 @@ public abstract class TermsEnum { @Override public SeekStatus seek(long ord) { return SeekStatus.END; } - @Override - public void cacheCurrentTerm() {} - @Override public BytesRef term() { throw new IllegalStateException("this method should never be called"); @@ -183,5 +222,15 @@ public abstract class TermsEnum { public synchronized AttributeSource attributes() { return super.attributes(); } + + @Override + public TermState termState() throws IOException { + throw new IllegalStateException("this method should never be called"); + } + + @Override + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + throw new IllegalStateException("this method should never be called"); + } }; } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PostingsReaderBase.java b/lucene/src/java/org/apache/lucene/index/codecs/PostingsReaderBase.java index 8cbd9780cbc..73c516aa030 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PostingsReaderBase.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PostingsReaderBase.java @@ -42,17 +42,17 @@ public abstract class PostingsReaderBase implements Closeable { public abstract void init(IndexInput termsIn) throws IOException; /** Return a newly created empty TermState */ - public abstract TermState newTermState() throws IOException; + public abstract PrefixCodedTermState newTermState() throws IOException; - public abstract void readTerm(IndexInput termsIn, FieldInfo fieldInfo, TermState state, boolean isIndexTerm) throws IOException; + public abstract void readTerm(IndexInput termsIn, FieldInfo fieldInfo, PrefixCodedTermState state, boolean isIndexTerm) throws IOException; /** Must fully consume state, since after this call that * TermState may be reused. */ - public abstract DocsEnum docs(FieldInfo fieldInfo, TermState state, Bits skipDocs, DocsEnum reuse) throws IOException; + public abstract DocsEnum docs(FieldInfo fieldInfo, PrefixCodedTermState state, Bits skipDocs, DocsEnum reuse) throws IOException; /** Must fully consume state, since after this call that * TermState may be reused. */ - public abstract DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, TermState state, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException; + public abstract DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, PrefixCodedTermState state, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException; public abstract void close() throws IOException; } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/TermState.java b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java similarity index 54% rename from lucene/src/java/org/apache/lucene/index/codecs/TermState.java rename to lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java index ec423269a10..0ca99aed31e 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/TermState.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java @@ -1,5 +1,4 @@ package org.apache.lucene.index.codecs; - /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -17,40 +16,30 @@ package org.apache.lucene.index.codecs; * limitations under the License. */ -import org.apache.lucene.index.DocsEnum; // for javadocs - -import org.apache.lucene.index.codecs.standard.StandardPostingsReader; // javadocs +import org.apache.lucene.index.OrdTermState; +import org.apache.lucene.index.TermState; /** - * Holds all state required for {@link StandardPostingsReader} + * Holds all state required for {@link PostingsReaderBase} * to produce a {@link DocsEnum} without re-seeking the * terms dict. - * @lucene.experimental */ +public class PrefixCodedTermState extends OrdTermState { + public int docFreq; // how many docs have this term + public long filePointer; // fp into the terms dict primary file (_X.tis) -public class TermState implements Cloneable { - public long ord; // ord for this term - public long filePointer; // fp into the terms dict primary file (_X.tis) - public int docFreq; // how many docs have this term - - public void copyFrom(TermState other) { - ord = other.ord; + @Override + public void copyFrom(TermState _other) { + assert _other instanceof PrefixCodedTermState : "can not copy from " + _other.getClass().getName(); + PrefixCodedTermState other = (PrefixCodedTermState) _other; + super.copyFrom(_other); filePointer = other.filePointer; docFreq = other.docFreq; } - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException cnse) { - // should not happen - throw new RuntimeException(cnse); - } - } - @Override public String toString() { - return "tis.fp=" + filePointer + " docFreq=" + docFreq + " ord=" + ord; + return super.toString() + "[ord=" + ord + ", tis.filePointer=" + filePointer + "]"; } + } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java index 053af472512..166add82cff 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsReader.java @@ -31,6 +31,7 @@ import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.FieldsEnum; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentInfo; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.store.Directory; @@ -68,7 +69,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { private final Comparator termComp; // Caches the most recently looked-up field + terms: - private final DoubleBarrelLRUCache termsCache; + private final DoubleBarrelLRUCache termsCache; // Reads the terms index private TermsIndexReaderBase indexReader; @@ -84,11 +85,6 @@ public class PrefixCodedTermsReader extends FieldsProducer { public FieldAndTerm() { } - public FieldAndTerm(String field, BytesRef term) { - this.field = field; - this.term = new BytesRef(term); - } - public FieldAndTerm(FieldAndTerm other) { field = other.field; term = new BytesRef(other.term); @@ -116,7 +112,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { throws IOException { this.postingsReader = postingsReader; - termsCache = new DoubleBarrelLRUCache(termsCacheSize); + termsCache = new DoubleBarrelLRUCache(termsCacheSize); this.termComp = termComp; @@ -278,10 +274,10 @@ public class PrefixCodedTermsReader extends FieldsProducer { } // Iterates through terms in this field, not supporting ord() - private class SegmentTermsEnum extends TermsEnum { + private final class SegmentTermsEnum extends TermsEnum { private final IndexInput in; private final DeltaBytesReader bytesReader; - private final TermState state; + private final PrefixCodedTermState state; private boolean seekPending; private final FieldAndTerm fieldTerm = new FieldAndTerm(); private final TermsIndexReaderBase.FieldIndexEnum indexEnum; @@ -307,14 +303,6 @@ public class PrefixCodedTermsReader extends FieldsProducer { return termComp; } - @Override - public void cacheCurrentTerm() { - TermState stateCopy = (TermState) state.clone(); - stateCopy.filePointer = in.getFilePointer(); - termsCache.put(new FieldAndTerm(fieldInfo.name, bytesReader.term), - stateCopy); - } - // called only from assert private boolean first; private int indexTermCount; @@ -342,7 +330,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { * is found, SeekStatus.NOT_FOUND if a different term * was found, SeekStatus.END if we hit EOF */ @Override - public SeekStatus seek(BytesRef term, boolean useCache) throws IOException { + public SeekStatus seek(final BytesRef term, final boolean useCache) throws IOException { if (indexEnum == null) { throw new IllegalStateException("terms index was not loaded"); @@ -357,9 +345,8 @@ public class PrefixCodedTermsReader extends FieldsProducer { cachedState = termsCache.get(fieldTerm); if (cachedState != null) { state.copyFrom(cachedState); - seekPending = true; + setTermState(term, state); positioned = false; - bytesReader.term.copy(term); //System.out.println(" cached!"); return SeekStatus.FOUND; } @@ -439,12 +426,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { if (cmp == 0) { // Done! if (useCache) { - // Store in cache - FieldAndTerm entryKey = new FieldAndTerm(fieldTerm); - cachedState = (TermState) state.clone(); - // this is fp after current term - cachedState.filePointer = in.getFilePointer(); - termsCache.put(entryKey, cachedState); + cacheTerm(fieldTerm); } return SeekStatus.FOUND; @@ -464,6 +446,23 @@ public class PrefixCodedTermsReader extends FieldsProducer { return SeekStatus.END; } + private final void setTermState(BytesRef term, final TermState termState) { + assert termState != null && termState instanceof PrefixCodedTermState; + state.copyFrom(termState); + seekPending = true; + bytesReader.term.copy(term); + } + + private final void cacheTerm(FieldAndTerm other) { + // Store in cache + final FieldAndTerm entryKey = new FieldAndTerm(other); + final PrefixCodedTermState cachedState = (PrefixCodedTermState) state.clone(); + // this is fp after current term + cachedState.filePointer = in.getFilePointer(); + termsCache.put(entryKey, cachedState); + } + + @Override public BytesRef term() { return bytesReader.term; @@ -498,7 +497,9 @@ public class PrefixCodedTermsReader extends FieldsProducer { postingsReader.readTerm(in, fieldInfo, state, isIndexTerm); - state.ord++; + if (doOrd) { + state.ord++; + } positioned = true; //System.out.println("te.next term=" + bytesReader.term.utf8ToString()); @@ -512,7 +513,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { - DocsEnum docsEnum = postingsReader.docs(fieldInfo, state, skipDocs, reuse); + final DocsEnum docsEnum = postingsReader.docs(fieldInfo, state, skipDocs, reuse); assert docsEnum != null; return docsEnum; } @@ -526,6 +527,23 @@ public class PrefixCodedTermsReader extends FieldsProducer { } } + @Override + public SeekStatus seek(BytesRef term, TermState otherState) throws IOException { + assert otherState != null && otherState instanceof PrefixCodedTermState; + assert otherState.getClass() == this.state.getClass() : "Illegal TermState type " + otherState.getClass(); + assert ((PrefixCodedTermState)otherState).ord < numTerms; + setTermState(term, otherState); + positioned = false; + return SeekStatus.FOUND; + } + + @Override + public TermState termState() throws IOException { + final PrefixCodedTermState newTermState = (PrefixCodedTermState) state.clone(); + newTermState.filePointer = in.getFilePointer(); + return newTermState; + } + @Override public SeekStatus seek(long ord) throws IOException { @@ -562,7 +580,6 @@ public class PrefixCodedTermsReader extends FieldsProducer { return SeekStatus.FOUND; } - @Override public long ord() { if (!doOrd) { throw new UnsupportedOperationException(); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java b/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java index c94e53b543b..3f54b0b9037 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java @@ -33,6 +33,7 @@ import org.apache.lucene.index.FieldsEnum; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentInfo; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.CompoundFileReader; @@ -741,11 +742,6 @@ public class PreFlexFields extends FieldsProducer { } } - @Override - public void cacheCurrentTerm() throws IOException { - getTermsDict().cacheCurrentTerm(termEnum); - } - @Override public SeekStatus seek(long ord) throws IOException { throw new UnsupportedOperationException(); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java index d2bc02a69f9..ac497a4e5a8 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java @@ -22,8 +22,9 @@ import java.io.IOException; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.FieldInfo; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.codecs.PostingsReaderBase; -import org.apache.lucene.index.codecs.TermState; +import org.apache.lucene.index.codecs.PrefixCodedTermState; import org.apache.lucene.store.ByteArrayDataInput; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.ArrayUtil; @@ -56,10 +57,10 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { wrappedPostingsReader.init(termsIn); } - private static class PulsingTermState extends TermState { + private static class PulsingTermState extends PrefixCodedTermState { private byte[] postings; private int postingsSize; // -1 if this term was not inlined - private TermState wrappedTermState; + private PrefixCodedTermState wrappedTermState; private boolean pendingIndexTerm; @Override @@ -71,7 +72,7 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { System.arraycopy(postings, 0, clone.postings, 0, postingsSize); } else { assert wrappedTermState != null; - clone.wrappedTermState = (TermState) wrappedTermState.clone(); + clone.wrappedTermState = (PrefixCodedTermState) wrappedTermState.clone(); } return clone; } @@ -102,15 +103,14 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { } @Override - public TermState newTermState() throws IOException { + public PrefixCodedTermState newTermState() throws IOException { PulsingTermState state = new PulsingTermState(); state.wrappedTermState = wrappedPostingsReader.newTermState(); return state; } @Override - public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, TermState _termState, boolean isIndexTerm) throws IOException { - + public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, PrefixCodedTermState _termState, boolean isIndexTerm) throws IOException { PulsingTermState termState = (PulsingTermState) _termState; termState.pendingIndexTerm |= isIndexTerm; @@ -137,7 +137,7 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { // TODO: we could actually reuse, by having TL that // holds the last wrapped reuse, and vice-versa @Override - public DocsEnum docs(FieldInfo field, TermState _termState, Bits skipDocs, DocsEnum reuse) throws IOException { + public DocsEnum docs(FieldInfo field, PrefixCodedTermState _termState, Bits skipDocs, DocsEnum reuse) throws IOException { PulsingTermState termState = (PulsingTermState) _termState; if (termState.postingsSize != -1) { PulsingDocsEnum postings; @@ -162,7 +162,7 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { // TODO: -- not great that we can't always reuse @Override - public DocsAndPositionsEnum docsAndPositions(FieldInfo field, TermState _termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { + public DocsAndPositionsEnum docsAndPositions(FieldInfo field, PrefixCodedTermState _termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { if (field.omitTermFreqAndPositions) { return null; } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java index d3a35c5bc75..0f428473672 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsReaderImpl.java @@ -25,8 +25,9 @@ import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentInfo; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.codecs.PostingsReaderBase; -import org.apache.lucene.index.codecs.TermState; +import org.apache.lucene.index.codecs.PrefixCodedTermState; import org.apache.lucene.store.Directory; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.Bits; @@ -129,12 +130,13 @@ public class SepPostingsReaderImpl extends PostingsReaderBase { } } - private static class SepTermState extends TermState { + private static final class SepTermState extends PrefixCodedTermState { // We store only the seek point to the docs file because // the rest of the info (freqIndex, posIndex, etc.) is // stored in the docs file: IntIndexInput.Index docIndex; - + + @Override public Object clone() { SepTermState other = (SepTermState) super.clone(); other.docIndex = (IntIndexInput.Index) docIndex.clone(); @@ -154,19 +156,19 @@ public class SepPostingsReaderImpl extends PostingsReaderBase { } @Override - public TermState newTermState() throws IOException { + public PrefixCodedTermState newTermState() throws IOException { final SepTermState state = new SepTermState(); state.docIndex = docIn.index(); return state; } @Override - public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, TermState termState, boolean isIndexTerm) throws IOException { + public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, PrefixCodedTermState termState, boolean isIndexTerm) throws IOException { ((SepTermState) termState).docIndex.read(termsIn, isIndexTerm); } @Override - public DocsEnum docs(FieldInfo fieldInfo, TermState _termState, Bits skipDocs, DocsEnum reuse) throws IOException { + public DocsEnum docs(FieldInfo fieldInfo, PrefixCodedTermState _termState, Bits skipDocs, DocsEnum reuse) throws IOException { final SepTermState termState = (SepTermState) _termState; SepDocsEnum docsEnum; if (reuse == null || !(reuse instanceof SepDocsEnum)) { @@ -185,7 +187,7 @@ public class SepPostingsReaderImpl extends PostingsReaderBase { } @Override - public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, TermState _termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { + public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, PrefixCodedTermState _termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { assert !fieldInfo.omitTermFreqAndPositions; final SepTermState termState = (SepTermState) _termState; SepDocsAndPositionsEnum postingsEnum; diff --git a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java index 1f722f6a530..673f2261335 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java @@ -21,6 +21,7 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.codecs.FieldsProducer; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.FieldsEnum; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -151,10 +152,6 @@ class SimpleTextFieldsReader extends FieldsProducer { } } - @Override - public void cacheCurrentTerm() { - } - @Override public BytesRef next() throws IOException { assert !ended; @@ -214,7 +211,7 @@ class SimpleTextFieldsReader extends FieldsProducer { } return docsAndPositionsEnum.reset(docsStart, skipDocs); } - + @Override public Comparator getComparator() { return BytesRef.getUTF8SortedAsUnicodeComparator(); @@ -439,7 +436,6 @@ class SimpleTextFieldsReader extends FieldsProducer { } private class SimpleTextTerms extends Terms { - private final String field; private final long termsStart; private final boolean omitTF; private FST> fst; @@ -447,7 +443,6 @@ class SimpleTextFieldsReader extends FieldsProducer { private final BytesRef scratch = new BytesRef(10); public SimpleTextTerms(String field, long termsStart) throws IOException { - this.field = StringHelper.intern(field); this.termsStart = termsStart; omitTF = fieldInfos.fieldInfo(field).omitTermFreqAndPositions; loadTerms(); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java index 10ec9d8b20f..aa6e6fa5050 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsReader.java @@ -26,8 +26,9 @@ import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.IndexFileNames; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.codecs.PostingsReaderBase; -import org.apache.lucene.index.codecs.TermState; +import org.apache.lucene.index.codecs.PrefixCodedTermState; import org.apache.lucene.store.IndexInput; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; @@ -83,20 +84,20 @@ public class StandardPostingsReader extends PostingsReaderBase { } // Must keep final because we do non-standard clone - private final static class DocTermState extends TermState { + private final static class StandardTermState extends PrefixCodedTermState { long freqOffset; long proxOffset; int skipOffset; public Object clone() { - DocTermState other = new DocTermState(); + StandardTermState other = new StandardTermState(); other.copyFrom(this); return other; } public void copyFrom(TermState _other) { super.copyFrom(_other); - DocTermState other = (DocTermState) _other; + StandardTermState other = (StandardTermState) _other; freqOffset = other.freqOffset; proxOffset = other.proxOffset; skipOffset = other.skipOffset; @@ -108,8 +109,8 @@ public class StandardPostingsReader extends PostingsReaderBase { } @Override - public TermState newTermState() { - return new DocTermState(); + public PrefixCodedTermState newTermState() { + return new StandardTermState(); } @Override @@ -126,10 +127,9 @@ public class StandardPostingsReader extends PostingsReaderBase { } @Override - public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, TermState termState, boolean isIndexTerm) + public void readTerm(IndexInput termsIn, FieldInfo fieldInfo, PrefixCodedTermState termState, boolean isIndexTerm) throws IOException { - - final DocTermState docTermState = (DocTermState) termState; + final StandardTermState docTermState = (StandardTermState) termState; if (isIndexTerm) { docTermState.freqOffset = termsIn.readVLong(); @@ -153,7 +153,7 @@ public class StandardPostingsReader extends PostingsReaderBase { } @Override - public DocsEnum docs(FieldInfo fieldInfo, TermState termState, Bits skipDocs, DocsEnum reuse) throws IOException { + public DocsEnum docs(FieldInfo fieldInfo, PrefixCodedTermState termState, Bits skipDocs, DocsEnum reuse) throws IOException { SegmentDocsEnum docsEnum; if (reuse == null || !(reuse instanceof SegmentDocsEnum)) { docsEnum = new SegmentDocsEnum(freqIn); @@ -166,11 +166,11 @@ public class StandardPostingsReader extends PostingsReaderBase { docsEnum = new SegmentDocsEnum(freqIn); } } - return docsEnum.reset(fieldInfo, (DocTermState) termState, skipDocs); + return docsEnum.reset(fieldInfo, (StandardTermState) termState, skipDocs); } @Override - public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, TermState termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { + public DocsAndPositionsEnum docsAndPositions(FieldInfo fieldInfo, PrefixCodedTermState termState, Bits skipDocs, DocsAndPositionsEnum reuse) throws IOException { if (fieldInfo.omitTermFreqAndPositions) { return null; } @@ -189,7 +189,7 @@ public class StandardPostingsReader extends PostingsReaderBase { docsEnum = new SegmentDocsAndPositionsAndPayloadsEnum(freqIn, proxIn); } } - return docsEnum.reset(fieldInfo, (DocTermState) termState, skipDocs); + return docsEnum.reset(fieldInfo, (StandardTermState) termState, skipDocs); } else { SegmentDocsAndPositionsEnum docsEnum; if (reuse == null || !(reuse instanceof SegmentDocsAndPositionsEnum)) { @@ -203,7 +203,7 @@ public class StandardPostingsReader extends PostingsReaderBase { docsEnum = new SegmentDocsAndPositionsEnum(freqIn, proxIn); } } - return docsEnum.reset(fieldInfo, (DocTermState) termState, skipDocs); + return docsEnum.reset(fieldInfo, (StandardTermState) termState, skipDocs); } } @@ -233,7 +233,7 @@ public class StandardPostingsReader extends PostingsReaderBase { this.freqIn = (IndexInput) freqIn.clone(); } - public SegmentDocsEnum reset(FieldInfo fieldInfo, DocTermState termState, Bits skipDocs) throws IOException { + public SegmentDocsEnum reset(FieldInfo fieldInfo, StandardTermState termState, Bits skipDocs) throws IOException { omitTF = fieldInfo.omitTermFreqAndPositions; if (omitTF) { freq = 1; @@ -407,7 +407,7 @@ public class StandardPostingsReader extends PostingsReaderBase { this.proxIn = (IndexInput) proxIn.clone(); } - public SegmentDocsAndPositionsEnum reset(FieldInfo fieldInfo, DocTermState termState, Bits skipDocs) throws IOException { + public SegmentDocsAndPositionsEnum reset(FieldInfo fieldInfo, StandardTermState termState, Bits skipDocs) throws IOException { assert !fieldInfo.omitTermFreqAndPositions; assert !fieldInfo.storePayloads; @@ -594,7 +594,7 @@ public class StandardPostingsReader extends PostingsReaderBase { this.proxIn = (IndexInput) proxIn.clone(); } - public SegmentDocsAndPositionsAndPayloadsEnum reset(FieldInfo fieldInfo, DocTermState termState, Bits skipDocs) throws IOException { + public SegmentDocsAndPositionsAndPayloadsEnum reset(FieldInfo fieldInfo, StandardTermState termState, Bits skipDocs) throws IOException { assert !fieldInfo.omitTermFreqAndPositions; assert fieldInfo.storePayloads; if (payload == null) { diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreAutoRewrite.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreAutoRewrite.java index 6dd17bf3645..64aef2b3cf5 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreAutoRewrite.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreAutoRewrite.java @@ -21,9 +21,15 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.util.ArrayUtil; +import org.apache.lucene.util.ByteBlockPool; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefHash; +import org.apache.lucene.util.PerReaderTermState; +import org.apache.lucene.util.RamUsageEstimator; +import org.apache.lucene.util.BytesRefHash.DirectBytesStartArray; class ConstantScoreAutoRewrite extends TermCollectingRewrite { @@ -71,8 +77,8 @@ class ConstantScoreAutoRewrite extends TermCollectingRewrite { } @Override - protected void addClause(BooleanQuery topLevel, Term term, int docFreq, float boost /*ignored*/) { - topLevel.add(new TermQuery(term, docFreq), BooleanClause.Occur.SHOULD); + protected void addClause(BooleanQuery topLevel, Term term, int docFreq, float boost /*ignored*/, PerReaderTermState states) { + topLevel.add(new TermQuery(term, states), BooleanClause.Occur.SHOULD); } @Override @@ -98,9 +104,10 @@ class ConstantScoreAutoRewrite extends TermCollectingRewrite { final BytesRefHash pendingTerms = col.pendingTerms; final int sort[] = pendingTerms.sort(col.termsEnum.getComparator()); for(int i = 0; i < size; i++) { + final int pos = sort[i]; // docFreq is not used for constant score here, we pass 1 // to explicitely set a fake value, so it's not calculated - addClause(bq, placeholderTerm.createTerm(pendingTerms.get(sort[i], new BytesRef())), 1, 1.0f); + addClause(bq, placeholderTerm.createTerm(pendingTerms.get(pos, new BytesRef())), 1, 1.0f, col.array.termState[pos]); } // Strip scores final Query result = new ConstantScoreQuery(bq); @@ -123,12 +130,21 @@ class ConstantScoreAutoRewrite extends TermCollectingRewrite { @Override public boolean collect(BytesRef bytes) throws IOException { - pendingTerms.add(bytes); + int pos = pendingTerms.add(bytes); docVisitCount += termsEnum.docFreq(); if (pendingTerms.size() >= termCountLimit || docVisitCount >= docCountCutoff) { hasCutOff = true; return false; } + + final TermState termState = termsEnum.termState(); + assert termState != null; + if (pos < 0) { + pos = (-pos)-1; + array.termState[pos].register(termState, readerContext.ord, termsEnum.docFreq()); + } else { + array.termState[pos] = new PerReaderTermState(topReaderContext, termState, readerContext.ord, termsEnum.docFreq()); + } return true; } @@ -137,7 +153,8 @@ class ConstantScoreAutoRewrite extends TermCollectingRewrite { TermsEnum termsEnum; final int docCountCutoff, termCountLimit; - final BytesRefHash pendingTerms = new BytesRefHash(); + final TermStateByteStart array = new TermStateByteStart(16); + final BytesRefHash pendingTerms = new BytesRefHash(new ByteBlockPool(new ByteBlockPool.DirectAllocator()), 16, array); } @Override @@ -166,4 +183,40 @@ class ConstantScoreAutoRewrite extends TermCollectingRewrite { return true; } + + /** Special implementation of BytesStartArray that keeps parallel arrays for {@link PerReaderTermState} */ + static final class TermStateByteStart extends DirectBytesStartArray { + PerReaderTermState[] termState; + + public TermStateByteStart(int initSize) { + super(initSize); + } + + @Override + public int[] init() { + final int[] ord = super.init(); + termState = new PerReaderTermState[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; + assert termState.length >= ord.length; + return ord; + } + + @Override + public int[] grow() { + final int[] ord = super.grow(); + if (termState.length < ord.length) { + PerReaderTermState[] tmpTermState = new PerReaderTermState[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; + System.arraycopy(termState, 0, tmpTermState, 0, termState.length); + termState = tmpTermState; + } + assert termState.length >= ord.length; + return ord; + } + + @Override + public int[] clear() { + termState = null; + return super.clear(); + } + + } } diff --git a/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java b/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java index 84437b755f0..7353b9c3cdf 100644 --- a/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.Comparator; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -155,12 +156,24 @@ public abstract class FilteredTermsEnum extends TermsEnum { public DocsAndPositionsEnum docsAndPositions(Bits bits, DocsAndPositionsEnum reuse) throws IOException { return tenum.docsAndPositions(bits, reuse); } - + + /** This enum does not support seeking! + * @throws UnsupportedOperationException + */ @Override - public void cacheCurrentTerm() throws IOException { - tenum.cacheCurrentTerm(); + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + throw new UnsupportedOperationException(getClass().getName()+" does not support seeking"); } - + + /** + * Returns the filtered enums term state + */ + @Override + public TermState termState() throws IOException { + assert tenum != null; + return tenum.termState(); + } + @SuppressWarnings("fallthrough") @Override public BytesRef next() throws IOException { diff --git a/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java b/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java index 48a7709bed0..f8e67b267f3 100644 --- a/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.Attribute; import org.apache.lucene.util.AttributeImpl; @@ -244,11 +245,6 @@ public final class FuzzyTermsEnum extends TermsEnum { return actualEnum.docFreq(); } - @Override - public void cacheCurrentTerm() throws IOException { - actualEnum.cacheCurrentTerm(); - } - @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { return actualEnum.docs(skipDocs, reuse); @@ -260,6 +256,15 @@ public final class FuzzyTermsEnum extends TermsEnum { return actualEnum.docsAndPositions(skipDocs, reuse); } + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + return actualEnum.seek(term, state); + } + + @Override + public TermState termState() throws IOException { + return actualEnum.termState(); + } + @Override public Comparator getComparator() throws IOException { return actualEnum.getComparator(); diff --git a/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java b/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java index a108360cea0..8051d7fc160 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiTermQuery.java @@ -26,6 +26,7 @@ import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.util.AttributeSource; +import org.apache.lucene.util.PerReaderTermState; /** * An abstract {@link Query} that matches documents @@ -159,8 +160,8 @@ public abstract class MultiTermQuery extends Query { } @Override - protected void addClause(BooleanQuery topLevel, Term term, int docCount, float boost) { - final TermQuery tq = new TermQuery(term, docCount); + protected void addClause(BooleanQuery topLevel, Term term, int docCount, float boost, PerReaderTermState states) { + final TermQuery tq = new TermQuery(term, states); tq.setBoost(boost); topLevel.add(tq, BooleanClause.Occur.SHOULD); } @@ -200,8 +201,8 @@ public abstract class MultiTermQuery extends Query { } @Override - protected void addClause(BooleanQuery topLevel, Term term, int docFreq, float boost) { - final Query q = new ConstantScoreQuery(new TermQuery(term, docFreq)); + protected void addClause(BooleanQuery topLevel, Term term, int docFreq, float boost, PerReaderTermState states) { + final Query q = new ConstantScoreQuery(new TermQuery(term, states)); q.setBoost(boost); topLevel.add(q, BooleanClause.Occur.SHOULD); } diff --git a/lucene/src/java/org/apache/lucene/search/ScoringRewrite.java b/lucene/src/java/org/apache/lucene/search/ScoringRewrite.java index 355d64e8701..3cf74641b09 100644 --- a/lucene/src/java/org/apache/lucene/search/ScoringRewrite.java +++ b/lucene/src/java/org/apache/lucene/search/ScoringRewrite.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.search.MultiTermQuery.RewriteMethod; @@ -27,6 +28,7 @@ import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.ByteBlockPool; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefHash; +import org.apache.lucene.util.PerReaderTermState; import org.apache.lucene.util.RamUsageEstimator; import org.apache.lucene.util.BytesRefHash.DirectBytesStartArray; @@ -53,8 +55,9 @@ public abstract class ScoringRewrite extends TermCollectingRewr } @Override - protected void addClause(BooleanQuery topLevel, Term term, int docCount, float boost) { - final TermQuery tq = new TermQuery(term, docCount); + protected void addClause(BooleanQuery topLevel, Term term, int docCount, + float boost, PerReaderTermState states) { + final TermQuery tq = new TermQuery(term, states); tq.setBoost(boost); topLevel.add(tq, BooleanClause.Occur.SHOULD); } @@ -114,13 +117,13 @@ public abstract class ScoringRewrite extends TermCollectingRewr final int size = col.terms.size(); if (size > 0) { final int sort[] = col.terms.sort(col.termsEnum.getComparator()); - final int[] docFreq = col.array.docFreq; final float[] boost = col.array.boost; + final PerReaderTermState[] termStates = col.array.termState; for (int i = 0; i < size; i++) { final int pos = sort[i]; final Term term = placeholderTerm.createTerm(col.terms.get(pos, new BytesRef())); - assert reader.docFreq(term) == docFreq[pos]; - addClause(result, term, docFreq[pos], query.getBoost() * boost[pos]); + assert reader.docFreq(term) == termStates[pos].docFreq(); + addClause(result, term, termStates[pos].docFreq(), query.getBoost() * boost[pos], termStates[pos]); } } query.incTotalNumberOfTerms(size); @@ -143,15 +146,17 @@ public abstract class ScoringRewrite extends TermCollectingRewr @Override public boolean collect(BytesRef bytes) throws IOException { final int e = terms.add(bytes); + final TermState state = termsEnum.termState(); + assert state != null; if (e < 0 ) { // duplicate term: update docFreq final int pos = (-e)-1; - array.docFreq[pos] += termsEnum.docFreq(); + array.termState[pos].register(state, readerContext.ord, termsEnum.docFreq()); assert array.boost[pos] == boostAtt.getBoost() : "boost should be equal in all segment TermsEnums"; } else { // new entry: we populate the entry initially - array.docFreq[e] = termsEnum.docFreq(); array.boost[e] = boostAtt.getBoost(); + array.termState[e] = new PerReaderTermState(topReaderContext, state, readerContext.ord, termsEnum.docFreq()); ScoringRewrite.this.checkMaxClauseCount(terms.size()); } return true; @@ -160,8 +165,8 @@ public abstract class ScoringRewrite extends TermCollectingRewr /** Special implementation of BytesStartArray that keeps parallel arrays for boost and docFreq */ static final class TermFreqBoostByteStart extends DirectBytesStartArray { - int[] docFreq; float[] boost; + PerReaderTermState[] termState; public TermFreqBoostByteStart(int initSize) { super(initSize); @@ -171,24 +176,28 @@ public abstract class ScoringRewrite extends TermCollectingRewr public int[] init() { final int[] ord = super.init(); boost = new float[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_FLOAT)]; - docFreq = new int[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_INT)]; - assert boost.length >= ord.length && docFreq.length >= ord.length; + termState = new PerReaderTermState[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; + assert termState.length >= ord.length && boost.length >= ord.length; return ord; } @Override public int[] grow() { final int[] ord = super.grow(); - docFreq = ArrayUtil.grow(docFreq, ord.length); boost = ArrayUtil.grow(boost, ord.length); - assert boost.length >= ord.length && docFreq.length >= ord.length; + if (termState.length < ord.length) { + PerReaderTermState[] tmpTermState = new PerReaderTermState[ArrayUtil.oversize(ord.length, RamUsageEstimator.NUM_BYTES_OBJECT_REF)]; + System.arraycopy(termState, 0, tmpTermState, 0, termState.length); + termState = tmpTermState; + } + assert termState.length >= ord.length && boost.length >= ord.length; return ord; } @Override public int[] clear() { boost = null; - docFreq = null; + termState = null; return super.clear(); } diff --git a/lucene/src/java/org/apache/lucene/search/TermCollectingRewrite.java b/lucene/src/java/org/apache/lucene/search/TermCollectingRewrite.java index e710b96c145..501831728d3 100644 --- a/lucene/src/java/org/apache/lucene/search/TermCollectingRewrite.java +++ b/lucene/src/java/org/apache/lucene/search/TermCollectingRewrite.java @@ -18,8 +18,6 @@ package org.apache.lucene.search; */ import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Comparator; import org.apache.lucene.index.Fields; @@ -27,25 +25,33 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.util.AttributeSource; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.PerReaderTermState; import org.apache.lucene.util.ReaderUtil; abstract class TermCollectingRewrite extends MultiTermQuery.RewriteMethod { + /** Return a suitable top-level Query for holding all expanded terms. */ protected abstract Q getTopLevelQuery() throws IOException; /** Add a MultiTermQuery term to the top-level query */ - protected abstract void addClause(Q topLevel, Term term, int docCount, float boost) throws IOException; + protected final void addClause(Q topLevel, Term term, int docCount, float boost) throws IOException { + addClause(topLevel, term, docCount, boost, null); + } + + protected abstract void addClause(Q topLevel, Term term, int docCount, float boost, PerReaderTermState states) throws IOException; + protected final void collectTerms(IndexReader reader, MultiTermQuery query, TermCollector collector) throws IOException { - final List subReaders = new ArrayList(); - ReaderUtil.gatherSubReaders(subReaders, reader); + ReaderContext topReaderContext = reader.getTopReaderContext(); Comparator lastTermComp = null; - - for (IndexReader r : subReaders) { - final Fields fields = r.fields(); + final AtomicReaderContext[] leaves = ReaderUtil.leaves(topReaderContext); + for (AtomicReaderContext context : leaves) { + final Fields fields = context.reader.fields(); if (fields == null) { // reader has no fields continue; @@ -68,11 +74,10 @@ abstract class TermCollectingRewrite extends MultiTermQuery.Rew if (lastTermComp != null && newTermComp != null && newTermComp != lastTermComp) throw new RuntimeException("term comparator should not change between segments: "+lastTermComp+" != "+newTermComp); lastTermComp = newTermComp; - + collector.setReaderContext(topReaderContext, context); collector.setNextEnum(termsEnum); BytesRef bytes; while ((bytes = termsEnum.next()) != null) { - termsEnum.cacheCurrentTerm(); if (!collector.collect(bytes)) return; // interrupt whole term collection, so also don't iterate other subReaders } @@ -80,6 +85,14 @@ abstract class TermCollectingRewrite extends MultiTermQuery.Rew } protected static abstract class TermCollector { + + protected AtomicReaderContext readerContext; + protected ReaderContext topReaderContext; + + public void setReaderContext(ReaderContext topReaderContext, AtomicReaderContext readerContext) { + this.readerContext = readerContext; + this.topReaderContext = topReaderContext; + } /** attributes used for communication with the enum */ public final AttributeSource attributes = new AttributeSource(); diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index 5ed96f8ddca..aa41c1240a7 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -22,10 +22,14 @@ import java.util.Set; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.TermState; +import org.apache.lucene.index.Terms; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.Explanation.IDFExplanation; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.PerReaderTermState; import org.apache.lucene.util.ToStringUtils; /** A Query that matches documents containing a term. @@ -33,20 +37,22 @@ import org.apache.lucene.util.ToStringUtils; */ public class TermQuery extends Query { private final Term term; - private final int docFreq; + private int docFreq; + private transient PerReaderTermState perReaderTermState; private class TermWeight extends Weight { private final Similarity similarity; private float value; - private float idf; + private final float idf; private float queryNorm; private float queryWeight; - private IDFExplanation idfExp; - private transient ReaderContext weightContext; // only set if -ea for assert in scorer() + private final IDFExplanation idfExp; + private transient PerReaderTermState termStates; - public TermWeight(IndexSearcher searcher) + public TermWeight(IndexSearcher searcher, PerReaderTermState termStates, int docFreq) throws IOException { - assert setWeightContext(searcher); + assert termStates != null : "PerReaderTermState must not be null"; + this.termStates = termStates; this.similarity = getSimilarity(searcher); if (docFreq != -1) { idfExp = similarity.idfExplain(term, searcher, docFreq); @@ -80,31 +86,34 @@ public class TermQuery extends Query { @Override public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - assert assertTopReaderContext(context); + final String field = term.field(); final IndexReader reader = context.reader; - DocsEnum docs = reader.termDocsEnum(reader.getDeletedDocs(), - term.field(), - term.bytes()); - - if (docs == null) { + assert assertTopReaderContext(termStates, context) : "The top-reader used to create Weight is not the same as the current reader's top-reader"; + final TermState state = termStates + .get(context.ord); + if (state == null) { // term is not present in that reader + assert termNotInReader(reader, field, term.bytes()) : "no termstate found but term exists in reader"; return null; } - - return new TermScorer(this, docs, similarity, reader.norms(term.field())); + final DocsEnum docs = reader.termDocsEnum(reader.getDeletedDocs(), field, term.bytes(), state); + assert docs != null; + return new TermScorer(this, docs, similarity, context.reader.norms(field)); } - private boolean assertTopReaderContext(ReaderContext context) { - while (context.parent != null) { + private boolean termNotInReader(IndexReader reader, String field, BytesRef bytes) throws IOException { + // only called from assert + final Terms terms = reader.terms(field); + return terms == null || terms.docFreq(bytes) == 0; + } + + private boolean assertTopReaderContext(PerReaderTermState state, ReaderContext context) { + while(context.parent != null) { context = context.parent; } - return weightContext == context; + return state.topReaderContext == context; } - private boolean setWeightContext(IndexSearcher searcher) { - weightContext = searcher.getTopReaderContext(); - return true; - } - + @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { @@ -157,7 +166,7 @@ public class TermQuery extends Query { fieldExpl.addDetail(expl); Explanation fieldNormExpl = new Explanation(); - byte[] fieldNorms = reader.norms(field); + final byte[] fieldNorms = reader.norms(field); float fieldNorm = fieldNorms!=null ? similarity.decodeNormValue(fieldNorms[doc]) : 1.0f; fieldNormExpl.setValue(fieldNorm); @@ -193,6 +202,17 @@ public class TermQuery extends Query { public TermQuery(Term t, int docFreq) { term = t; this.docFreq = docFreq; + perReaderTermState = null; + } + + /** Expert: constructs a TermQuery that will use the + * provided docFreq instead of looking up the docFreq + * against the searcher. */ + public TermQuery(Term t, PerReaderTermState states) { + assert states != null; + term = t; + docFreq = states.docFreq(); + perReaderTermState = states; } /** Returns the term of this query. */ @@ -200,7 +220,21 @@ public class TermQuery extends Query { @Override public Weight createWeight(IndexSearcher searcher) throws IOException { - return new TermWeight(searcher); + final ReaderContext context = searcher.getTopReaderContext(); + final int weightDocFreq; + final PerReaderTermState termState; + if (perReaderTermState == null || perReaderTermState.topReaderContext != context) { + // make TermQuery single-pass if we don't have a PRTS or if the context differs! + termState = PerReaderTermState.build(context, term, true); // cache term lookups! + // we must not ignore the given docFreq - if set use the given value + weightDocFreq = docFreq == -1 ? termState.docFreq() : docFreq; + } else { + // PRTS was pre-build for this IS + termState = this.perReaderTermState; + weightDocFreq = docFreq; + } + + return new TermWeight(searcher, termState, weightDocFreq); } @Override diff --git a/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java b/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java index b3e409a8df7..b75ec16b57a 100644 --- a/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java +++ b/lucene/src/java/org/apache/lucene/search/TopTermsRewrite.java @@ -25,9 +25,11 @@ import java.util.Comparator; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.PerReaderTermState; /** * Base rewrite method for collecting only the top terms @@ -78,12 +80,12 @@ public abstract class TopTermsRewrite extends TermCollectingRew this.termComp = termsEnum.getComparator(); // lazy init the initial ScoreTerm because comparator is not known on ctor: if (st == null) - st = new ScoreTerm(this.termComp); + st = new ScoreTerm(this.termComp, new PerReaderTermState(topReaderContext)); boostAtt = termsEnum.attributes().addAttribute(BoostAttribute.class); } @Override - public boolean collect(BytesRef bytes) { + public boolean collect(BytesRef bytes) throws IOException { final float boost = boostAtt.getBoost(); // ignore uncompetetive hits if (stQueue.size() == maxSize) { @@ -94,23 +96,27 @@ public abstract class TopTermsRewrite extends TermCollectingRew return true; } ScoreTerm t = visitedTerms.get(bytes); + final TermState state = termsEnum.termState(); + assert state != null; if (t != null) { // if the term is already in the PQ, only update docFreq of term in PQ - t.docFreq += termsEnum.docFreq(); assert t.boost == boost : "boost should be equal in all segment TermsEnums"; + t.termState.register(state, readerContext.ord, termsEnum.docFreq()); } else { // add new entry in PQ, we must clone the term, else it may get overwritten! st.bytes.copy(bytes); st.boost = boost; - st.docFreq = termsEnum.docFreq(); visitedTerms.put(st.bytes, st); + assert st.termState.docFreq() == 0; + st.termState.register(state, readerContext.ord, termsEnum.docFreq()); stQueue.offer(st); // possibly drop entries from queue if (stQueue.size() > maxSize) { st = stQueue.poll(); visitedTerms.remove(st.bytes); + st.termState.clear(); // reset the termstate! } else { - st = new ScoreTerm(termComp); + st = new ScoreTerm(termComp, new PerReaderTermState(topReaderContext)); } assert stQueue.size() <= maxSize : "the PQ size must be limited to maxSize"; // set maxBoostAtt with values to help FuzzyTermsEnum to optimize @@ -120,6 +126,7 @@ public abstract class TopTermsRewrite extends TermCollectingRew maxBoostAtt.setCompetitiveTerm(t.bytes); } } + return true; } }); @@ -130,8 +137,8 @@ public abstract class TopTermsRewrite extends TermCollectingRew ArrayUtil.quickSort(scoreTerms, scoreTermSortByTermComp); for (final ScoreTerm st : scoreTerms) { final Term term = placeholderTerm.createTerm(st.bytes); - assert reader.docFreq(term) == st.docFreq; - addClause(q, term, st.docFreq, query.getBoost() * st.boost); // add to query + assert reader.docFreq(term) == st.termState.docFreq() : "reader DF is " + reader.docFreq(term) + " vs " + st.termState.docFreq(); + addClause(q, term, st.termState.docFreq(), query.getBoost() * st.boost, st.termState); // add to query } query.incTotalNumberOfTerms(scoreTerms.length); return q; @@ -147,7 +154,7 @@ public abstract class TopTermsRewrite extends TermCollectingRew if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; - final TopTermsRewrite other = (TopTermsRewrite) obj; + final TopTermsRewrite other = (TopTermsRewrite) obj; if (size != other.size) return false; return true; } @@ -163,13 +170,12 @@ public abstract class TopTermsRewrite extends TermCollectingRew static final class ScoreTerm implements Comparable { public final Comparator termComp; - public final BytesRef bytes = new BytesRef(); public float boost; - public int docFreq; - - public ScoreTerm(Comparator termComp) { + public final PerReaderTermState termState; + public ScoreTerm(Comparator termComp, PerReaderTermState termState) { this.termComp = termComp; + this.termState = termState; } public int compareTo(ScoreTerm other) { diff --git a/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java b/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java index da03f5b92af..314a3a2da72 100644 --- a/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java +++ b/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java @@ -24,8 +24,11 @@ import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.MultiFields; +import org.apache.lucene.index.OrdTermState; +import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.index.codecs.PrefixCodedTermState; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.FieldCache.DocTermsIndex; import org.apache.lucene.util.ArrayUtil; @@ -303,11 +306,6 @@ public class DocTermsIndexCreator extends EntryCreatorWithOptions return term; } - @Override - public void cacheCurrentTerm() throws IOException { - throw new UnsupportedOperationException(); - } - @Override public BytesRef term() throws IOException { return term; @@ -337,6 +335,19 @@ public class DocTermsIndexCreator extends EntryCreatorWithOptions public Comparator getComparator() throws IOException { return BytesRef.getUTF8SortedAsUnicodeComparator(); } + + @Override + public SeekStatus seek(BytesRef term, TermState state) throws IOException { + assert state != null && state instanceof OrdTermState; + return this.seek(((OrdTermState)state).ord); + } + + @Override + public TermState termState() throws IOException { + OrdTermState state = new OrdTermState(); + state.ord = currentOrd; + return state; + } } } } diff --git a/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java b/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java index b9fc0bc9301..e260c814abd 100644 --- a/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java +++ b/lucene/src/java/org/apache/lucene/search/spans/SpanMultiTermQueryWrapper.java @@ -26,6 +26,7 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.TopTermsRewrite; import org.apache.lucene.search.ScoringRewrite; import org.apache.lucene.search.BooleanClause.Occur; // javadocs only +import org.apache.lucene.util.PerReaderTermState; /** * Wraps any {@link MultiTermQuery} as a {@link SpanQuery}, @@ -153,7 +154,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue } @Override - protected void addClause(SpanOrQuery topLevel, Term term, int docCount, float boost) { + protected void addClause(SpanOrQuery topLevel, Term term, int docCount, float boost, PerReaderTermState states) { final SpanTermQuery q = new SpanTermQuery(term); q.setBoost(boost); topLevel.addClause(q); @@ -202,7 +203,7 @@ public class SpanMultiTermQueryWrapper extends SpanQue } @Override - protected void addClause(SpanOrQuery topLevel, Term term, int docFreq, float boost) { + protected void addClause(SpanOrQuery topLevel, Term term, int docFreq, float boost, PerReaderTermState states) { final SpanTermQuery q = new SpanTermQuery(term); q.setBoost(boost); topLevel.addClause(q); diff --git a/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java b/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java new file mode 100644 index 00000000000..bff514df035 --- /dev/null +++ b/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java @@ -0,0 +1,148 @@ +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 java.util.Arrays; + +import org.apache.lucene.index.Fields; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.index.TermState; +import org.apache.lucene.index.Terms; +import org.apache.lucene.index.TermsEnum; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.TermsEnum.SeekStatus; + +/** + * Maintains a {@link IndexReader} {@link TermState} view over + * {@link IndexReader} instances containing a single term. The + * {@link PerReaderTermState} doesn't track if the given {@link TermState} + * objects are valid, neither if the {@link TermState} instances refer to the + * same terms in the associated readers. + * + * @lucene.experimental + */ +public final class PerReaderTermState { + public final ReaderContext topReaderContext; // for asserting! + private final TermState[] states; + private int docFreq; + + /** + * Creates an empty {@link PerReaderTermState} from a {@link ReaderContext} + */ + public PerReaderTermState(ReaderContext context) { + assert context != null && context.isTopLevel; + topReaderContext = context; + docFreq = 0; + final int len; + if (context.leaves() == null) { + len = 1; + } else { + len = context.leaves().length; + } + states = new TermState[len]; + } + + /** + * Creates a {@link PerReaderTermState} with an initial {@link TermState}, + * {@link IndexReader} pair. + */ + public PerReaderTermState(ReaderContext context, TermState state, int ord, int docFreq) { + this(context); + register(state, ord, docFreq); + } + + /** + * Creates a {@link PerReaderTermState} from a top-level {@link ReaderContext} and the + * given {@link Term}. This method will lookup the given term in all context's leaf readers + * and register each of the readers containing the term in the returned {@link PerReaderTermState} + * using the leaf reader's ordinal. + *

    + * Note: the given context must be a top-level context. + */ + public static PerReaderTermState build(ReaderContext context, Term term, boolean cache) + throws IOException { + assert context != null && context.isTopLevel; + final String field = term.field(); + final BytesRef bytes = term.bytes(); + final PerReaderTermState perReaderTermState = new PerReaderTermState(context); + final AtomicReaderContext[] leaves = ReaderUtil.leaves(context); + for (int i = 0; i < leaves.length; i++) { + final Fields fields = leaves[i].reader.fields(); + if (fields != null) { + final Terms terms = fields.terms(field); + if (terms != null) { + final TermsEnum termsEnum = terms.getThreadTermsEnum(); // thread-private don't share! + if (SeekStatus.FOUND == termsEnum.seek(bytes, cache)) { + final TermState termState = termsEnum.termState(); + perReaderTermState.register(termState, leaves[i].ord, termsEnum.docFreq()); + } + } + } + } + return perReaderTermState; + } + + /** + * Clears the {@link PerReaderTermState} internal state and removes all + * registered {@link TermState}s + */ + public void clear() { + docFreq = 0; + Arrays.fill(states, null); + } + + /** + * Registers and associates a {@link TermState} with an leaf ordinal. The leaf ordinal + * should be derived from a {@link ReaderContext}'s leaf ord. + */ + public void register(TermState state, final int ord, final int docFreq) { + assert state != null : "state must not be null"; + assert ord >= 0 && ord < states.length; + assert states[ord] == null : "state for ord: " + ord + + " already registered"; + this.docFreq += docFreq; + states[ord] = state; + } + + /** + * Returns the {@link TermState} for an leaf ordinal or null if no + * {@link TermState} for the ordinal was registered. + * + * @param ord + * the readers leaf ordinal to get the {@link TermState} for. + * @return the {@link TermState} for the given readers ord or null if no + * {@link TermState} for the reader was registered + */ + public TermState get(int ord) { + assert ord >= 0 && ord < states.length; + return states[ord]; + } + + /** + * Returns the accumulated document frequency of all {@link TermState} + * instances passed to {@link #register(TermState, int)}. + * @return the accumulated document frequency of all {@link TermState} + * instances passed to {@link #register(TermState, int)}. + */ + public int docFreq() { + return docFreq; + } +} \ No newline at end of file diff --git a/lucene/src/test/org/apache/lucene/TestExternalCodecs.java b/lucene/src/test/org/apache/lucene/TestExternalCodecs.java index 8c5f7bcaa12..0b97c1bef31 100644 --- a/lucene/src/test/org/apache/lucene/TestExternalCodecs.java +++ b/lucene/src/test/org/apache/lucene/TestExternalCodecs.java @@ -18,6 +18,7 @@ package org.apache.lucene; */ import org.apache.lucene.util.*; +import org.apache.lucene.util.Bits; import org.apache.lucene.index.*; import org.apache.lucene.document.*; import org.apache.lucene.search.*; @@ -329,10 +330,6 @@ public class TestExternalCodecs extends LuceneTestCase { return ramField.termToDocs.get(current).docs.size(); } - @Override - public void cacheCurrentTerm() { - } - @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) { return new RAMDocsEnum(ramField.termToDocs.get(current), skipDocs); diff --git a/lucene/src/test/org/apache/lucene/search/QueryUtils.java b/lucene/src/test/org/apache/lucene/search/QueryUtils.java index 1b3002211b7..d5754321591 100644 --- a/lucene/src/test/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test/org/apache/lucene/search/QueryUtils.java @@ -212,8 +212,6 @@ public class QueryUtils { throw e2; } } - - /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc * and ensure a hitcollector receives same docs and scores diff --git a/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java b/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java index df4b54cda8f..90eff7ba07d 100644 --- a/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java +++ b/lucene/src/test/org/apache/lucene/util/automaton/fst/TestFSTs.java @@ -40,6 +40,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiFields; +import org.apache.lucene.index.OrdTermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.codecs.CodecProvider; diff --git a/solr/src/java/org/apache/solr/request/UnInvertedField.java b/solr/src/java/org/apache/solr/request/UnInvertedField.java index 3845ec9ba31..7e6bf9978db 100755 --- a/solr/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/src/java/org/apache/solr/request/UnInvertedField.java @@ -1000,10 +1000,6 @@ class NumberedTermsEnum extends TermsEnum { return tenum.docFreq(); } - @Override - public void cacheCurrentTerm() { - throw new UnsupportedOperationException(); - } public BytesRef skipTo(BytesRef target) throws IOException { From cfcaa9edcc4a0d1b6bcc1cbbc37c377bc2c100fc Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Thu, 13 Jan 2011 00:08:48 +0000 Subject: [PATCH 058/252] LUCENE-2846: remove fake norms and invalid uses of Similarity.getDefault git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058367 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 19 ++ .../instantiated/InstantiatedIndexReader.java | 9 - .../instantiated/InstantiatedIndexWriter.java | 6 +- .../store/instantiated/TestEmptyIndex.java | 6 - .../store/instantiated/TestIndicesEquals.java | 29 -- .../lucene/index/memory/MemoryIndex.java | 7 - .../org/apache/lucene/index/CheckIndex.java | 4 +- .../apache/lucene/index/DirectoryReader.java | 6 - .../org/apache/lucene/index/FieldInfo.java | 4 +- .../org/apache/lucene/index/FieldInfos.java | 15 +- .../java/org/apache/lucene/index/Fields.java | 2 +- .../lucene/index/FilterIndexReader.java | 6 - .../org/apache/lucene/index/IndexReader.java | 28 -- .../org/apache/lucene/index/MultiNorms.java | 31 +- .../org/apache/lucene/index/MultiReader.java | 6 - .../org/apache/lucene/index/NormsWriter.java | 12 +- .../lucene/index/NormsWriterPerField.java | 1 - .../apache/lucene/index/ParallelReader.java | 22 +- .../apache/lucene/index/SegmentMerger.java | 19 +- .../apache/lucene/index/SegmentReader.java | 18 -- .../lucene/index/SlowMultiReaderWrapper.java | 21 +- .../org/apache/lucene/search/Similarity.java | 10 - .../index/TestBackwardsCompatibility.java | 13 +- .../lucene/index/TestDeletionPolicy.java | 5 +- .../lucene/index/TestIndexFileDeleter.java | 3 +- .../apache/lucene/index/TestIndexReader.java | 17 +- .../lucene/index/TestIndexReaderClone.java | 6 +- .../index/TestIndexReaderCloneNorms.java | 10 +- .../lucene/index/TestIndexReaderReopen.java | 17 +- .../org/apache/lucene/index/TestNorms.java | 4 +- .../apache/lucene/index/TestOmitNorms.java | 304 ++++++++++++++++++ .../lucene/index/TestParallelReader.java | 4 +- .../lucene/index/TestSegmentReader.java | 9 +- .../lucene/search/TestMatchAllDocsQuery.java | 2 +- .../org/apache/lucene/search/TestSetNorm.java | 8 +- .../apache/solr/search/SolrIndexReader.java | 10 - 36 files changed, 426 insertions(+), 267 deletions(-) create mode 100644 lucene/src/test/org/apache/lucene/index/TestOmitNorms.java diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 05b9e5c963c..98bd2d7b5b7 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -152,6 +152,17 @@ Changes in Runtime Behavior without any changes to the index will not cause any index version increment. (Simon Willnauer, Mike McCandless) +* LUCENE-2846: omitNorms now behaves like omitTermFrequencyAndPositions, if you + omitNorms(true) for field "a" for 1000 documents, but then add a document with + omitNorms(false) for field "a", all documents for field "a" will have no norms. + Previously, Lucene would fill the first 1000 documents with "fake norms" from + Similarity.getDefault(). (Robert Muir, Mike Mccandless) + +* LUCENE-2846: When some documents contain field "a", and others do not, the + documents that don't have the field get a norm byte value of 0. Previously, Lucene + would populate "fake norms" with Similarity.getDefault() for these documents. + (Robert Muir, Mike Mccandless) + API Changes * LUCENE-2302, LUCENE-1458, LUCENE-2111, LUCENE-2514: Terms are no longer @@ -193,6 +204,14 @@ API Changes Collector#setNextReader & FieldComparator#setNextReader now expect an AtomicReaderContext instead of an IndexReader. (Simon Willnauer) +* LUCENE-2846: Remove the deprecated IndexReader.setNorm(int, String, float). + This method was only syntactic sugar for setNorm(int, String, byte), but + using the global Similarity.getDefault().encodeNormValue. Use the byte-based + method instead to ensure that the norm is encoded with your Similarity. + Also removed norms(String, byte[], int), which was only used by MultiReader + for building top-level norms. If you really need a top-level norms, use + MultiNorms or SlowMultiReaderWrapper. (Robert Muir, Mike Mccandless) + New features * LUCENE-2604: Added RegexpQuery support to QueryParser. Regular expressions diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java index 58c5313bed4..3b191b83fc5 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java @@ -333,15 +333,6 @@ public class InstantiatedIndexReader extends IndexReader { return norms; } - @Override - public void norms(String field, byte[] bytes, int offset) throws IOException { - byte[] norms = getIndex().getNormsByFieldNameAndDocumentNumber().get(field); - if (norms == null) { - return; - } - System.arraycopy(norms, 0, bytes, offset, norms.length); - } - @Override protected void doSetNorm(int doc, String field, byte value) throws IOException { if (uncommittedNormsByFieldNameAndDocumentNumber == null) { diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java index 0bfa8bd6e26..f5cd26dfe31 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java @@ -201,9 +201,9 @@ public class InstantiatedIndexWriter implements Closeable { byte[] oldNorms = index.getNormsByFieldNameAndDocumentNumber().get(field); if (oldNorms != null) { System.arraycopy(oldNorms, 0, norms, 0, oldNorms.length); - Arrays.fill(norms, oldNorms.length, norms.length, similarity.encodeNormValue(1.0f)); + Arrays.fill(norms, oldNorms.length, norms.length, (byte) 0); } else { - Arrays.fill(norms, 0, norms.length, similarity.encodeNormValue(1.0f)); + Arrays.fill(norms, 0, norms.length, (byte) 0); } normsByFieldNameAndDocumentNumber.put(field, norms); fieldNames.remove(field); @@ -211,7 +211,7 @@ public class InstantiatedIndexWriter implements Closeable { for (String field : fieldNames) { //System.out.println(field); byte[] norms = new byte[index.getDocumentsByNumber().length + termDocumentInformationFactoryByDocument.size()]; - Arrays.fill(norms, 0, norms.length, similarity.encodeNormValue(1.0f)); + Arrays.fill(norms, 0, norms.length, (byte) 0); normsByFieldNameAndDocumentNumber.put(field, norms); } fieldNames.clear(); diff --git a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestEmptyIndex.java b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestEmptyIndex.java index d6a7cf54a6b..1eb03fdaa5a 100644 --- a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestEmptyIndex.java +++ b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestEmptyIndex.java @@ -71,12 +71,6 @@ public class TestEmptyIndex extends LuceneTestCase { byte[] norms = MultiNorms.norms(r, "foo"); if (norms != null) { assertEquals(0, norms.length); - norms = new byte[10]; - Arrays.fill(norms, (byte)10); - r.norms("foo", norms, 10); - for (byte b : norms) { - assertEquals((byte)10, b); - } } } diff --git a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java index 3d5c247cb7f..1ad0743b635 100644 --- a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java +++ b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java @@ -358,35 +358,6 @@ public class TestIndicesEquals extends LuceneTestCase { for (int i = 0; i < aprioriNorms.length; i++) { assertEquals("norms does not equals for field " + field + " in document " + i, aprioriNorms[i], testNorms[i]); } - - // test norms as used by multireader - - aprioriNorms = new byte[aprioriReader.maxDoc()]; - MultiNorms.norms(aprioriReader, (String) field, aprioriNorms, 0); - - testNorms = new byte[testReader.maxDoc()]; - MultiNorms.norms(testReader, (String) field, testNorms, 0); - - assertEquals(aprioriNorms.length, testNorms.length); - - for (int i = 0; i < aprioriNorms.length; i++) { - assertEquals("norms does not equals for field " + field + " in document " + i, aprioriNorms[i], testNorms[i]); - } - - - // test norms as used by multireader - - aprioriNorms = new byte[aprioriReader.maxDoc() + 10]; - MultiNorms.norms(aprioriReader, (String) field, aprioriNorms, 10); - - testNorms = new byte[testReader.maxDoc() + 10]; - MultiNorms.norms(testReader, (String) field, testNorms, 10); - - assertEquals(aprioriNorms.length, testNorms.length); - - for (int i = 0; i < aprioriNorms.length; i++) { - assertEquals("norms does not equals for field " + field + " in document " + i, aprioriNorms[i], testNorms[i]); - } } } diff --git a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index 08e880bfe99..cd1df94a9c7 100644 --- a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -1185,13 +1185,6 @@ public class MemoryIndex implements Serializable { return norms; } - @Override - public void norms(String fieldName, byte[] bytes, int offset) { - if (DEBUG) System.err.println("MemoryIndexReader.norms*: " + fieldName); - byte[] norms = norms(fieldName); - System.arraycopy(norms, 0, bytes, offset, norms.length); - } - @Override protected void doSetNorm(int doc, String fieldName, byte value) { throw new UnsupportedOperationException(); diff --git a/lucene/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/src/java/org/apache/lucene/index/CheckIndex.java index 392ab635249..e825c670e29 100644 --- a/lucene/src/java/org/apache/lucene/index/CheckIndex.java +++ b/lucene/src/java/org/apache/lucene/index/CheckIndex.java @@ -548,10 +548,10 @@ public class CheckIndex { if (infoStream != null) { infoStream.print(" test: field norms........."); } - final byte[] b = new byte[reader.maxDoc()]; + byte[] b; for (final String fieldName : fieldNames) { if (reader.hasNorms(fieldName)) { - reader.norms(fieldName, b, 0); + b = reader.norms(fieldName); ++status.totFields; } } diff --git a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java index c4ed2633760..9da85ca5e6a 100644 --- a/lucene/src/java/org/apache/lucene/index/DirectoryReader.java +++ b/lucene/src/java/org/apache/lucene/index/DirectoryReader.java @@ -601,12 +601,6 @@ class DirectoryReader extends IndexReader implements Cloneable { throw new UnsupportedOperationException("please use MultiNorms.norms, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level norms"); } - @Override - public synchronized void norms(String field, byte[] result, int offset) - throws IOException { - throw new UnsupportedOperationException("please use MultiNorms.norms, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level norms"); - } - @Override protected void doSetNorm(int n, String field, byte value) throws CorruptIndexException, IOException { diff --git a/lucene/src/java/org/apache/lucene/index/FieldInfo.java b/lucene/src/java/org/apache/lucene/index/FieldInfo.java index 9526a7b40cf..2477f9e5c1f 100644 --- a/lucene/src/java/org/apache/lucene/index/FieldInfo.java +++ b/lucene/src/java/org/apache/lucene/index/FieldInfo.java @@ -52,7 +52,7 @@ public final class FieldInfo { this.storeOffsetWithTermVector = false; this.storePositionWithTermVector = false; this.storePayloads = false; - this.omitNorms = true; + this.omitNorms = false; this.omitTermFreqAndPositions = false; } } @@ -82,7 +82,7 @@ public final class FieldInfo { this.storePayloads = true; } if (this.omitNorms != omitNorms) { - this.omitNorms = false; // once norms are stored, always store + this.omitNorms = true; // if one require omitNorms at least once, it remains off for life } if (this.omitTermFreqAndPositions != omitTermFreqAndPositions) { this.omitTermFreqAndPositions = true; // if one require omitTermFreqAndPositions at least once, it remains off for life diff --git a/lucene/src/java/org/apache/lucene/index/FieldInfos.java b/lucene/src/java/org/apache/lucene/index/FieldInfos.java index 0fb4878b4be..ef1a3b7476f 100644 --- a/lucene/src/java/org/apache/lucene/index/FieldInfos.java +++ b/lucene/src/java/org/apache/lucene/index/FieldInfos.java @@ -278,14 +278,21 @@ public final class FieldInfos { } public boolean hasVectors() { - boolean hasVectors = false; for (int i = 0; i < size(); i++) { if (fieldInfo(i).storeTermVector) { - hasVectors = true; - break; + return true; } } - return hasVectors; + return false; + } + + public boolean hasNorms() { + for (int i = 0; i < size(); i++) { + if (!fieldInfo(i).omitNorms) { + return true; + } + } + return false; } public void write(Directory d, String name) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/index/Fields.java b/lucene/src/java/org/apache/lucene/index/Fields.java index a14ca1d52c3..d7b0bba997f 100644 --- a/lucene/src/java/org/apache/lucene/index/Fields.java +++ b/lucene/src/java/org/apache/lucene/index/Fields.java @@ -28,7 +28,7 @@ public abstract class Fields { * names. This will not return null. */ public abstract FieldsEnum iterator() throws IOException; - /** Get the {@link Terms} for this field. This may return + /** Get the {@link Terms} for this field. This will return * null if the field does not exist. */ public abstract Terms terms(String field) throws IOException; diff --git a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java index 8246fe4894d..ffe82b017dc 100644 --- a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java @@ -355,12 +355,6 @@ public class FilterIndexReader extends IndexReader { return in.norms(f); } - @Override - public void norms(String f, byte[] bytes, int offset) throws IOException { - ensureOpen(); - in.norms(f, bytes, offset); - } - @Override protected void doSetNorm(int d, String f, byte b) throws CorruptIndexException, IOException { in.setNorm(d, f, b); diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index 6a23da780fc..95f4977f177 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -931,14 +931,6 @@ public abstract class IndexReader implements Cloneable,Closeable { */ public abstract byte[] norms(String field) throws IOException; - /** Reads the byte-encoded normalization factor for the named field of every - * document. This is used by the search code to score documents. - * - * @see org.apache.lucene.document.Field#setBoost(float) - */ - public abstract void norms(String field, byte[] bytes, int offset) - throws IOException; - /** Expert: Resets the normalization factor for the named field of the named * document. The norm represents the product of the field's {@link * org.apache.lucene.document.Fieldable#setBoost(float) boost} and its {@link Similarity#lengthNorm(String, @@ -970,26 +962,6 @@ public abstract class IndexReader implements Cloneable,Closeable { protected abstract void doSetNorm(int doc, String field, byte value) throws CorruptIndexException, IOException; - /** Expert: Resets the normalization factor for the named field of the named - * document. - * - * @see #norms(String) - * @see Similarity#decodeNormValue(byte) - * - * @throws StaleReaderException if the index has changed - * since this reader was opened - * @throws CorruptIndexException if the index is corrupt - * @throws LockObtainFailedException if another writer - * has this index open (write.lock could not - * be obtained) - * @throws IOException if there is a low-level IO error - */ - public void setNorm(int doc, String field, float value) - throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { - ensureOpen(); - setNorm(doc, field, Similarity.getDefault().encodeNormValue(value)); - } - /** Flex API: returns {@link Fields} for this reader. * This method may return null if the reader has no * postings. diff --git a/lucene/src/java/org/apache/lucene/index/MultiNorms.java b/lucene/src/java/org/apache/lucene/index/MultiNorms.java index 34bd967c73e..1026480fb29 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiNorms.java +++ b/lucene/src/java/org/apache/lucene/index/MultiNorms.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import org.apache.lucene.search.Similarity; import org.apache.lucene.util.ReaderUtil; /** @@ -61,26 +60,24 @@ public class MultiNorms { ReaderUtil.gatherSubReaders(leaves, r); int end = 0; for (IndexReader leaf : leaves) { + Fields fields = leaf.fields(); + boolean hasField = (fields != null && fields.terms(field) != null); + int start = end; - leaf.norms(field, norms, start); + byte leafNorms[] = leaf.norms(field); + if (leafNorms == null) { + if (hasField) { // omitted norms + return null; + } + // doesn't have field, fill bytes + leafNorms = new byte[leaf.maxDoc()]; + Arrays.fill(leafNorms, (byte) 0); + } + + System.arraycopy(leafNorms, 0, norms, start, leafNorms.length); end += leaf.maxDoc(); } return norms; } } - - /** - * Warning: this is heavy! Do not use in a loop, or implement norms() - * in your own reader with this (you should likely cache the result). - */ - public static void norms(IndexReader r, String field, byte[] bytes, int offset) - throws IOException { - // TODO: optimize more maybe - byte[] norms = norms(r, field); - if (norms == null) { - Arrays.fill(bytes, offset, bytes.length, Similarity.getDefault().encodeNormValue(1.0f)); - } else { - System.arraycopy(norms, 0, bytes, offset, r.maxDoc()); - } - } } diff --git a/lucene/src/java/org/apache/lucene/index/MultiReader.java b/lucene/src/java/org/apache/lucene/index/MultiReader.java index 37328d1314a..8a5dca94f22 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiReader.java +++ b/lucene/src/java/org/apache/lucene/index/MultiReader.java @@ -304,12 +304,6 @@ public class MultiReader extends IndexReader implements Cloneable { throw new UnsupportedOperationException("please use MultiNorms.norms, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level norms"); } - @Override - public synchronized void norms(String field, byte[] result, int offset) - throws IOException { - throw new UnsupportedOperationException("please use MultiNorms.norms, or wrap your IndexReader with SlowMultiReaderWrapper, if you really need a top level norms"); - } - @Override protected void doSetNorm(int n, String field, byte value) throws CorruptIndexException, IOException { diff --git a/lucene/src/java/org/apache/lucene/index/NormsWriter.java b/lucene/src/java/org/apache/lucene/index/NormsWriter.java index 036832297cf..82b4a730e5b 100644 --- a/lucene/src/java/org/apache/lucene/index/NormsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/NormsWriter.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.ArrayList; import org.apache.lucene.store.IndexOutput; -import org.apache.lucene.search.Similarity; // TODO FI: norms could actually be stored as doc store @@ -37,7 +36,6 @@ import org.apache.lucene.search.Similarity; final class NormsWriter extends InvertedDocEndConsumer { - private final byte defaultNorm = Similarity.getDefault().encodeNormValue(1.0f); private FieldInfos fieldInfos; @Override public InvertedDocEndConsumerPerThread addThread(DocInverterPerThread docInverterPerThread) { @@ -62,6 +60,10 @@ final class NormsWriter extends InvertedDocEndConsumer { final Map> byField = new HashMap>(); + if (!fieldInfos.hasNorms()) { + return; + } + // Typically, each thread will have encountered the same // field. So first we collate by field, ie, all // per-thread field instances that correspond to the @@ -137,7 +139,7 @@ final class NormsWriter extends InvertedDocEndConsumer { // Fill hole for(;upto - * WARNING: If you override this method, you should change the default - * Similarity to your implementation with {@link Similarity#setDefault(Similarity)}. - * Otherwise, your method may not always be called, especially if you omit norms - * for some fields. * @see #encodeNormValue(float) */ public float decodeNormValue(byte b) { @@ -662,11 +657,6 @@ public abstract class Similarity implements Serializable { * are rounded down to the largest representable value. Positive values too * small to represent are rounded up to the smallest positive representable * value. - *

    - * WARNING: If you override this method, you should change the default - * Similarity to your implementation with {@link Similarity#setDefault(Similarity)}. - * Otherwise, your method may not always be called, especially if you omit norms - * for some fields. * @see org.apache.lucene.document.Field#setBoost(float) * @see org.apache.lucene.util.SmallFloat */ diff --git a/lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java b/lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java index e85e4fb4bc5..ffa6238b072 100644 --- a/lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java +++ b/lucene/src/test/org/apache/lucene/index/TestBackwardsCompatibility.java @@ -43,6 +43,7 @@ import org.apache.lucene.search.FieldCache; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Similarity; import org.apache.lucene.search.TermQuery; import org.apache.lucene.store.Directory; import org.apache.lucene.util.Bits; @@ -216,6 +217,9 @@ public class TestBackwardsCompatibility extends LuceneTestCase { public void testOptimizeOldIndex() throws Exception { for(int i=0;i Date: Thu, 13 Jan 2011 02:39:35 +0000 Subject: [PATCH 059/252] SOLR-2282: use solr home properly in the test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058393 13f79535-47bb-0310-9956-ffa450edef68 --- .../clustering/DistributedClusteringComponentTest.java | 6 ++++++ .../org/apache/solr/BaseDistributedSearchTestCase.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java index 1b815b2cb0d..51c9726d95f 100644 --- a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java +++ b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java @@ -26,6 +26,12 @@ import org.junit.Ignore; public class DistributedClusteringComponentTest extends BaseDistributedSearchTestCase { + @Override + public String getSolrHome() { + // TODO: this should work with just "solr-clustering"... + return getFile("solr-clustering").getAbsolutePath(); + } + @Override public void doTest() throws Exception { del("*:*"); diff --git a/solr/src/test/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/src/test/org/apache/solr/BaseDistributedSearchTestCase.java index 945d54da3e1..33839c86c3d 100644 --- a/solr/src/test/org/apache/solr/BaseDistributedSearchTestCase.java +++ b/solr/src/test/org/apache/solr/BaseDistributedSearchTestCase.java @@ -124,12 +124,21 @@ public abstract class BaseDistributedSearchTestCase extends SolrTestCaseJ4 { return randVals; } + /** + * Subclasses can override this to change a test's solr home + * (default is in test-files) + */ + public String getSolrHome() { + return SolrTestCaseJ4.TEST_HOME; + } + @Override public void setUp() throws Exception { SolrTestCaseJ4.resetExceptionIgnores(); // ignore anything with ignore_exception in it super.setUp(); System.setProperty("solr.test.sys.prop1", "propone"); System.setProperty("solr.test.sys.prop2", "proptwo"); + System.setProperty("solr.solr.home", getSolrHome()); testDir = new File(TEMP_DIR, getClass().getName() + "-" + System.currentTimeMillis()); testDir.mkdirs(); From f19e8c58fbb2b24de6037eee84adc0cbcbc99200 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 13 Jan 2011 07:13:23 +0000 Subject: [PATCH 060/252] LUCENE-2831: Cut over ValueSource#docValues to AtomicReaderContext & removed SolrIndexReader git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058431 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/search/IndexSearcher.java | 28 +- .../org/apache/lucene/search/TermQuery.java | 11 +- .../search/function/FieldCacheSource.java | 5 +- .../search/function/MultiValueSource.java | 62 +-- .../search/function/OrdFieldSource.java | 6 +- .../function/ReverseOrdFieldSource.java | 6 +- .../lucene/search/function/ValueSource.java | 21 +- .../search/function/ValueSourceQuery.java | 9 +- .../org/apache/lucene/util/ReaderUtil.java | 11 + .../function/JustCompileSearchSpans.java | 3 +- .../search/function/TestFieldScoreQuery.java | 25 +- .../lucene/search/function/TestOrdValues.java | 29 +- .../search/function/TestValueSource.java | 15 +- .../java/org/apache/solr/core/SolrCore.java | 2 +- .../solr/handler/MoreLikeThisHandler.java | 2 +- .../solr/handler/ReplicationHandler.java | 8 +- .../org/apache/solr/handler/SnapPuller.java | 2 +- .../solr/handler/admin/CoreAdminHandler.java | 2 +- .../handler/admin/LukeRequestHandler.java | 4 +- .../handler/component/HighlightComponent.java | 2 +- .../component/QueryElevationComponent.java | 4 +- .../component/SpellCheckComponent.java | 4 +- .../handler/component/StatsComponent.java | 4 +- .../component/TermVectorComponent.java | 2 +- .../highlight/DefaultSolrHighlighter.java | 6 +- .../org/apache/solr/request/SimpleFacets.java | 4 +- .../apache/solr/request/UnInvertedField.java | 8 +- .../org/apache/solr/schema/DateField.java | 6 +- .../org/apache/solr/schema/LatLonType.java | 13 +- .../apache/solr/schema/RandomSortField.java | 20 +- .../solr/schema/SortableDoubleField.java | 6 +- .../solr/schema/SortableFloatField.java | 6 +- .../apache/solr/schema/SortableIntField.java | 6 +- .../apache/solr/schema/SortableLongField.java | 6 +- .../apache/solr/schema/StrFieldSource.java | 6 +- .../java/org/apache/solr/search/Grouping.java | 4 +- .../org/apache/solr/search/SolrFilter.java | 4 +- .../apache/solr/search/SolrIndexReader.java | 505 ------------------ .../apache/solr/search/SolrIndexSearcher.java | 21 +- .../apache/solr/search/ValueSourceParser.java | 14 +- .../solr/search/function/BoostedQuery.java | 16 +- .../solr/search/function/ByteFieldSource.java | 6 +- .../search/function/ConstValueSource.java | 4 +- .../search/function/DocFreqValueSource.java | 4 +- .../function/DoubleConstValueSource.java | 4 +- .../search/function/DoubleFieldSource.java | 5 +- .../search/function/DualFloatFunction.java | 8 +- .../solr/search/function/FileFloatSource.java | 17 +- .../search/function/FloatFieldSource.java | 6 +- .../solr/search/function/FunctionQuery.java | 7 +- .../solr/search/function/IDFValueSource.java | 3 +- .../solr/search/function/IntFieldSource.java | 5 +- .../function/JoinDocFreqValueSource.java | 20 +- .../search/function/LinearFloatFunction.java | 6 +- .../search/function/LiteralValueSource.java | 4 +- .../solr/search/function/LongFieldSource.java | 5 +- .../search/function/MaxDocValueSource.java | 4 +- .../search/function/MaxFloatFunction.java | 6 +- .../search/function/MultiFloatFunction.java | 6 +- .../solr/search/function/NormValueSource.java | 6 +- .../search/function/NumDocsValueSource.java | 10 +- .../solr/search/function/OrdFieldSource.java | 20 +- .../search/function/QueryValueSource.java | 42 +- .../function/RangeMapFloatFunction.java | 6 +- .../function/ReciprocalFloatFunction.java | 6 +- .../function/ReverseOrdFieldSource.java | 18 +- .../search/function/ScaleFloatFunction.java | 15 +- .../search/function/ShortFieldSource.java | 6 +- .../search/function/SimpleFloatFunction.java | 6 +- .../search/function/StringIndexDocValues.java | 5 +- .../solr/search/function/TFValueSource.java | 6 +- .../search/function/TermFreqValueSource.java | 6 +- .../solr/search/function/ValueSource.java | 41 +- .../function/ValueSourceRangeFilter.java | 6 +- .../search/function/VectorValueSource.java | 10 +- .../function/distance/GeohashFunction.java | 8 +- .../distance/GeohashHaversineFunction.java | 8 +- .../distance/HaversineConstFunction.java | 8 +- .../function/distance/HaversineFunction.java | 8 +- .../distance/StringDistanceFunction.java | 8 +- .../distance/VectorDistanceFunction.java | 8 +- .../solr/spelling/IndexBasedSpellChecker.java | 2 +- .../solr/spelling/suggest/Suggester.java | 2 +- .../org/apache/solr/update/UpdateHandler.java | 2 +- .../test/org/apache/solr/core/TestConfig.java | 2 +- .../solr/core/TestQuerySenderListener.java | 2 +- .../QueryElevationComponentTest.java | 8 +- .../org/apache/solr/request/TestFaceting.java | 4 +- .../apache/solr/search/TestIndexSearcher.java | 2 +- .../spelling/DirectSolrSpellCheckerTest.java | 2 +- .../spelling/FileBasedSpellCheckerTest.java | 6 +- .../spelling/IndexBasedSpellCheckerTest.java | 6 +- .../SignatureUpdateProcessorFactoryTest.java | 2 +- .../servlet/cache/HttpCacheHeaderUtil.java | 4 +- 94 files changed, 393 insertions(+), 946 deletions(-) delete mode 100755 solr/src/java/org/apache/solr/search/SolrIndexReader.java diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 9bd72d426db..9e587962ea6 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -174,20 +174,34 @@ public class IndexSearcher { } } } - - /* Ctor for concurrent sub-searchers searching only on a specific leaf of the given top-reader context - * - instead of searching over all leaves this searcher only searches a single leaf searcher slice. Hence, - * for scorer and filter this looks like an ordinary search in the hierarchy such that there is no difference - * between single and multi-threaded */ - private IndexSearcher(ReaderContext topLevel, AtomicReaderContext leaf) { + + /** + * Expert: Creates a searcher from a top-level {@link ReaderContext} with and + * executes searches on the given leave slice exclusively instead of searching + * over all leaves. This constructor should be used to run one or more leaves + * within a single thread. Hence, for scorer and filter this looks like an + * ordinary search in the hierarchy such that there is no difference between + * single and multi-threaded. + * + * @lucene.experimental + * */ + public IndexSearcher(ReaderContext topLevel, AtomicReaderContext... leaves) { + assert assertLeaves(topLevel, leaves); readerContext = topLevel; reader = topLevel.reader; - leafContexts = new AtomicReaderContext[] {leaf}; + leafContexts = leaves; executor = null; subSearchers = null; closeReader = false; } + private boolean assertLeaves(ReaderContext topLevel, AtomicReaderContext... leaves) { + for (AtomicReaderContext leaf : leaves) { + assert ReaderUtil.getTopLevelContext(leaf) == topLevel : "leaf context is not a leaf of the given top-level context"; + } + return true; + } + /** Return the {@link IndexReader} this searches. */ public IndexReader getIndexReader() { return reader; diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index aa41c1240a7..56d0dcd63d1 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -30,6 +30,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.search.Explanation.IDFExplanation; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.PerReaderTermState; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.ToStringUtils; /** A Query that matches documents containing a term. @@ -88,7 +89,7 @@ public class TermQuery extends Query { public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { final String field = term.field(); final IndexReader reader = context.reader; - assert assertTopReaderContext(termStates, context) : "The top-reader used to create Weight is not the same as the current reader's top-reader"; + assert termStates.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight is not the same as the current reader's top-reader"; final TermState state = termStates .get(context.ord); if (state == null) { // term is not present in that reader @@ -106,14 +107,6 @@ public class TermQuery extends Query { return terms == null || terms.docFreq(bytes) == 0; } - private boolean assertTopReaderContext(PerReaderTermState state, ReaderContext context) { - while(context.parent != null) { - context = context.parent; - } - return state.topReaderContext == context; - } - - @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/search/function/FieldCacheSource.java b/lucene/src/java/org/apache/lucene/search/function/FieldCacheSource.java index b55ae5ff820..c079ebddb81 100644 --- a/lucene/src/java/org/apache/lucene/search/function/FieldCacheSource.java +++ b/lucene/src/java/org/apache/lucene/search/function/FieldCacheSource.java @@ -20,6 +20,7 @@ package org.apache.lucene.search.function; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldCache; /** @@ -55,8 +56,8 @@ public abstract class FieldCacheSource extends ValueSource { /* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#getValues(org.apache.lucene.index.IndexReader) */ @Override - public final DocValues getValues(IndexReader reader) throws IOException { - return getCachedFieldValues(FieldCache.DEFAULT, field, reader); + public final DocValues getValues(AtomicReaderContext context) throws IOException { + return getCachedFieldValues(FieldCache.DEFAULT, field, context.reader); } /* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#description() */ diff --git a/lucene/src/java/org/apache/lucene/search/function/MultiValueSource.java b/lucene/src/java/org/apache/lucene/search/function/MultiValueSource.java index 534cd1230b9..7dbccb25a69 100644 --- a/lucene/src/java/org/apache/lucene/search/function/MultiValueSource.java +++ b/lucene/src/java/org/apache/lucene/search/function/MultiValueSource.java @@ -20,6 +20,9 @@ package org.apache.lucene.search.function; import java.io.IOException; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.Explanation; import org.apache.lucene.util.ReaderUtil; @@ -44,16 +47,16 @@ public final class MultiValueSource extends ValueSource { } @Override - public DocValues getValues(IndexReader reader) throws IOException { - - IndexReader[] subReaders = reader.getSequentialSubReaders(); - if (subReaders != null) { - // This is a composite reader - return new MultiDocValues(subReaders); - } else { + public DocValues getValues(AtomicReaderContext context) throws IOException { // Already an atomic reader -- just delegate - return other.getValues(reader); + return other.getValues(context); + } + + public DocValues getValues(ReaderContext context) throws IOException { + if (context.isAtomic) { + return getValues((AtomicReaderContext) context); } + return new MultiDocValues(ReaderUtil.leaves(context)); } @Override @@ -78,59 +81,56 @@ public final class MultiValueSource extends ValueSource { private final class MultiDocValues extends DocValues { final DocValues[] docValues; - final int[] docStarts; + final AtomicReaderContext[] leaves; - MultiDocValues(IndexReader[] subReaders) throws IOException { - docValues = new DocValues[subReaders.length]; - docStarts = new int[subReaders.length]; - int base = 0; - for(int i=0;in in the diff --git a/lucene/src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java b/lucene/src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java index a85f040352c..96f5032c629 100644 --- a/lucene/src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java +++ b/lucene/src/test/org/apache/lucene/search/function/JustCompileSearchSpans.java @@ -18,6 +18,7 @@ package org.apache.lucene.search.function; */ import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldCache; import java.io.IOException; @@ -82,7 +83,7 @@ final class JustCompileSearchFunction { } @Override - public DocValues getValues(IndexReader reader) throws IOException { + public DocValues getValues(AtomicReaderContext context) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java b/lucene/src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java index 8ff2af949d9..a90be6ec36c 100755 --- a/lucene/src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java +++ b/lucene/src/test/org/apache/lucene/search/function/TestFieldScoreQuery.java @@ -19,12 +19,13 @@ package org.apache.lucene.search.function; import java.util.HashMap; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.QueryUtils; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; +import org.apache.lucene.util.ReaderUtil; import org.junit.Test; /** @@ -185,12 +186,12 @@ public class TestFieldScoreQuery extends FunctionTestSetup { FieldScoreQuery q = new FieldScoreQuery(field,tp); ScoreDoc[] h = s.search(q, null, 1000).scoreDocs; assertEquals("All docs should be matched!",N_DOCS,h.length); - IndexReader[] readers = s.getIndexReader().getSequentialSubReaders(); - for (int j = 0; j < readers.length; j++) { - IndexReader reader = readers[j]; + AtomicReaderContext[] leaves = ReaderUtil.leaves(s.getTopReaderContext()); + for (int j = 0; j < leaves.length; j++) { + AtomicReaderContext leaf = leaves[j]; try { if (i == 0) { - innerArray[j] = q.valSrc.getValues(reader).getInnerArray(); + innerArray[j] = q.valSrc.getValues(leaf).getInnerArray(); log(i + ". compare: " + innerArray[j].getClass() + " to " + expectedArrayTypes.get(tp).getClass()); assertEquals( @@ -198,9 +199,9 @@ public class TestFieldScoreQuery extends FunctionTestSetup { innerArray[j].getClass(), expectedArrayTypes.get(tp).getClass()); } else { log(i + ". compare: " + innerArray[j] + " to " - + q.valSrc.getValues(reader).getInnerArray()); + + q.valSrc.getValues(leaf).getInnerArray()); assertSame("field values should be cached and reused!", innerArray[j], - q.valSrc.getValues(reader).getInnerArray()); + q.valSrc.getValues(leaf).getInnerArray()); } } catch (UnsupportedOperationException e) { if (!warned) { @@ -217,15 +218,15 @@ public class TestFieldScoreQuery extends FunctionTestSetup { FieldScoreQuery q = new FieldScoreQuery(field,tp); ScoreDoc[] h = s.search(q, null, 1000).scoreDocs; assertEquals("All docs should be matched!",N_DOCS,h.length); - IndexReader[] readers = s.getIndexReader().getSequentialSubReaders(); - for (int j = 0; j < readers.length; j++) { - IndexReader reader = readers[j]; + AtomicReaderContext[] leaves = ReaderUtil.leaves(s.getTopReaderContext()); + for (int j = 0; j < leaves.length; j++) { + AtomicReaderContext leaf = leaves[j]; try { log("compare: " + innerArray + " to " - + q.valSrc.getValues(reader).getInnerArray()); + + q.valSrc.getValues(leaf).getInnerArray()); assertNotSame( "cached field values should not be reused if reader as changed!", - innerArray, q.valSrc.getValues(reader).getInnerArray()); + innerArray, q.valSrc.getValues(leaf).getInnerArray()); } catch (UnsupportedOperationException e) { if (!warned) { System.err.println("WARNING: " + testName() diff --git a/lucene/src/test/org/apache/lucene/search/function/TestOrdValues.java b/lucene/src/test/org/apache/lucene/search/function/TestOrdValues.java index 8fb7eda1484..706eca76f43 100644 --- a/lucene/src/test/org/apache/lucene/search/function/TestOrdValues.java +++ b/lucene/src/test/org/apache/lucene/search/function/TestOrdValues.java @@ -18,8 +18,9 @@ package org.apache.lucene.search.function; */ import org.apache.lucene.index.CorruptIndexException; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; +import org.apache.lucene.util.ReaderUtil; import org.junit.Test; /** @@ -168,14 +169,14 @@ public class TestOrdValues extends FunctionTestSetup { ScoreDoc[] h = s.search(q, null, 1000).scoreDocs; try { assertEquals("All docs should be matched!", N_DOCS, h.length); - IndexReader[] readers = s.getIndexReader().getSequentialSubReaders(); + AtomicReaderContext[] leaves = ReaderUtil.leaves(s.getTopReaderContext()); - for (IndexReader reader : readers) { + for (AtomicReaderContext leaf : leaves) { if (i == 0) { - innerArray = q.valSrc.getValues(reader).getInnerArray(); + innerArray = q.valSrc.getValues(leaf).getInnerArray(); } else { - log(i + ". compare: " + innerArray + " to " + q.valSrc.getValues(reader).getInnerArray()); - assertSame("field values should be cached and reused!", innerArray, q.valSrc.getValues(reader).getInnerArray()); + log(i + ". compare: " + innerArray + " to " + q.valSrc.getValues(leaf).getInnerArray()); + assertSame("field values should be cached and reused!", innerArray, q.valSrc.getValues(leaf).getInnerArray()); } } } catch (UnsupportedOperationException e) { @@ -201,15 +202,15 @@ public class TestOrdValues extends FunctionTestSetup { q = new ValueSourceQuery(vs); h = s.search(q, null, 1000).scoreDocs; assertEquals("All docs should be matched!", N_DOCS, h.length); - IndexReader[] readers = s.getIndexReader().getSequentialSubReaders(); + AtomicReaderContext[] leaves = ReaderUtil.leaves(s.getTopReaderContext()); - for (IndexReader reader : readers) { + for (AtomicReaderContext leaf : leaves) { try { log("compare (should differ): " + innerArray + " to " - + q.valSrc.getValues(reader).getInnerArray()); + + q.valSrc.getValues(leaf).getInnerArray()); assertNotSame( "different values should be loaded for a different field!", - innerArray, q.valSrc.getValues(reader).getInnerArray()); + innerArray, q.valSrc.getValues(leaf).getInnerArray()); } catch (UnsupportedOperationException e) { if (!warned) { System.err.println("WARNING: " + testName() @@ -229,15 +230,15 @@ public class TestOrdValues extends FunctionTestSetup { q = new ValueSourceQuery(vs); h = s.search(q, null, 1000).scoreDocs; assertEquals("All docs should be matched!", N_DOCS, h.length); - readers = s.getIndexReader().getSequentialSubReaders(); + leaves = ReaderUtil.leaves(s.getTopReaderContext()); - for (IndexReader reader : readers) { + for (AtomicReaderContext leaf : leaves) { try { log("compare (should differ): " + innerArray + " to " - + q.valSrc.getValues(reader).getInnerArray()); + + q.valSrc.getValues(leaf).getInnerArray()); assertNotSame( "cached field values should not be reused if reader as changed!", - innerArray, q.valSrc.getValues(reader).getInnerArray()); + innerArray, q.valSrc.getValues(leaf).getInnerArray()); } catch (UnsupportedOperationException e) { if (!warned) { System.err.println("WARNING: " + testName() diff --git a/lucene/src/test/org/apache/lucene/search/function/TestValueSource.java b/lucene/src/test/org/apache/lucene/search/function/TestValueSource.java index 38b6e9cd91f..d6b9f780dae 100644 --- a/lucene/src/test/org/apache/lucene/search/function/TestValueSource.java +++ b/lucene/src/test/org/apache/lucene/search/function/TestValueSource.java @@ -22,6 +22,7 @@ import org.apache.lucene.store.*; import org.apache.lucene.search.*; import org.apache.lucene.analysis.*; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.document.*; public class TestValueSource extends LuceneTestCase { @@ -45,11 +46,17 @@ public class TestValueSource extends LuceneTestCase { assertTrue(r.getSequentialSubReaders().length > 1); ValueSource s1 = new IntFieldSource("field"); - DocValues v1 = s1.getValues(r); - DocValues v2 = new MultiValueSource(s1).getValues(r); - + AtomicReaderContext[] leaves = ReaderUtil.leaves(r.getTopReaderContext()); + DocValues v1 = null; + DocValues v2 = new MultiValueSource(s1).getValues(r.getTopReaderContext()); + int leafOrd = -1; for(int i=0;i searcher = core.getSearcher(); try { - version[0] = searcher.get().getReader().getIndexCommit().getVersion(); - version[1] = searcher.get().getReader().getIndexCommit().getGeneration(); + version[0] = searcher.get().getIndexReader().getIndexCommit().getVersion(); + version[1] = searcher.get().getIndexReader().getIndexCommit().getGeneration(); } catch (IOException e) { LOG.warn("Unable to get index version : ", e); } finally { @@ -823,7 +823,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw replicateOnStart = true; RefCounted s = core.getNewestSearcher(false); try { - IndexReader reader = s==null ? null : s.get().getReader(); + IndexReader reader = s==null ? null : s.get().getIndexReader(); if (reader!=null && reader.getIndexCommit() != null && reader.getIndexCommit().getGeneration() != 1L) { try { if(replicateOnOptimize){ diff --git a/solr/src/java/org/apache/solr/handler/SnapPuller.java b/solr/src/java/org/apache/solr/handler/SnapPuller.java index 1a41f827680..88ac16671cf 100644 --- a/solr/src/java/org/apache/solr/handler/SnapPuller.java +++ b/solr/src/java/org/apache/solr/handler/SnapPuller.java @@ -269,7 +269,7 @@ public class SnapPuller { RefCounted searcherRefCounted = null; try { searcherRefCounted = core.getNewestSearcher(false); - commit = searcherRefCounted.get().getReader().getIndexCommit(); + commit = searcherRefCounted.get().getIndexReader().getIndexCommit(); } finally { if (searcherRefCounted != null) searcherRefCounted.decref(); diff --git a/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java index 39dc8cd136a..aa0d3ee9b9a 100644 --- a/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java +++ b/solr/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java @@ -470,7 +470,7 @@ public class CoreAdminHandler extends RequestHandlerBase { info.add("uptime", System.currentTimeMillis() - core.getStartTime()); RefCounted searcher = core.getSearcher(); try { - info.add("index", LukeRequestHandler.getIndexInfo(searcher.get().getReader(), false)); + info.add("index", LukeRequestHandler.getIndexInfo(searcher.get().getIndexReader(), false)); } finally { searcher.decref(); } diff --git a/solr/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java b/solr/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java index 76c28f85720..c11b0ace7f3 100644 --- a/solr/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java +++ b/solr/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java @@ -97,7 +97,7 @@ public class LukeRequestHandler extends RequestHandlerBase { IndexSchema schema = req.getSchema(); SolrIndexSearcher searcher = req.getSearcher(); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); SolrParams params = req.getParams(); int numTerms = params.getInt( NUMTERMS, DEFAULT_COUNT ); @@ -285,7 +285,7 @@ public class LukeRequestHandler extends RequestHandlerBase final SolrIndexSearcher searcher, final Set fields, final int numTerms ) throws Exception { - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); IndexSchema schema = searcher.getSchema(); // Walk the term enum and keep a priority queue for each map in our set diff --git a/solr/src/java/org/apache/solr/handler/component/HighlightComponent.java b/solr/src/java/org/apache/solr/handler/component/HighlightComponent.java index 255a75691f1..10070d795f7 100644 --- a/solr/src/java/org/apache/solr/handler/component/HighlightComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/HighlightComponent.java @@ -113,7 +113,7 @@ public class HighlightComponent extends SearchComponent implements PluginInfoIni if(highlightQuery != null) { boolean rewrite = !(Boolean.valueOf(req.getParams().get(HighlightParams.USE_PHRASE_HIGHLIGHTER, "true")) && Boolean.valueOf(req.getParams().get(HighlightParams.HIGHLIGHT_MULTI_TERM, "true"))); - highlightQuery = rewrite ? highlightQuery.rewrite(req.getSearcher().getReader()) : highlightQuery; + highlightQuery = rewrite ? highlightQuery.rewrite(req.getSearcher().getIndexReader()) : highlightQuery; } // No highlighting if there is no query -- consider q.alt="*:* diff --git a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java index 65061e231b0..8b4af7d715d 100644 --- a/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/QueryElevationComponent.java @@ -200,7 +200,7 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore RefCounted searchHolder = null; try { searchHolder = core.getNewestSearcher(false); - IndexReader reader = searchHolder.get().getReader(); + IndexReader reader = searchHolder.get().getIndexReader(); getElevationMap( reader, core ); } finally { if (searchHolder != null) searchHolder.decref(); @@ -344,7 +344,7 @@ public class QueryElevationComponent extends SearchComponent implements SolrCore } qstr = getAnalyzedQuery(qstr); - IndexReader reader = req.getSearcher().getReader(); + IndexReader reader = req.getSearcher().getIndexReader(); ElevationObj booster = null; try { booster = getElevationMap( reader, req.getCore() ).get( qstr ); diff --git a/solr/src/java/org/apache/solr/handler/component/SpellCheckComponent.java b/solr/src/java/org/apache/solr/handler/component/SpellCheckComponent.java index efd685dba04..524fc3fa572 100644 --- a/solr/src/java/org/apache/solr/handler/component/SpellCheckComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/SpellCheckComponent.java @@ -143,7 +143,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar boolean extendedResults = params.getBool(SPELLCHECK_EXTENDED_RESULTS, false); NamedList response = new SimpleOrderedMap(); - IndexReader reader = rb.req.getSearcher().getReader(); + IndexReader reader = rb.req.getSearcher().getIndexReader(); boolean collate = params.getBool(SPELLCHECK_COLLATE, false); float accuracy = params.getFloat(SPELLCHECK_ACCURACY, Float.MIN_VALUE); SolrParams customParams = getCustomParams(getDictionaryName(params), params, shardRequest); @@ -678,7 +678,7 @@ public class SpellCheckComponent extends SearchComponent implements SolrCoreAwar if (buildOnCommit) { buildSpellIndex(newSearcher); } else if (buildOnOptimize) { - if (newSearcher.getReader().isOptimized()) { + if (newSearcher.getIndexReader().isOptimized()) { buildSpellIndex(newSearcher); } else { LOG.info("Index is not optimized therefore skipping building spell check index for: " + checker.getDictionaryName()); diff --git a/solr/src/java/org/apache/solr/handler/component/StatsComponent.java b/solr/src/java/org/apache/solr/handler/component/StatsComponent.java index dc0b4333047..64af5b95ebb 100644 --- a/solr/src/java/org/apache/solr/handler/component/StatsComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/StatsComponent.java @@ -248,7 +248,7 @@ class SimpleStats { FieldCache.DocTermsIndex si = null; try { - si = FieldCache.DEFAULT.getTermsIndex(searcher.getReader(), fieldName); + si = FieldCache.DEFAULT.getTermsIndex(searcher.getIndexReader(), fieldName); } catch (IOException e) { throw new RuntimeException( "failed to open field cache for: "+fieldName, e ); @@ -263,7 +263,7 @@ class SimpleStats { for( String f : facet ) { ft = searcher.getSchema().getFieldType(f); try { - si = FieldCache.DEFAULT.getTermsIndex(searcher.getReader(), f); + si = FieldCache.DEFAULT.getTermsIndex(searcher.getIndexReader(), f); } catch (IOException e) { throw new RuntimeException( "failed to open field cache for: "+f, e ); diff --git a/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java b/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java index 59310c6fa14..1fea0ac618b 100644 --- a/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java +++ b/solr/src/java/org/apache/solr/handler/component/TermVectorComponent.java @@ -174,7 +174,7 @@ public class TermVectorComponent extends SearchComponent implements SolrCoreAwar } SolrIndexSearcher searcher = rb.req.getSearcher(); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); //the TVMapper is a TermVectorMapper which can be used to optimize loading of Term Vectors SchemaField keyField = schema.getUniqueKeyField(); String uniqFieldName = null; diff --git a/solr/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java b/solr/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java index a032da6f55a..41604fab4b1 100644 --- a/solr/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java +++ b/solr/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java @@ -216,7 +216,7 @@ public class DefaultSolrHighlighter extends SolrHighlighter implements PluginInf private Scorer getQueryScorer(Query query, String fieldName, SolrQueryRequest request) { boolean reqFieldMatch = request.getParams().getFieldBool(fieldName, HighlightParams.FIELD_MATCH, false); if (reqFieldMatch) { - return new QueryTermScorer(query, request.getSearcher().getReader(), fieldName); + return new QueryTermScorer(query, request.getSearcher().getIndexReader(), fieldName); } else { return new QueryTermScorer(query); @@ -415,7 +415,7 @@ public class DefaultSolrHighlighter extends SolrHighlighter implements PluginInf TermOffsetsTokenStream tots = null; // to be non-null iff we're using TermOffsets optimization try { - TokenStream tvStream = TokenSources.getTokenStream(searcher.getReader(), docId, fieldName); + TokenStream tvStream = TokenSources.getTokenStream(searcher.getIndexReader(), docId, fieldName); if (tvStream != null) { tots = new TermOffsetsTokenStream(tvStream); } @@ -503,7 +503,7 @@ public class DefaultSolrHighlighter extends SolrHighlighter implements PluginInf String fieldName ) throws IOException { SolrParams params = req.getParams(); SolrFragmentsBuilder solrFb = getSolrFragmentsBuilder( fieldName, params ); - String[] snippets = highlighter.getBestFragments( fieldQuery, req.getSearcher().getReader(), docId, fieldName, + String[] snippets = highlighter.getBestFragments( fieldQuery, req.getSearcher().getIndexReader(), docId, fieldName, params.getFieldInt( fieldName, HighlightParams.FRAGSIZE, 100 ), params.getFieldInt( fieldName, HighlightParams.SNIPPETS, 1 ), getFragListBuilder( fieldName, params ), diff --git a/solr/src/java/org/apache/solr/request/SimpleFacets.java b/solr/src/java/org/apache/solr/request/SimpleFacets.java index 15ef35d7c15..65c948edabe 100644 --- a/solr/src/java/org/apache/solr/request/SimpleFacets.java +++ b/solr/src/java/org/apache/solr/request/SimpleFacets.java @@ -413,7 +413,7 @@ public class SimpleFacets { FieldType ft = searcher.getSchema().getFieldType(fieldName); NamedList res = new NamedList(); - FieldCache.DocTermsIndex si = FieldCache.DEFAULT.getTermsIndex(searcher.getReader(), fieldName); + FieldCache.DocTermsIndex si = FieldCache.DEFAULT.getTermsIndex(searcher.getIndexReader(), fieldName); final BytesRef prefixRef; if (prefix == null) { @@ -611,7 +611,7 @@ public class SimpleFacets { IndexSchema schema = searcher.getSchema(); - IndexReader r = searcher.getReader(); + IndexReader r = searcher.getIndexReader(); FieldType ft = schema.getFieldType(field); boolean sortByCount = sort.equals("count") || sort.equals("true"); diff --git a/solr/src/java/org/apache/solr/request/UnInvertedField.java b/solr/src/java/org/apache/solr/request/UnInvertedField.java index 7e6bf9978db..d724961cb22 100755 --- a/solr/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/src/java/org/apache/solr/request/UnInvertedField.java @@ -192,7 +192,7 @@ public class UnInvertedField { private void uninvert(SolrIndexSearcher searcher) throws IOException { long startTime = System.currentTimeMillis(); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); int maxDoc = reader.maxDoc(); int[] index = new int[maxDoc]; // immediate term numbers, or the index into the byte[] representing the last number @@ -481,7 +481,7 @@ public class UnInvertedField { int startTerm = 0; int endTerm = numTermsInField; // one past the end - NumberedTermsEnum te = ti.getEnumerator(searcher.getReader()); + NumberedTermsEnum te = ti.getEnumerator(searcher.getIndexReader()); if (prefix != null && prefix.length() > 0) { BytesRef prefixBr = new BytesRef(prefix); te.skipTo(prefixBr); @@ -719,7 +719,7 @@ public class UnInvertedField { for (String f : facet) { FieldType facet_ft = searcher.getSchema().getFieldType(f); try { - si = FieldCache.DEFAULT.getTermsIndex(searcher.getReader(), f); + si = FieldCache.DEFAULT.getTermsIndex(searcher.getIndexReader(), f); } catch (IOException e) { throw new RuntimeException("failed to open field cache for: " + f, e); @@ -731,7 +731,7 @@ public class UnInvertedField { final int[] index = this.index; final int[] counts = new int[numTermsInField];//keep track of the number of times we see each word in the field for all the documents in the docset - NumberedTermsEnum te = ti.getEnumerator(searcher.getReader()); + NumberedTermsEnum te = ti.getEnumerator(searcher.getIndexReader()); boolean doNegative = false; diff --git a/solr/src/java/org/apache/solr/schema/DateField.java b/solr/src/java/org/apache/solr/schema/DateField.java index 09b091fdc8c..d60584a5f3a 100644 --- a/solr/src/java/org/apache/solr/schema/DateField.java +++ b/solr/src/java/org/apache/solr/schema/DateField.java @@ -18,7 +18,7 @@ package org.apache.solr.schema; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; import org.apache.lucene.search.TermRangeQuery; @@ -427,8 +427,8 @@ class DateFieldSource extends FieldCacheSource { return "date(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - return new StringIndexDocValues(this, reader, field) { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new StringIndexDocValues(this, readerContext, field) { protected String toTerm(String readableValue) { // needed for frange queries to work properly return ft.toInternal(readableValue); diff --git a/solr/src/java/org/apache/solr/schema/LatLonType.java b/solr/src/java/org/apache/solr/schema/LatLonType.java index 2e35dcf72db..a1d0fdfeab5 100644 --- a/solr/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/src/java/org/apache/solr/schema/LatLonType.java @@ -20,7 +20,6 @@ import org.apache.lucene.document.Field; import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.MultiFields; import org.apache.lucene.search.*; import org.apache.lucene.spatial.DistanceUtils; import org.apache.lucene.spatial.tier.InvalidGeoException; @@ -372,7 +371,7 @@ class SpatialDistanceQuery extends Query { @Override public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - return new SpatialScorer(getSimilarity(searcher), context.reader, this); + return new SpatialScorer(getSimilarity(searcher), context, this); } @Override @@ -405,15 +404,15 @@ class SpatialDistanceQuery extends Query { int lastDistDoc; double lastDist; - public SpatialScorer(Similarity similarity, IndexReader reader, SpatialWeight w) throws IOException { + public SpatialScorer(Similarity similarity, AtomicReaderContext readerContext, SpatialWeight w) throws IOException { super(similarity); this.weight = w; this.qWeight = w.getValue(); - this.reader = reader; + this.reader = readerContext.reader; this.maxDoc = reader.maxDoc(); - this.delDocs = reader.hasDeletions() ? MultiFields.getDeletedDocs(reader) : null; - latVals = latSource.getValues(weight.latContext, reader); - lonVals = lonSource.getValues(weight.lonContext, reader); + this.delDocs = reader.getDeletedDocs(); + latVals = latSource.getValues(weight.latContext, readerContext); + lonVals = lonSource.getValues(weight.lonContext, readerContext); this.lonMin = SpatialDistanceQuery.this.lonMin; this.lonMax = SpatialDistanceQuery.this.lonMax; diff --git a/solr/src/java/org/apache/solr/schema/RandomSortField.java b/solr/src/java/org/apache/solr/schema/RandomSortField.java index 848e8206f9d..fd69557e3b1 100644 --- a/solr/src/java/org/apache/solr/schema/RandomSortField.java +++ b/solr/src/java/org/apache/solr/schema/RandomSortField.java @@ -24,11 +24,11 @@ import org.apache.lucene.document.Fieldable; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; +import org.apache.lucene.util.ReaderUtil; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.ValueSource; -import org.apache.solr.search.SolrIndexReader; /** * Utility Field used for random sorting. It should not be passed a value. @@ -78,17 +78,11 @@ public class RandomSortField extends FieldType { * Given a field name and an IndexReader, get a random hash seed. * Using dynamic fields, you can force the random order to change */ - private static int getSeed(String fieldName, IndexReader r) { - SolrIndexReader top = (SolrIndexReader)r; - int base=0; - while (top.getParent() != null) { - base += top.getBase(); - top = top.getParent(); - } - + private static int getSeed(String fieldName, AtomicReaderContext context) { + final IndexReader top = ReaderUtil.getTopLevelContext(context).reader; // calling getVersion() on a segment will currently give you a null pointer exception, so // we use the top-level reader. - return fieldName.hashCode() + base + (int)top.getVersion(); + return fieldName.hashCode() + context.docBase + (int)top.getVersion(); } @Override @@ -129,7 +123,7 @@ public class RandomSortField extends FieldType { } public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { - seed = getSeed(fieldname, context.reader); + seed = getSeed(fieldname, context); return this; } @@ -155,9 +149,9 @@ public class RandomSortField extends FieldType { } @Override - public DocValues getValues(Map context, final IndexReader reader) throws IOException { + public DocValues getValues(Map context, final AtomicReaderContext readerContext) throws IOException { return new DocValues() { - private final int seed = getSeed(field, reader); + private final int seed = getSeed(field, readerContext); @Override public float floatVal(int doc) { return (float)hash(doc+seed); diff --git a/solr/src/java/org/apache/solr/schema/SortableDoubleField.java b/solr/src/java/org/apache/solr/schema/SortableDoubleField.java index f1744efc688..411e9b5f6fc 100644 --- a/solr/src/java/org/apache/solr/schema/SortableDoubleField.java +++ b/solr/src/java/org/apache/solr/schema/SortableDoubleField.java @@ -28,7 +28,7 @@ import org.apache.solr.search.function.FieldCacheSource; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.StringIndexDocValues; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.util.ByteUtils; import org.apache.solr.util.NumberUtils; import org.apache.solr.response.TextResponseWriter; @@ -99,10 +99,10 @@ class SortableDoubleFieldSource extends FieldCacheSource { return "sdouble(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final double def = defVal; - return new StringIndexDocValues(this, reader, field) { + return new StringIndexDocValues(this, readerContext, field) { private final BytesRef spare = new BytesRef(); protected String toTerm(String readableValue) { diff --git a/solr/src/java/org/apache/solr/schema/SortableFloatField.java b/solr/src/java/org/apache/solr/schema/SortableFloatField.java index 407c17f90e3..e56ffd70c2a 100644 --- a/solr/src/java/org/apache/solr/schema/SortableFloatField.java +++ b/solr/src/java/org/apache/solr/schema/SortableFloatField.java @@ -28,7 +28,7 @@ import org.apache.solr.search.function.FieldCacheSource; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.StringIndexDocValues; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.util.ByteUtils; import org.apache.solr.util.NumberUtils; import org.apache.solr.response.TextResponseWriter; @@ -99,10 +99,10 @@ class SortableFloatFieldSource extends FieldCacheSource { return "sfloat(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final float def = defVal; - return new StringIndexDocValues(this, reader, field) { + return new StringIndexDocValues(this, readerContext, field) { private final BytesRef spare = new BytesRef(); protected String toTerm(String readableValue) { diff --git a/solr/src/java/org/apache/solr/schema/SortableIntField.java b/solr/src/java/org/apache/solr/schema/SortableIntField.java index 3771d3eb0e2..b6db1cff194 100644 --- a/solr/src/java/org/apache/solr/schema/SortableIntField.java +++ b/solr/src/java/org/apache/solr/schema/SortableIntField.java @@ -28,7 +28,7 @@ import org.apache.solr.search.function.FieldCacheSource; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.StringIndexDocValues; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.util.ByteUtils; import org.apache.solr.util.NumberUtils; import org.apache.solr.response.TextResponseWriter; @@ -101,10 +101,10 @@ class SortableIntFieldSource extends FieldCacheSource { return "sint(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final int def = defVal; - return new StringIndexDocValues(this, reader, field) { + return new StringIndexDocValues(this, readerContext, field) { private final BytesRef spare = new BytesRef(); protected String toTerm(String readableValue) { diff --git a/solr/src/java/org/apache/solr/schema/SortableLongField.java b/solr/src/java/org/apache/solr/schema/SortableLongField.java index b9657d1451a..3be76b9b1c1 100644 --- a/solr/src/java/org/apache/solr/schema/SortableLongField.java +++ b/solr/src/java/org/apache/solr/schema/SortableLongField.java @@ -28,7 +28,7 @@ import org.apache.solr.search.function.FieldCacheSource; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.StringIndexDocValues; import org.apache.lucene.document.Fieldable; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.util.ByteUtils; import org.apache.solr.util.NumberUtils; import org.apache.solr.response.TextResponseWriter; @@ -100,10 +100,10 @@ class SortableLongFieldSource extends FieldCacheSource { return "slong(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final long def = defVal; - return new StringIndexDocValues(this, reader, field) { + return new StringIndexDocValues(this, readerContext, field) { private final BytesRef spare = new BytesRef(); protected String toTerm(String readableValue) { diff --git a/solr/src/java/org/apache/solr/schema/StrFieldSource.java b/solr/src/java/org/apache/solr/schema/StrFieldSource.java index ab12750a084..36dcfcefcee 100755 --- a/solr/src/java/org/apache/solr/schema/StrFieldSource.java +++ b/solr/src/java/org/apache/solr/schema/StrFieldSource.java @@ -17,7 +17,7 @@ package org.apache.solr.schema; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.BytesRef; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.FieldCacheSource; @@ -36,8 +36,8 @@ public class StrFieldSource extends FieldCacheSource { return "str(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - return new StringIndexDocValues(this, reader, field) { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + return new StringIndexDocValues(this, readerContext, field) { protected String toTerm(String readableValue) { return readableValue; } diff --git a/solr/src/java/org/apache/solr/search/Grouping.java b/solr/src/java/org/apache/solr/search/Grouping.java index bc7e858c2ac..894b592f3e1 100755 --- a/solr/src/java/org/apache/solr/search/Grouping.java +++ b/solr/src/java/org/apache/solr/search/Grouping.java @@ -688,7 +688,7 @@ class TopGroupCollector extends GroupCollector { @Override public void setNextReader(AtomicReaderContext readerContext) throws IOException { this.docBase = readerContext.docBase; - docValues = vs.getValues(context, readerContext.reader); + docValues = vs.getValues(context, readerContext); filler = docValues.getValueFiller(); mval = filler.getValue(); for (int i=0; i= low) { - int mid = (low + high) >>> 1; - int offset = offsets[mid]; - // check low first since first segments are normally bigger. - if (doc < offset) - high = mid - 1; - else if (doc > offset) { - low = mid + 1; - } - else { - // exact match on the offset. - return mid; - } - } - // low is the insertion point, high should be just below that (and the segment we want). - return high; - } - - static String shortName(Object o) { - return o.getClass().getSimpleName()+ "@" + Integer.toHexString(o.hashCode()); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("SolrIndexReader{this=").append(Integer.toHexString(this.hashCode())); - sb.append(",r=").append(shortName(in)); - sb.append(",refCnt=").append(getRefCount()); - sb.append(",segments="); - sb.append(subReaders == null ? 1 : subReaders.length); - if (parent != null) { - sb.append(",parent=").append(parent.toString()); - } - sb.append('}'); - return sb.toString(); - } - - static void setSearcher(SolrIndexReader sr, SolrIndexSearcher searcher) { - sr.searcher = searcher; - SolrIndexReader[] readers = sr.getSequentialSubReaders(); - if (readers == null) return; - for (SolrIndexReader r : readers) { - setSearcher(r, searcher); - } - } - - private static void buildInfoMap(SolrIndexReader other, HashMap map) { - if (other == null) return; - map.put(other.getWrappedReader(), other.info); - SolrIndexReader[] readers = other.getSequentialSubReaders(); - if (readers == null) return; - for (SolrIndexReader r : readers) { - buildInfoMap(r, map); - } - } - - private static void setInfo(SolrIndexReader target, HashMap map) { - SolrReaderInfo info = map.get(target.getWrappedReader()); - if (info == null) info = new SolrReaderInfo(target.getWrappedReader()); - target.info = info; - SolrIndexReader[] readers = target.getSequentialSubReaders(); - if (readers == null) return; - for (SolrIndexReader r : readers) { - setInfo(r, map); - } - } - - /** Copies SolrReaderInfo instances from the source to this SolrIndexReader */ - public void associateInfo(SolrIndexReader source) { - // seemed safer to not mess with reopen() but simply set - // one set of caches from another reader tree. - HashMap map = new HashMap(); - buildInfoMap(source, map); - setInfo(this, map); - } - - public IndexReader getWrappedReader() { - return in; - } - - /** returns the parent reader, or null of none */ - public SolrIndexReader getParent() { - return parent; - } - - /** returns the docid offset within the parent reader */ - public int getBase() { - return base; - } - - @Override - public Directory directory() { - return in.directory(); - } - - @Override - public Bits getDeletedDocs() { - return in.getDeletedDocs(); - } - - @Override - public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException { - return in.getTermFreqVectors(docNumber); - } - - @Override - public TermFreqVector getTermFreqVector(int docNumber, String field) - throws IOException { - return in.getTermFreqVector(docNumber, field); - } - - @Override - public void getTermFreqVector(int docNumber, String field, TermVectorMapper mapper) throws IOException { - in.getTermFreqVector(docNumber, field, mapper); - - } - - @Override - public void getTermFreqVector(int docNumber, TermVectorMapper mapper) throws IOException { - in.getTermFreqVector(docNumber, mapper); - } - - @Override - public int numDocs() { - return in.numDocs(); - } - - @Override - public int maxDoc() { - return in.maxDoc(); - } - - @Override - public Document document(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException { - return in.document(n, fieldSelector); - } - - @Override - public boolean hasDeletions() { - return in.hasDeletions(); - } - - @Override - protected void doUndeleteAll() throws CorruptIndexException, IOException {in.undeleteAll();} - - @Override - public boolean hasNorms(String field) throws IOException { - return in.hasNorms(field); - } - - @Override - public byte[] norms(String f) throws IOException { - return in.norms(f); - } - - @Override - protected void doSetNorm(int d, String f, byte b) throws CorruptIndexException, IOException { - in.setNorm(d, f, b); - } - - @Override - public Fields fields() throws IOException { - return in.fields(); - } - - @Override - public int docFreq(Term t) throws IOException { - ensureOpen(); - return in.docFreq(t); - } - - @Override - public int docFreq(String field, BytesRef t) throws IOException { - return in.docFreq(field, t); - } - - @Override - public Terms terms(String field) throws IOException { - return in.terms(field); - } - - @Override - public DocsEnum termDocsEnum(Bits skipDocs, String field, BytesRef term) throws IOException { - return in.termDocsEnum(skipDocs, field, term); - } - - @Override - public DocsAndPositionsEnum termPositionsEnum(Bits skipDocs, String field, BytesRef term) throws IOException { - return in.termPositionsEnum(skipDocs, field, term); - } - - @Override - protected void doDelete(int n) throws CorruptIndexException, IOException { in.deleteDocument(n); } - - - // Let FilterIndexReader handle commit()... we cannot override commit() - // or call in.commit() ourselves. - // protected void doCommit() throws IOException { in.commit(); } - - @Override - protected void doClose() throws IOException { - in.close(); - } - - @Override - public Collection getFieldNames(IndexReader.FieldOption fieldNames) { - return in.getFieldNames(fieldNames); - } - - @Override - public long getVersion() { - return in.getVersion(); - } - - @Override - public boolean isCurrent() throws CorruptIndexException, IOException { - return in.isCurrent(); - } - - @Override - public boolean isOptimized() { - return in.isOptimized(); - } - - @Override - public SolrIndexReader[] getSequentialSubReaders() { - return subReaders; - } - - @Override - public int hashCode() { - return in.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (o instanceof SolrIndexReader) { - o = ((SolrIndexReader)o).in; - } - return in.equals(o); - } - - @Override - public int getRefCount() { - return in.getRefCount(); - } - - @Override - public IndexReader reopen(IndexCommit commit) throws CorruptIndexException, IOException { - return in.reopen(commit); - } - - @Override - public Object clone() { - // hmmm, is this right? - return super.clone(); - } - - @Override - public IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException { - // hmmm, is this right? - return super.clone(openReadOnly); - } - - @Override - public Map getCommitUserData() { - return in.getCommitUserData(); - } - - @Override - public long getUniqueTermCount() throws IOException { - return in.getUniqueTermCount(); - } - - @Override - public SolrIndexReader reopen(boolean openReadOnly) throws IOException { - IndexReader r = in.reopen(openReadOnly); - if (r == in) { - return this; - } - SolrIndexReader sr = new SolrIndexReader(r, null, 0); - sr.associateInfo(this); - return sr; - } - - @Override - public SolrIndexReader reopen() throws CorruptIndexException, IOException { - return reopen(true); - } - - @Override - public void decRef() throws IOException { - in.decRef(); - } - - @Override - public void deleteDocument(int docNum) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { - in.deleteDocument(docNum); - } - - @Override - public int deleteDocuments(Term term) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { - return in.deleteDocuments(term); - } - - @Override - public Document document(int n) throws CorruptIndexException, IOException { - return in.document(n); - } - -// @Override -// public String getCommitUserData() { -// return in.getCommitUserData(); -// } - - @Override - public IndexCommit getIndexCommit() throws IOException { - return in.getIndexCommit(); - } - - @Override - public void incRef() { - in.incRef(); - } - - @Override - public int numDeletedDocs() { - return in.numDeletedDocs(); - } - - @Override - public void setNorm(int doc, String field, byte value) throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { - in.setNorm(doc, field, value); - } - - @Override - public void undeleteAll() throws StaleReaderException, CorruptIndexException, LockObtainFailedException, IOException { - in.undeleteAll(); - } - - @Override - public Object getCoreCacheKey() { - return in.getCoreCacheKey(); - } - - @Override - public int getTermInfosIndexDivisor() { - return in.getTermInfosIndexDivisor(); - } - - @Override - public ReaderContext getTopReaderContext() { - return topLevelContext; - } -} - - - -/** SolrReaderInfo contains information that is the same for - * every SolrIndexReader that wraps the same IndexReader. - * Multiple SolrIndexReader instances will be accessing this - * class concurrently. - */ -class SolrReaderInfo { - private final IndexReader reader; - public SolrReaderInfo(IndexReader reader) { - this.reader = reader; - } - public IndexReader getReader() { return reader; } - -} \ No newline at end of file diff --git a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java index 9a59dc78cbc..6dec3f0df6b 100644 --- a/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java +++ b/solr/src/java/org/apache/solr/search/SolrIndexSearcher.java @@ -68,7 +68,7 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { private long openTime = System.currentTimeMillis(); private long registerTime = 0; private long warmupTime = 0; - private final SolrIndexReader reader; + private final IndexReader reader; private final boolean closeReader; private final int queryResultWindowSize; @@ -117,28 +117,15 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { this(core, schema,name,r, false, enableCache); } - private static SolrIndexReader wrap(IndexReader r) { - SolrIndexReader sir; - // wrap the reader - if (!(r instanceof SolrIndexReader)) { - sir = new SolrIndexReader(r, null, 0); - sir.associateInfo(null); - } else { - sir = (SolrIndexReader)r; - } - return sir; - } public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name, IndexReader r, boolean closeReader, boolean enableCache) { - super(wrap(r)); - this.reader = (SolrIndexReader)super.getIndexReader(); + super(r); + this.reader = getIndexReader(); this.core = core; this.schema = schema; this.name = "Searcher@" + Integer.toHexString(hashCode()) + (name!=null ? " "+name : ""); log.info("Opening " + this.name); - SolrIndexReader.setSearcher(reader, this); - if (r.directory() instanceof FSDirectory) { FSDirectory fsDirectory = (FSDirectory) r.directory(); indexDir = fsDirectory.getDirectory().getAbsolutePath(); @@ -247,8 +234,6 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean { numCloses.incrementAndGet(); } - /** Direct access to the IndexReader used by this searcher */ - public SolrIndexReader getReader() { return reader; } /** Direct access to the IndexSchema for use with this searcher */ public IndexSchema getSchema() { return schema; } diff --git a/solr/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/src/java/org/apache/solr/search/ValueSourceParser.java index 5b1805ee017..b7668608f61 100755 --- a/solr/src/java/org/apache/solr/search/ValueSourceParser.java +++ b/solr/src/java/org/apache/solr/search/ValueSourceParser.java @@ -16,7 +16,7 @@ */ package org.apache.solr.search; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.Query; @@ -710,7 +710,7 @@ class LongConstValueSource extends ConstNumberSource { return "const(" + constant + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { return new DocValues() { public float floatVal(int doc) { return fv; @@ -807,8 +807,8 @@ abstract class DoubleParser extends NamedParser { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals = source.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues vals = source.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return (float)doubleVal(doc); @@ -862,9 +862,9 @@ abstract class Double2Parser extends NamedParser { return name() + "(" + a.description() + "," + b.description() + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues aVals = a.getValues(context, reader); - final DocValues bVals = b.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues aVals = a.getValues(context, readerContext); + final DocValues bVals = b.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return (float)doubleVal(doc); diff --git a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java index 645f3805cb8..2ceb78ba6f7 100755 --- a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -96,7 +96,7 @@ public class BoostedQuery extends Query { if(subQueryScorer == null) { return null; } - return new BoostedQuery.CustomScorer(getSimilarity(searcher), searcher, context.reader, this, subQueryScorer, boostVal); + return new BoostedQuery.CustomScorer(getSimilarity(searcher), context, this, subQueryScorer, boostVal); } @Override @@ -105,7 +105,7 @@ public class BoostedQuery extends Query { if (!subQueryExpl.isMatch()) { return subQueryExpl; } - DocValues vals = boostVal.getValues(fcontext, readerContext.reader); + DocValues vals = boostVal.getValues(fcontext, readerContext); float sc = subQueryExpl.getValue() * vals.floatVal(doc); Explanation res = new ComplexExplanation( true, sc, BoostedQuery.this.toString() + ", product of:"); @@ -121,18 +121,16 @@ public class BoostedQuery extends Query { private final float qWeight; private final Scorer scorer; private final DocValues vals; - private final IndexReader reader; - private final IndexSearcher searcher; + private final AtomicReaderContext readerContext; - private CustomScorer(Similarity similarity, IndexSearcher searcher, IndexReader reader, BoostedQuery.BoostedWeight w, + private CustomScorer(Similarity similarity, AtomicReaderContext readerContext, BoostedQuery.BoostedWeight w, Scorer scorer, ValueSource vs) throws IOException { super(similarity); this.weight = w; this.qWeight = w.getValue(); this.scorer = scorer; - this.reader = reader; - this.searcher = searcher; // for explain - this.vals = vs.getValues(weight.fcontext, reader); + this.readerContext = readerContext; + this.vals = vs.getValues(weight.fcontext, readerContext); } @Override @@ -161,7 +159,7 @@ public class BoostedQuery extends Query { } public Explanation explain(int doc) throws IOException { - Explanation subQueryExpl = weight.qWeight.explain(ValueSource.readerToContext(weight.fcontext,reader) ,doc); + Explanation subQueryExpl = weight.qWeight.explain(readerContext ,doc); if (!subQueryExpl.isMatch()) { return subQueryExpl; } diff --git a/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java b/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java index 0cba6fd4c20..2dd5bb77ddf 100644 --- a/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/ByteFieldSource.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.cache.ByteValuesCreator; import org.apache.lucene.search.cache.CachedArray.ByteValues; @@ -41,8 +41,8 @@ public class ByteFieldSource extends NumericFieldCacheSource { return "byte(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final ByteValues vals = cache.getBytes(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final ByteValues vals = cache.getBytes(readerContext.reader, field, creator); final byte[] arr = vals.values; return new DocValues() { diff --git a/solr/src/java/org/apache/solr/search/function/ConstValueSource.java b/solr/src/java/org/apache/solr/search/function/ConstValueSource.java index b4a09bf0c13..846591dafb2 100755 --- a/solr/src/java/org/apache/solr/search/function/ConstValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/ConstValueSource.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; import java.util.Map; @@ -38,7 +38,7 @@ public class ConstValueSource extends ConstNumberSource { return "const(" + constant + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { return new DocValues() { public float floatVal(int doc) { return constant; diff --git a/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java b/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java index 2fef6ac117e..641f2a9aaa8 100755 --- a/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/DocFreqValueSource.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.util.BytesRef; @@ -239,7 +239,7 @@ public class DocFreqValueSource extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { IndexSearcher searcher = (IndexSearcher)context.get("searcher"); int docfreq = searcher.docFreq(new Term(indexedField, indexedBytes)); return new ConstIntDocValues(docfreq, this); diff --git a/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java b/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java index 19c5443ca39..9df2d685f2d 100755 --- a/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; import java.util.Map; @@ -37,7 +37,7 @@ public class DoubleConstValueSource extends ConstNumberSource { return "const(" + constant + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { return new DocValues() { public float floatVal(int doc) { return fv; diff --git a/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java b/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java index de670596d84..02017aee0a6 100644 --- a/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/DoubleFieldSource.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.Bits; import org.apache.lucene.search.cache.DoubleValuesCreator; import org.apache.lucene.search.cache.CachedArray.DoubleValues; @@ -45,8 +46,8 @@ public class DoubleFieldSource extends NumericFieldCacheSource { return "double(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DoubleValues vals = cache.getDoubles(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DoubleValues vals = cache.getDoubles(readerContext.reader, field, creator); final double[] arr = vals.values; final Bits valid = vals.valid; diff --git a/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java b/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java index 0b4b54c444f..9eaec662091 100755 --- a/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/DualFloatFunction.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import java.io.IOException; @@ -43,9 +43,9 @@ public abstract class DualFloatFunction extends ValueSource { return name() + "(" + a.description() + "," + b.description() + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues aVals = a.getValues(context, reader); - final DocValues bVals = b.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues aVals = a.getValues(context, readerContext); + final DocValues bVals = b.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return func(doc, aVals, bVals); diff --git a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java index c682ea8a2e0..817062c770d 100755 --- a/solr/src/java/org/apache/solr/search/function/FileFloatSource.java +++ b/solr/src/java/org/apache/solr/search/function/FileFloatSource.java @@ -18,15 +18,17 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.DocsEnum; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.MultiFields; +import org.apache.lucene.util.ReaderUtil; import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.BytesRef; import org.apache.solr.core.SolrCore; import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.FieldType; import org.apache.solr.search.QParser; -import org.apache.solr.search.SolrIndexReader; import org.apache.solr.util.VersionedFile; import java.io.*; @@ -55,19 +57,12 @@ public class FileFloatSource extends ValueSource { return "float(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { int offset = 0; - if (reader instanceof SolrIndexReader) { - SolrIndexReader r = (SolrIndexReader)reader; - while (r.getParent() != null) { - offset += r.getBase(); - r = r.getParent(); - } - reader = r; - } + ReaderContext topLevelContext = ReaderUtil.getTopLevelContext(readerContext); final int off = offset; - final float[] arr = getCachedFloats(reader); + final float[] arr = getCachedFloats(topLevelContext.reader); return new DocValues() { public float floatVal(int doc) { return arr[doc + off]; diff --git a/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java b/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java index 607de808325..a985b49fe7c 100644 --- a/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/FloatFieldSource.java @@ -20,7 +20,7 @@ package org.apache.solr.search.function; import java.io.IOException; import java.util.Map; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.Bits; import org.apache.lucene.search.cache.FloatValuesCreator; import org.apache.lucene.search.cache.CachedArray.FloatValues; @@ -45,8 +45,8 @@ public class FloatFieldSource extends NumericFieldCacheSource { return "float(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final FloatValues vals = cache.getFloats(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final FloatValues vals = cache.getFloats(readerContext.reader, field, creator); final float[] arr = vals.values; final Bits valid = vals.valid; diff --git a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java index dc0f644995e..8cd1a6f0257 100644 --- a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java +++ b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java @@ -19,7 +19,6 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.*; import org.apache.lucene.index.MultiFields; import org.apache.lucene.util.Bits; @@ -115,7 +114,7 @@ public class FunctionQuery extends Query { final boolean hasDeletions; final Bits delDocs; - public AllScorer(Similarity similarity, ReaderContext context, FunctionWeight w) throws IOException { + public AllScorer(Similarity similarity, AtomicReaderContext context, FunctionWeight w) throws IOException { super(similarity); this.weight = w; this.qWeight = w.getValue(); @@ -124,9 +123,7 @@ public class FunctionQuery extends Query { this.hasDeletions = reader.hasDeletions(); this.delDocs = MultiFields.getDeletedDocs(reader); assert !hasDeletions || delDocs != null; - Map funcContext = weight.context; - funcContext.put(reader, context); - vals = func.getValues(funcContext, reader); + vals = func.getValues(weight.context, context); } @Override diff --git a/solr/src/java/org/apache/solr/search/function/IDFValueSource.java b/solr/src/java/org/apache/solr/search/function/IDFValueSource.java index 5cb86fbb6b3..a9543b1c893 100755 --- a/solr/src/java/org/apache/solr/search/function/IDFValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/IDFValueSource.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Similarity; import org.apache.lucene.util.BytesRef; @@ -38,7 +39,7 @@ public class IDFValueSource extends DocFreqValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { IndexSearcher searcher = (IndexSearcher)context.get("searcher"); Similarity sim = searcher.getSimilarity(); // todo: we need docFreq that takes a BytesRef diff --git a/solr/src/java/org/apache/solr/search/function/IntFieldSource.java b/solr/src/java/org/apache/solr/search/function/IntFieldSource.java index 5b01abb34bf..0cee5e769cf 100644 --- a/solr/src/java/org/apache/solr/search/function/IntFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/IntFieldSource.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.Bits; import org.apache.solr.search.MutableValueInt; import org.apache.solr.search.MutableValue; @@ -45,8 +46,8 @@ public class IntFieldSource extends NumericFieldCacheSource { } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final IntValues vals = cache.getInts(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final IntValues vals = cache.getInts(readerContext.reader, field, creator); final int[] arr = vals.values; final Bits valid = vals.valid; diff --git a/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java b/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java index f93c9882e40..dae45789fca 100644 --- a/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/JoinDocFreqValueSource.java @@ -21,10 +21,11 @@ import java.io.IOException; import java.util.Map; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.FieldCache.DocTerms; import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.ReaderUtil; import org.apache.solr.common.SolrException; -import org.apache.solr.search.SolrIndexReader; /** * Use a field value and find the Document Frequency within another field. @@ -46,21 +47,10 @@ public class JoinDocFreqValueSource extends FieldCacheSource { return NAME + "(" + field +":("+qfield+"))"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { - final DocTerms terms = cache.getTerms(reader, field, true ); - - int offset = 0; - IndexReader topReader = reader; - if (topReader instanceof SolrIndexReader) { - SolrIndexReader r = (SolrIndexReader)topReader; - while (r.getParent() != null) { - offset += r.getBase(); - r = r.getParent(); - } - topReader = r; - } - final IndexReader top = topReader; + final DocTerms terms = cache.getTerms(readerContext.reader, field, true ); + final IndexReader top = ReaderUtil.getTopLevelContext(readerContext).reader; return new DocValues() { BytesRef ref = new BytesRef(); diff --git a/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java b/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java index 79a3a0ac37f..7ceb07e2bf9 100644 --- a/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/LinearFloatFunction.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import java.io.IOException; @@ -46,8 +46,8 @@ public class LinearFloatFunction extends ValueSource { return slope + "*float(" + source.description() + ")+" + intercept; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals = source.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues vals = source.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return vals.floatVal(doc) * slope + intercept; diff --git a/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java b/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java index 0c16a838d8c..64965e74cf7 100644 --- a/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/LiteralValueSource.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.util.Map; import java.io.IOException; @@ -38,7 +38,7 @@ public class LiteralValueSource extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { return new DocValues() { @Override diff --git a/solr/src/java/org/apache/solr/search/function/LongFieldSource.java b/solr/src/java/org/apache/solr/search/function/LongFieldSource.java index 60587d229c3..dfa92b7b2c1 100644 --- a/solr/src/java/org/apache/solr/search/function/LongFieldSource.java +++ b/solr/src/java/org/apache/solr/search/function/LongFieldSource.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.Bits; import org.apache.lucene.search.cache.LongValuesCreator; import org.apache.lucene.search.cache.CachedArray.LongValues; @@ -50,8 +51,8 @@ public class LongFieldSource extends NumericFieldCacheSource { return Long.parseLong(extVal); } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final LongValues vals = cache.getLongs(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final LongValues vals = cache.getLongs(readerContext.reader, field, creator); final long[] arr = vals.values; final Bits valid = vals.valid; diff --git a/solr/src/java/org/apache/solr/search/function/MaxDocValueSource.java b/solr/src/java/org/apache/solr/search/function/MaxDocValueSource.java index 6f4bebcd586..30d94528a93 100755 --- a/solr/src/java/org/apache/solr/search/function/MaxDocValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/MaxDocValueSource.java @@ -16,7 +16,7 @@ */ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import java.io.IOException; @@ -38,7 +38,7 @@ public class MaxDocValueSource extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { IndexSearcher searcher = (IndexSearcher)context.get("searcher"); return new ConstIntDocValues(searcher.maxDoc(), this); } diff --git a/solr/src/java/org/apache/solr/search/function/MaxFloatFunction.java b/solr/src/java/org/apache/solr/search/function/MaxFloatFunction.java index bab340f36b3..37af4d94809 100644 --- a/solr/src/java/org/apache/solr/search/function/MaxFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/MaxFloatFunction.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import java.io.IOException; @@ -45,8 +45,8 @@ public class MaxFloatFunction extends ValueSource { return "max(" + source.description() + "," + fval + ")"; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals = source.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues vals = source.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { float v = vals.floatVal(doc); diff --git a/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java b/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java index 331cd649095..f66bdfe7502 100644 --- a/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/MultiFloatFunction.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import java.util.Map; @@ -54,10 +54,10 @@ public abstract class MultiFloatFunction extends ValueSource { return sb.toString(); } - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { final DocValues[] valsArr = new DocValues[sources.length]; for (int i=0; i { return "short(" + field + ')'; } - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final ShortValues vals = cache.getShorts(reader, field, creator); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final ShortValues vals = cache.getShorts(readerContext.reader, field, creator); final short[] arr = vals.values; return new DocValues() { diff --git a/solr/src/java/org/apache/solr/search/function/SimpleFloatFunction.java b/solr/src/java/org/apache/solr/search/function/SimpleFloatFunction.java index 4e82f005310..e4079ac2dbd 100755 --- a/solr/src/java/org/apache/solr/search/function/SimpleFloatFunction.java +++ b/solr/src/java/org/apache/solr/search/function/SimpleFloatFunction.java @@ -17,7 +17,7 @@ package org.apache.solr.search.function; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import java.io.IOException; import java.util.Map; @@ -32,8 +32,8 @@ import java.util.Map; protected abstract float func(int doc, DocValues vals); @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals = source.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues vals = source.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return func(doc, vals); diff --git a/solr/src/java/org/apache/solr/search/function/StringIndexDocValues.java b/solr/src/java/org/apache/solr/search/function/StringIndexDocValues.java index 66e88419a38..f533a7319fc 100755 --- a/solr/src/java/org/apache/solr/search/function/StringIndexDocValues.java +++ b/solr/src/java/org/apache/solr/search/function/StringIndexDocValues.java @@ -19,6 +19,7 @@ package org.apache.solr.search.function; import org.apache.lucene.search.FieldCache; import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.BytesRef; import org.apache.solr.search.MutableValue; import org.apache.solr.search.MutableValueStr; @@ -33,9 +34,9 @@ public abstract class StringIndexDocValues extends DocValues { protected final ValueSource vs; protected final MutableValueStr val = new MutableValueStr(); - public StringIndexDocValues(ValueSource vs, IndexReader reader, String field) throws IOException { + public StringIndexDocValues(ValueSource vs, AtomicReaderContext context, String field) throws IOException { try { - termsIndex = FieldCache.DEFAULT.getTermsIndex(reader, field); + termsIndex = FieldCache.DEFAULT.getTermsIndex(context.reader, field); } catch (RuntimeException e) { throw new StringIndexException(field, e); } diff --git a/solr/src/java/org/apache/solr/search/function/TFValueSource.java b/solr/src/java/org/apache/solr/search/function/TFValueSource.java index fa82de53a25..cffb2264c59 100755 --- a/solr/src/java/org/apache/solr/search/function/TFValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/TFValueSource.java @@ -1,6 +1,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Similarity; @@ -21,9 +22,8 @@ public class TFValueSource extends TermFreqValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - // use MultiFields, just in case someone did a top() function - Fields fields = MultiFields.getFields(reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + Fields fields = readerContext.reader.fields(); final Terms terms = fields.terms(field); final Similarity similarity = ((IndexSearcher)context.get("searcher")).getSimilarity(); diff --git a/solr/src/java/org/apache/solr/search/function/TermFreqValueSource.java b/solr/src/java/org/apache/solr/search/function/TermFreqValueSource.java index a5603fd451b..5f8e1432ce0 100755 --- a/solr/src/java/org/apache/solr/search/function/TermFreqValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/TermFreqValueSource.java @@ -18,6 +18,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.*; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.util.BytesRef; import org.apache.solr.common.SolrException; @@ -36,9 +37,8 @@ public class TermFreqValueSource extends DocFreqValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - // use MultiFields, just in case someone did a top() function - Fields fields = MultiFields.getFields(reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + Fields fields = readerContext.reader.fields(); final Terms terms = fields.terms(field); return new IntDocValues(this) { diff --git a/solr/src/java/org/apache/solr/search/function/ValueSource.java b/solr/src/java/org/apache/solr/search/function/ValueSource.java index 9c1ac9724c3..e43ef276f1d 100644 --- a/solr/src/java/org/apache/solr/search/function/ValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/ValueSource.java @@ -19,7 +19,6 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.FieldComparator; import org.apache.lucene.search.FieldComparatorSource; import org.apache.lucene.search.Scorer; @@ -47,7 +46,7 @@ public abstract class ValueSource implements Serializable { * Gets the values for this reader and the context that was previously * passed to createWeight() */ - public abstract DocValues getValues(Map context, IndexReader reader) throws IOException; + public abstract DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException; public abstract boolean equals(Object o); @@ -66,7 +65,7 @@ public abstract class ValueSource implements Serializable { * EXPERIMENTAL: This method is subject to change. *
    WARNING: Sorted function queries are not currently weighted. *

    - * Get the SortField for this ValueSource. Uses the {@link #getValues(java.util.Map, org.apache.lucene.index.IndexReader)} + * Get the SortField for this ValueSource. Uses the {@link #getValues(java.util.Map, AtomicReaderContext)} * to populate the SortField. * * @param reverse true if this is a reverse sort. @@ -98,40 +97,6 @@ public abstract class ValueSource implements Serializable { return context; } - /* @lucene.internal - * This will most likely go away in the future. - */ - public static AtomicReaderContext readerToContext(Map fcontext, IndexReader reader) { - Object v = fcontext.get(reader); - if (v == null) { - IndexSearcher searcher = (IndexSearcher)fcontext.get("searcher"); - if (searcher == null) { - return null; - // TODO - // throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "no searcher found in function context"); - } - ReaderContext rcontext = searcher.getIndexReader().getTopReaderContext(); - if (rcontext.isAtomic) { - assert rcontext.reader == reader; - fcontext.put(rcontext.reader, (AtomicReaderContext)rcontext); - } else { - for (AtomicReaderContext subCtx : rcontext.leaves()) { - fcontext.put(subCtx.reader, subCtx); - } - } - - v = fcontext.get(reader); - if (v == null) { - return null; - // TODO - // throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "reader " + reader + " is not from the top reader " + searcher.getIndexReader()); - } - } - - return (AtomicReaderContext)v; - } - - class ValueSourceComparatorSource extends FieldComparatorSource { @@ -188,7 +153,7 @@ public abstract class ValueSource implements Serializable { } public FieldComparator setNextReader(AtomicReaderContext context) throws IOException { - docVals = getValues(Collections.emptyMap(), context.reader); + docVals = getValues(Collections.emptyMap(), context); return this; } diff --git a/solr/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java b/solr/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java index 8813736a849..151b3878111 100755 --- a/solr/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java +++ b/solr/src/java/org/apache/solr/search/function/ValueSourceRangeFilter.java @@ -20,7 +20,7 @@ package org.apache.solr.search.function; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.index.IndexReader.ReaderContext; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.solr.search.SolrFilter; import java.io.IOException; @@ -49,10 +49,10 @@ public class ValueSourceRangeFilter extends SolrFilter { this.includeUpper = upperVal != null && includeUpper; } - public DocIdSet getDocIdSet(final Map context, final ReaderContext readerContext) throws IOException { + public DocIdSet getDocIdSet(final Map context, final AtomicReaderContext readerContext) throws IOException { return new DocIdSet() { public DocIdSetIterator iterator() throws IOException { - return valueSource.getValues(context, readerContext.reader).getRangeScorer(readerContext.reader, lowerVal, upperVal, includeLower, includeUpper); + return valueSource.getValues(context, readerContext).getRangeScorer(readerContext.reader, lowerVal, upperVal, includeLower, includeUpper); } }; } diff --git a/solr/src/java/org/apache/solr/search/function/VectorValueSource.java b/solr/src/java/org/apache/solr/search/function/VectorValueSource.java index 5947df8041e..523e54670a3 100644 --- a/solr/src/java/org/apache/solr/search/function/VectorValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/VectorValueSource.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.solr.search.function.MultiValueSource; import org.apache.solr.search.function.DocValues; @@ -53,13 +53,13 @@ public class VectorValueSource extends MultiValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { int size = sources.size(); // special-case x,y and lat,lon since it's so common if (size==2) { - final DocValues x = sources.get(0).getValues(context, reader); - final DocValues y = sources.get(1).getValues(context, reader); + final DocValues x = sources.get(0).getValues(context, readerContext); + final DocValues y = sources.get(1).getValues(context, readerContext); return new DocValues() { @Override public void byteVal(int doc, byte[] vals) { @@ -106,7 +106,7 @@ public class VectorValueSource extends MultiValueSource { final DocValues[] valsArr = new DocValues[size]; for (int i = 0; i < size; i++) { - valsArr[i] = sources.get(i).getValues(context, reader); + valsArr[i] = sources.get(i).getValues(context, readerContext); } return new DocValues() { diff --git a/solr/src/java/org/apache/solr/search/function/distance/GeohashFunction.java b/solr/src/java/org/apache/solr/search/function/distance/GeohashFunction.java index 6102356b662..df146f7cb72 100644 --- a/solr/src/java/org/apache/solr/search/function/distance/GeohashFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/GeohashFunction.java @@ -18,7 +18,7 @@ package org.apache.solr.search.function.distance; import org.apache.solr.search.function.ValueSource; import org.apache.solr.search.function.DocValues; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.spatial.geohash.GeoHashUtils; import java.util.Map; @@ -46,9 +46,9 @@ public class GeohashFunction extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues latDV = lat.getValues(context, reader); - final DocValues lonDV = lon.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues latDV = lat.getValues(context, readerContext); + final DocValues lonDV = lon.getValues(context, readerContext); return new DocValues() { diff --git a/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java b/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java index cdcc182d13f..728b528e578 100644 --- a/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java @@ -20,7 +20,7 @@ package org.apache.solr.search.function.distance; import org.apache.lucene.spatial.DistanceUtils; import org.apache.solr.search.function.ValueSource; import org.apache.solr.search.function.DocValues; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.spatial.geohash.GeoHashUtils; @@ -54,9 +54,9 @@ public class GeohashHaversineFunction extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues gh1DV = geoHash1.getValues(context, reader); - final DocValues gh2DV = geoHash2.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues gh1DV = geoHash1.getValues(context, readerContext); + final DocValues gh2DV = geoHash2.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { diff --git a/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java b/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java index b1796b2646a..8ee45f57064 100755 --- a/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function.distance; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.queryParser.ParseException; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.spatial.DistanceUtils; @@ -190,9 +190,9 @@ public class HaversineConstFunction extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues latVals = latSource.getValues(context, reader); - final DocValues lonVals = lonSource.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues latVals = latSource.getValues(context, readerContext); + final DocValues lonVals = lonSource.getValues(context, readerContext); final double latCenterRad = this.latCenter * DistanceUtils.DEGREES_TO_RADIANS; final double lonCenterRad = this.lonCenter * DistanceUtils.DEGREES_TO_RADIANS; final double latCenterRad_cos = this.latCenterRad_cos; diff --git a/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java b/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java index 673840622c0..f54c3aa9ba4 100644 --- a/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function.distance; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.spatial.DistanceUtils; import org.apache.solr.common.SolrException; @@ -95,10 +95,10 @@ public class HaversineFunction extends ValueSource { @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues vals1 = p1.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues vals1 = p1.getValues(context, readerContext); - final DocValues vals2 = p2.getValues(context, reader); + final DocValues vals2 = p2.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { return (float) doubleVal(doc); diff --git a/solr/src/java/org/apache/solr/search/function/distance/StringDistanceFunction.java b/solr/src/java/org/apache/solr/search/function/distance/StringDistanceFunction.java index ecdcb4d75ba..f67639c9d28 100644 --- a/solr/src/java/org/apache/solr/search/function/distance/StringDistanceFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/StringDistanceFunction.java @@ -1,6 +1,6 @@ package org.apache.solr.search.function.distance; -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.spell.StringDistance; import org.apache.solr.search.function.DocValues; import org.apache.solr.search.function.ValueSource; @@ -31,9 +31,9 @@ public class StringDistanceFunction extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { - final DocValues str1DV = str1.getValues(context, reader); - final DocValues str2DV = str2.getValues(context, reader); + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { + final DocValues str1DV = str1.getValues(context, readerContext); + final DocValues str2DV = str2.getValues(context, readerContext); return new DocValues() { public float floatVal(int doc) { diff --git a/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java b/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java index 95495bd3f8e..3b86177bc04 100644 --- a/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java +++ b/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java @@ -16,7 +16,7 @@ package org.apache.solr.search.function.distance; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.spatial.DistanceUtils; import org.apache.solr.common.SolrException; @@ -78,11 +78,11 @@ public class VectorDistanceFunction extends ValueSource { } @Override - public DocValues getValues(Map context, IndexReader reader) throws IOException { + public DocValues getValues(Map context, AtomicReaderContext readerContext) throws IOException { - final DocValues vals1 = source1.getValues(context, reader); + final DocValues vals1 = source1.getValues(context, readerContext); - final DocValues vals2 = source2.getValues(context, reader); + final DocValues vals2 = source2.getValues(context, readerContext); return new DocValues() { diff --git a/solr/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java b/solr/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java index 3f85b259baf..bac6c8cbb47 100644 --- a/solr/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java +++ b/solr/src/java/org/apache/solr/spelling/IndexBasedSpellChecker.java @@ -73,7 +73,7 @@ public class IndexBasedSpellChecker extends AbstractLuceneSpellChecker { try { if (sourceLocation == null) { // Load from Solr's index - reader = searcher.getReader(); + reader = searcher.getIndexReader(); } else { // Load from Lucene index at given sourceLocation reader = this.reader; diff --git a/solr/src/java/org/apache/solr/spelling/suggest/Suggester.java b/solr/src/java/org/apache/solr/spelling/suggest/Suggester.java index 8ba1077fb3f..0eeb3141792 100644 --- a/solr/src/java/org/apache/solr/spelling/suggest/Suggester.java +++ b/solr/src/java/org/apache/solr/spelling/suggest/Suggester.java @@ -100,7 +100,7 @@ public class Suggester extends SolrSpellChecker { public void build(SolrCore core, SolrIndexSearcher searcher) { LOG.info("build()"); if (sourceLocation == null) { - reader = searcher.getReader(); + reader = searcher.getIndexReader(); dictionary = new HighFrequencyDictionary(reader, field, threshold); } else { try { diff --git a/solr/src/java/org/apache/solr/update/UpdateHandler.java b/solr/src/java/org/apache/solr/update/UpdateHandler.java index 7e06a2739fe..e7332349dfd 100644 --- a/solr/src/java/org/apache/solr/update/UpdateHandler.java +++ b/solr/src/java/org/apache/solr/update/UpdateHandler.java @@ -152,7 +152,7 @@ public abstract class UpdateHandler implements SolrInfoMBean { @Override public void collect(int doc) { try { - searcher.getReader().deleteDocument(doc + docBase); + searcher.getIndexReader().deleteDocument(doc + docBase); deleted++; } catch (IOException e) { // don't try to close the searcher on failure for now... diff --git a/solr/src/test/org/apache/solr/core/TestConfig.java b/solr/src/test/org/apache/solr/core/TestConfig.java index 03676c881e6..8c4145a610d 100644 --- a/solr/src/test/org/apache/solr/core/TestConfig.java +++ b/solr/src/test/org/apache/solr/core/TestConfig.java @@ -139,7 +139,7 @@ public class TestConfig extends SolrTestCaseJ4 { StandardIndexReaderFactory sirf = (StandardIndexReaderFactory) irf; assertEquals(12, sirf.termInfosIndexDivisor); SolrQueryRequest req = req(); - assertEquals(12, req.getSearcher().getReader().getTermInfosIndexDivisor()); + assertEquals(12, req.getSearcher().getIndexReader().getTermInfosIndexDivisor()); req.close(); } diff --git a/solr/src/test/org/apache/solr/core/TestQuerySenderListener.java b/solr/src/test/org/apache/solr/core/TestQuerySenderListener.java index b8edad8e255..70a7501c6e8 100644 --- a/solr/src/test/org/apache/solr/core/TestQuerySenderListener.java +++ b/solr/src/test/org/apache/solr/core/TestQuerySenderListener.java @@ -75,7 +75,7 @@ public class TestQuerySenderListener extends SolrTestCaseJ4 { String evt = mock.req.getParams().get(EventParams.EVENT); assertNotNull("Event is null", evt); assertTrue(evt + " is not equal to " + EventParams.FIRST_SEARCHER, evt.equals(EventParams.FIRST_SEARCHER) == true); - Directory dir = currentSearcher.getReader().directory(); + Directory dir = currentSearcher.getIndexReader().directory(); SolrIndexSearcher newSearcher = new SolrIndexSearcher(core, core.getSchema(), "testQuerySenderListener", dir, true, false); qsl.newSearcher(newSearcher, currentSearcher); diff --git a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java index b165298fa7d..dac3e913562 100644 --- a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java +++ b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java @@ -71,7 +71,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { comp.inform( core ); SolrQueryRequest req = req(); - IndexReader reader = req.getSearcher().getReader(); + IndexReader reader = req.getSearcher().getIndexReader(); Map map = comp.getElevationMap( reader, core ); req.close(); @@ -130,7 +130,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { args.put( "indent", "true" ); //args.put( CommonParams.FL, "id,title,score" ); SolrQueryRequest req = new LocalSolrQueryRequest( h.getCore(), new MapSolrParams( args) ); - IndexReader reader = req.getSearcher().getReader(); + IndexReader reader = req.getSearcher().getIndexReader(); QueryElevationComponent booster = (QueryElevationComponent)req.getCore().getSearchComponent( "elevate" ); assertQ("Make sure standard sort works as expected", req @@ -255,7 +255,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { comp.inform( h.getCore() ); SolrQueryRequest req = req(); - IndexReader reader = req.getSearcher().getReader(); + IndexReader reader = req.getSearcher().getIndexReader(); Map map = comp.getElevationMap(reader, h.getCore()); assertTrue( map.get( "aaa" ).priority.containsKey( new BytesRef("A") ) ); assertNull( map.get( "bbb" ) ); @@ -267,7 +267,7 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { assertU(commit()); req = req(); - reader = req.getSearcher().getReader(); + reader = req.getSearcher().getIndexReader(); map = comp.getElevationMap(reader, h.getCore()); assertNull( map.get( "aaa" ) ); assertTrue( map.get( "bbb" ).priority.containsKey( new BytesRef("B") ) ); diff --git a/solr/src/test/org/apache/solr/request/TestFaceting.java b/solr/src/test/org/apache/solr/request/TestFaceting.java index fa5b6cdd1e0..b9e1a5f8a9e 100755 --- a/solr/src/test/org/apache/solr/request/TestFaceting.java +++ b/solr/src/test/org/apache/solr/request/TestFaceting.java @@ -67,14 +67,14 @@ public class TestFaceting extends SolrTestCaseJ4 { req = lrf.makeRequest("q","*:*"); TermIndex ti = new TermIndex(proto.field()); - NumberedTermsEnum te = ti.getEnumerator(req.getSearcher().getReader()); + NumberedTermsEnum te = ti.getEnumerator(req.getSearcher().getIndexReader()); // iterate through first while(te.term() != null) te.next(); assertEquals(size, te.getTermNumber()); te.close(); - te = ti.getEnumerator(req.getSearcher().getReader()); + te = ti.getEnumerator(req.getSearcher().getIndexReader()); Random r = new Random(size); // test seeking by term string diff --git a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java index 0b5e114c257..4ad292607f9 100755 --- a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java +++ b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java @@ -45,7 +45,7 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { AtomicReaderContext[] leaves = ReaderUtil.leaves(topReaderContext); int idx = ReaderUtil.subIndex(doc, leaves); AtomicReaderContext leaf = leaves[idx]; - DocValues vals = vs.getValues(context, leaf.reader); + DocValues vals = vs.getValues(context, leaf); return vals.strVal(doc-leaf.docBase); } diff --git a/solr/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java b/solr/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java index 41b64532a8b..7e93afb8358 100644 --- a/solr/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java +++ b/solr/src/test/org/apache/solr/spelling/DirectSolrSpellCheckerTest.java @@ -62,7 +62,7 @@ public class DirectSolrSpellCheckerTest extends SolrTestCaseJ4 { RefCounted searcher = core.getSearcher(); Collection tokens = queryConverter.convert("fob"); - SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getReader()); + SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getIndexReader()); SpellingResult result = checker.getSuggestions(spellOpts); assertTrue("result is null and it shouldn't be", result != null); Map suggestions = result.get(tokens.iterator().next()); diff --git a/solr/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java b/solr/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java index 1230e78aa0b..3c536058f1f 100644 --- a/solr/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java +++ b/solr/src/test/org/apache/solr/spelling/FileBasedSpellCheckerTest.java @@ -78,7 +78,7 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 { RefCounted searcher = core.getSearcher(); Collection tokens = queryConverter.convert("fob"); - SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getReader()); + SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getIndexReader()); SpellingResult result = checker.getSuggestions(spellOpts); assertTrue("result is null and it shouldn't be", result != null); Map suggestions = result.get(tokens.iterator().next()); @@ -117,7 +117,7 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 { RefCounted searcher = core.getSearcher(); Collection tokens = queryConverter.convert("Solar"); - SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getReader()); + SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getIndexReader()); SpellingResult result = checker.getSuggestions(spellOpts); assertTrue("result is null and it shouldn't be", result != null); //should be lowercased, b/c we are using a lowercasing analyzer @@ -160,7 +160,7 @@ public class FileBasedSpellCheckerTest extends SolrTestCaseJ4 { RefCounted searcher = core.getSearcher(); Collection tokens = queryConverter.convert("solar"); - SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getReader()); + SpellingOptions spellOpts = new SpellingOptions(tokens, searcher.get().getIndexReader()); SpellingResult result = checker.getSuggestions(spellOpts); assertTrue("result is null and it shouldn't be", result != null); //should be lowercased, b/c we are using a lowercasing analyzer diff --git a/solr/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java b/solr/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java index d7f8edfb95b..440142c667b 100644 --- a/solr/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java +++ b/solr/src/test/org/apache/solr/spelling/IndexBasedSpellCheckerTest.java @@ -121,7 +121,7 @@ public class IndexBasedSpellCheckerTest extends SolrTestCaseJ4 { try { checker.build(core, searcher); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); Collection tokens = queryConverter.convert("documemt"); SpellingOptions spellOpts = new SpellingOptions(tokens, reader); SpellingResult result = checker.getSuggestions(spellOpts); @@ -196,7 +196,7 @@ public class IndexBasedSpellCheckerTest extends SolrTestCaseJ4 { try { checker.build(core, searcher); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); Collection tokens = queryConverter.convert("documemt"); SpellingOptions spellOpts = new SpellingOptions(tokens, reader, 1, false, true, 0.5f, null); SpellingResult result = checker.getSuggestions(spellOpts); @@ -309,7 +309,7 @@ public class IndexBasedSpellCheckerTest extends SolrTestCaseJ4 { try { checker.build(core, searcher); - IndexReader reader = searcher.getReader(); + IndexReader reader = searcher.getIndexReader(); Collection tokens = queryConverter.convert("flesh"); SpellingOptions spellOpts = new SpellingOptions(tokens, reader, 1, false, true, 0.5f, null); SpellingResult result = checker.getSuggestions(spellOpts); diff --git a/solr/src/test/org/apache/solr/update/processor/SignatureUpdateProcessorFactoryTest.java b/solr/src/test/org/apache/solr/update/processor/SignatureUpdateProcessorFactoryTest.java index 9b07cab1312..25f1a639442 100755 --- a/solr/src/test/org/apache/solr/update/processor/SignatureUpdateProcessorFactoryTest.java +++ b/solr/src/test/org/apache/solr/update/processor/SignatureUpdateProcessorFactoryTest.java @@ -62,7 +62,7 @@ public class SignatureUpdateProcessorFactoryTest extends SolrTestCaseJ4 { void checkNumDocs(int n) { SolrQueryRequest req = req(); try { - assertEquals(n, req.getSearcher().getReader().numDocs()); + assertEquals(n, req.getSearcher().getIndexReader().numDocs()); } finally { req.close(); } diff --git a/solr/src/webapp/src/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java b/solr/src/webapp/src/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java index 6169a5cb095..3a905cc545c 100644 --- a/solr/src/webapp/src/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java +++ b/solr/src/webapp/src/org/apache/solr/servlet/cache/HttpCacheHeaderUtil.java @@ -95,7 +95,7 @@ public final class HttpCacheHeaderUtil { public static String calcEtag(final SolrQueryRequest solrReq) { final SolrCore core = solrReq.getCore(); final long currentIndexVersion - = solrReq.getSearcher().getReader().getVersion(); + = solrReq.getSearcher().getIndexReader().getVersion(); EtagCacheVal etagCache = etagCoreCache.get(core); if (null == etagCache) { @@ -152,7 +152,7 @@ public final class HttpCacheHeaderUtil { // assume default, change if needed (getOpenTime() should be fast) lastMod = LastModFrom.DIRLASTMOD == lastModFrom - ? IndexReader.lastModified(searcher.getReader().directory()) + ? IndexReader.lastModified(searcher.getIndexReader().directory()) : searcher.getOpenTime(); } catch (IOException e) { // we're pretty freaking screwed if this happens From 23ad1c0f195b1d58a2966716ee24fd5d69d35439 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 13 Jan 2011 13:16:34 +0000 Subject: [PATCH 061/252] fixed testcases which failed with -Dtests.multiplier > 1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058540 13f79535-47bb-0310-9956-ffa450edef68 --- .../client/solrj/response/TermsResponseTest.java | 10 ++++++++++ .../apache/solr/core/RAMDirectoryFactoryTest.java | 5 ++++- .../test/org/apache/solr/handler/TestCSVLoader.java | 2 +- .../component/QueryElevationComponentTest.java | 8 ++++++++ .../handler/component/SpellCheckComponentTest.java | 12 ++++++++++++ 5 files changed, 35 insertions(+), 2 deletions(-) diff --git a/solr/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java b/solr/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java index 16258416ba8..5e0eed5313b 100644 --- a/solr/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java +++ b/solr/src/test/org/apache/solr/client/solrj/response/TermsResponseTest.java @@ -24,6 +24,7 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.response.TermsResponse.Term; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -36,6 +37,15 @@ public class TermsResponseTest extends SolrJettyTestBase { public static void beforeTest() throws Exception { initCore(EXAMPLE_CONFIG, EXAMPLE_SCHEMA, EXAMPLE_HOME); } + + @Before + @Override + public void setUp() throws Exception{ + super.setUp(); + clearIndex(); + assertU(commit()); + assertU(optimize()); + } @Test public void testTermsResponse() throws Exception { diff --git a/solr/src/test/org/apache/solr/core/RAMDirectoryFactoryTest.java b/solr/src/test/org/apache/solr/core/RAMDirectoryFactoryTest.java index 6e480a65556..9ca8583ea87 100644 --- a/solr/src/test/org/apache/solr/core/RAMDirectoryFactoryTest.java +++ b/solr/src/test/org/apache/solr/core/RAMDirectoryFactoryTest.java @@ -18,6 +18,7 @@ package org.apache.solr.core; import org.apache.lucene.store.Directory; +import org.apache.lucene.store.SingleInstanceLockFactory; import org.apache.lucene.util.LuceneTestCase; import java.io.IOException; @@ -27,7 +28,7 @@ import java.io.IOException; public class RAMDirectoryFactoryTest extends LuceneTestCase { public void testOpenReturnsTheSameForSamePath() throws IOException { final Directory directory = new RefCntRamDirectory(); - RAMDirectoryFactory factory = new RAMDirectoryFactory() { + RAMDirectoryFactory factory = new RAMDirectoryFactory() { @Override Directory openNew(String path) throws IOException { return directory; @@ -40,6 +41,8 @@ public class RAMDirectoryFactoryTest extends LuceneTestCase { "every time open() is called for the same path", directory, dir1); assertEquals("RAMDirectoryFactory should not create new instance of RefCntRamDirectory " + "every time open() is called for the same path", directory, dir2); + dir1.close(); + dir2.close(); } public void testOpenSucceedForEmptyDir() throws IOException { diff --git a/solr/src/test/org/apache/solr/handler/TestCSVLoader.java b/solr/src/test/org/apache/solr/handler/TestCSVLoader.java index c6415c5b065..1339a851c7b 100755 --- a/solr/src/test/org/apache/solr/handler/TestCSVLoader.java +++ b/solr/src/test/org/apache/solr/handler/TestCSVLoader.java @@ -76,7 +76,7 @@ public class TestCSVLoader extends SolrTestCaseJ4 { } void cleanup() { - assertU(delQ("id:[100 TO 110]")); + assertU(delQ("*:*")); assertU(commit()); } diff --git a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java index dac3e913562..349521d0901 100644 --- a/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java +++ b/solr/src/test/org/apache/solr/handler/component/QueryElevationComponentTest.java @@ -55,6 +55,14 @@ public class QueryElevationComponentTest extends SolrTestCaseJ4 { clearIndex(); assertU(commit()); assertU(optimize()); + // make sure this component is initialized correctly for each test + QueryElevationComponent comp = (QueryElevationComponent)h.getCore().getSearchComponent("elevate"); + NamedList args = new NamedList(); + args.add( QueryElevationComponent.CONFIG_FILE, "elevate.xml" ); + args.add( QueryElevationComponent.FIELD_TYPE, "string" ); + comp.init( args ); + comp.inform( h.getCore() ); + comp.forceElevation = false; } @Test diff --git a/solr/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java b/solr/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java index 66f353ee497..257aef389a6 100644 --- a/solr/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java +++ b/solr/src/test/org/apache/solr/handler/component/SpellCheckComponentTest.java @@ -40,6 +40,10 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 { @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig-spellcheckcomponent.xml","schema.xml"); + } + + public void setUp() throws Exception { + super.setUp(); assertU(adoc("id", "0", "lowerfilt", "This is a title")); assertU((adoc("id", "1", "lowerfilt", "The quick reb fox jumped over the lazy brown dogs."))); @@ -55,6 +59,14 @@ public class SpellCheckComponentTest extends SolrTestCaseJ4 { assertU((commit())); } + public void tearDown() throws Exception { + super.tearDown(); + assertU(delQ("*:*")); + optimize(); + assertU((commit())); + + } + @Test public void testExtendedResultsCount() throws Exception { assertJQ(req("qt",rh, SpellCheckComponent.COMPONENT_NAME, "true", SpellCheckComponent.SPELLCHECK_BUILD, "true", "q","bluo", SpellCheckComponent.SPELLCHECK_COUNT,"5", SpellCheckComponent.SPELLCHECK_EXTENDED_RESULTS,"false") From 05565c3b293cbbc96c1cc08e913e470419f33386 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 13 Jan 2011 13:37:26 +0000 Subject: [PATCH 062/252] fixed testcases which failed with -Dtests.multiplier > 1 git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058547 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/solr/handler/dataimport/TestJdbcDataSource.java | 3 ++- .../src/test/org/apache/solr/search/TestIndexSearcher.java | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/solr/contrib/dataimporthandler/src/test/java/org/apache/solr/handler/dataimport/TestJdbcDataSource.java b/solr/contrib/dataimporthandler/src/test/java/org/apache/solr/handler/dataimport/TestJdbcDataSource.java index 96a145d6bcf..68cc9ccc9ff 100644 --- a/solr/contrib/dataimporthandler/src/test/java/org/apache/solr/handler/dataimport/TestJdbcDataSource.java +++ b/solr/contrib/dataimporthandler/src/test/java/org/apache/solr/handler/dataimport/TestJdbcDataSource.java @@ -62,7 +62,7 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase { super.setUp(); System.setProperty("java.naming.factory.initial", MockInitialContextFactory.class.getName()); - + mockControl = EasyMock.createStrictControl(); driver = mockControl.createMock(Driver.class); dataSource = mockControl.createMock(DataSource.class); @@ -77,6 +77,7 @@ public class TestJdbcDataSource extends AbstractDataImportHandlerTestCase { System.setProperty("java.naming.factory.initial", sysProp); } super.tearDown(); + mockControl.reset(); } @Test diff --git a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java index 4ad292607f9..03fa134b6c0 100755 --- a/solr/src/test/org/apache/solr/search/TestIndexSearcher.java +++ b/solr/src/test/org/apache/solr/search/TestIndexSearcher.java @@ -35,6 +35,13 @@ public class TestIndexSearcher extends SolrTestCaseJ4 { public static void beforeClass() throws Exception { initCore("solrconfig.xml","schema.xml"); } + + public void tearDown() throws Exception { + super.tearDown(); + assertU(delQ("*:*")); + optimize(); + assertU((commit())); + } private String getStringVal(SolrQueryRequest sqr, String field, int doc) throws IOException { SchemaField sf = sqr.getSchema().getField(field); From 7913804b289aa4eee6a60f666bedc82e3dd222ad Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Thu, 13 Jan 2011 14:59:11 +0000 Subject: [PATCH 063/252] LUCENE-2865: Pass a context struct to Weight#scorer instead of naked booleans git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058592 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 + .../apache/lucene/index/BufferedDeletes.java | 2 +- .../apache/lucene/search/BooleanQuery.java | 8 +- .../lucene/search/ConstantScoreQuery.java | 7 +- .../lucene/search/DisjunctionMaxQuery.java | 5 +- .../apache/lucene/search/FilteredQuery.java | 6 +- .../apache/lucene/search/IndexSearcher.java | 8 +- .../lucene/search/MatchAllDocsQuery.java | 2 +- .../lucene/search/MultiPhraseQuery.java | 5 +- .../org/apache/lucene/search/PhraseQuery.java | 5 +- .../lucene/search/QueryWrapperFilter.java | 3 +- .../org/apache/lucene/search/TermQuery.java | 3 +- .../java/org/apache/lucene/search/Weight.java | 96 ++++++++++++++++--- .../search/function/CustomScoreQuery.java | 7 +- .../search/function/ValueSourceQuery.java | 3 +- .../search/payloads/PayloadNearQuery.java | 3 +- .../search/payloads/PayloadTermQuery.java | 3 +- .../lucene/search/spans/SpanWeight.java | 4 +- .../lucene/search/JustCompileSearch.java | 3 +- .../org/apache/lucene/search/QueryUtils.java | 13 +-- .../search/TestDisjunctionMaxQuery.java | 5 +- .../apache/lucene/search/TestTermScorer.java | 7 +- .../search/spans/TestNearSpansOrdered.java | 3 +- .../apache/lucene/search/spans/TestSpans.java | 3 +- .../org/apache/solr/schema/LatLonType.java | 4 +- .../solr/search/SolrConstantScoreQuery.java | 2 +- .../solr/search/function/BoostedQuery.java | 4 +- .../solr/search/function/FunctionQuery.java | 4 +- .../search/function/QueryValueSource.java | 3 +- 29 files changed, 153 insertions(+), 71 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 98bd2d7b5b7..c81ed4fae99 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -134,6 +134,9 @@ Changes in backwards compatibility policy * LUCENE-2839: Scorer#score(Collector,int,int) is now public because it is called from other classes and part of public API. (Uwe Schindler) + +* LUCENE-2865: Weight#scorer(AtomicReaderContext, boolean, boolean) now accepts + a ScorerContext struct instead of booleans.(Simon Willnauer) Changes in Runtime Behavior diff --git a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java index 936d9fd01f7..6b9ebcfe908 100644 --- a/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java +++ b/lucene/src/java/org/apache/lucene/index/BufferedDeletes.java @@ -372,7 +372,7 @@ class BufferedDeletes { Query query = entry.getKey(); int limit = entry.getValue().intValue(); Weight weight = query.weight(searcher); - Scorer scorer = weight.scorer(readerContext, true, false); + Scorer scorer = weight.scorer(readerContext, Weight.ScorerContext.def()); if (scorer != null) { while(true) { int doc = scorer.nextDoc(); diff --git a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java index 65159d17569..e3a09e1cfe9 100644 --- a/lucene/src/java/org/apache/lucene/search/BooleanQuery.java +++ b/lucene/src/java/org/apache/lucene/search/BooleanQuery.java @@ -226,7 +226,7 @@ public class BooleanQuery extends Query implements Iterable { for (Iterator wIter = weights.iterator(); wIter.hasNext();) { Weight w = wIter.next(); BooleanClause c = cIter.next(); - if (w.scorer(context, true, true) == null) { + if (w.scorer(context, ScorerContext.def().scoreDocsInOrder(true).topScorer(true)) == null) { if (c.isRequired()) { fail = true; Explanation r = new Explanation(0.0f, "no match on required clause (" + c.getQuery().toString() + ")"); @@ -288,7 +288,7 @@ public class BooleanQuery extends Query implements Iterable { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { List required = new ArrayList(); List prohibited = new ArrayList(); @@ -296,7 +296,7 @@ public class BooleanQuery extends Query implements Iterable { Iterator cIter = clauses.iterator(); for (Weight w : weights) { BooleanClause c = cIter.next(); - Scorer subScorer = w.scorer(context, true, false); + Scorer subScorer = w.scorer(context, ScorerContext.def()); if (subScorer == null) { if (c.isRequired()) { return null; @@ -311,7 +311,7 @@ public class BooleanQuery extends Query implements Iterable { } // Check if we can return a BooleanScorer - if (!scoreDocsInOrder && topScorer && required.size() == 0 && prohibited.size() < 32) { + if (!scorerContext.scoreDocsInOrder && scorerContext.topScorer && required.size() == 0 && prohibited.size() < 32) { return new BooleanScorer(this, disableCoord, similarity, minNrShouldMatch, optional, prohibited, maxCoord); } diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index dcbb0ecb204..b34b4c6c1e8 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; import java.io.IOException; @@ -133,7 +134,7 @@ public class ConstantScoreQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { final DocIdSetIterator disi; if (filter != null) { assert query == null; @@ -144,7 +145,7 @@ public class ConstantScoreQuery extends Query { } else { assert query != null && innerWeight != null; disi = - innerWeight.scorer(context, scoreDocsInOrder, topScorer); + innerWeight.scorer(context, scorerContext); } if (disi == null) return null; @@ -158,7 +159,7 @@ public class ConstantScoreQuery extends Query { @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { - final Scorer cs = scorer(context, true, false); + final Scorer cs = scorer(context, ScorerContext.def()); final boolean exists = (cs != null && cs.advance(doc) == doc); final ComplexExplanation result = new ComplexExplanation(); diff --git a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java index f7a797eec20..972e38e4ea6 100644 --- a/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java +++ b/lucene/src/java/org/apache/lucene/search/DisjunctionMaxQuery.java @@ -142,12 +142,11 @@ public class DisjunctionMaxQuery extends Query implements Iterable { /* Create the scorer used to score our associated DisjunctionMaxQuery */ @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, - boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { Scorer[] scorers = new Scorer[weights.size()]; int idx = 0; for (Weight w : weights) { - Scorer subScorer = w.scorer(context, true, false); + Scorer subScorer = w.scorer(context, ScorerContext.def()); if (subScorer != null && subScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { scorers[idx++] = subScorer; } diff --git a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java index 20ba46fa3b6..f2559e67a36 100644 --- a/lucene/src/java/org/apache/lucene/search/FilteredQuery.java +++ b/lucene/src/java/org/apache/lucene/search/FilteredQuery.java @@ -112,13 +112,13 @@ extends Query { // return a filtering scorer @Override - public Scorer scorer(AtomicReaderContext indexReader, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext context, ScorerContext scoreContext) throws IOException { - final Scorer scorer = weight.scorer(indexReader, true, false); + final Scorer scorer = weight.scorer(context, ScorerContext.def()); if (scorer == null) { return null; } - DocIdSet docIdSet = filter.getDocIdSet(indexReader); + DocIdSet docIdSet = filter.getDocIdSet(context); if (docIdSet == null) { return null; } diff --git a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java index 9e587962ea6..9bf54bb53a0 100644 --- a/lucene/src/java/org/apache/lucene/search/IndexSearcher.java +++ b/lucene/src/java/org/apache/lucene/search/IndexSearcher.java @@ -36,6 +36,7 @@ import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; import org.apache.lucene.store.NIOFSDirectory; // javadoc import org.apache.lucene.util.ReaderUtil; @@ -496,12 +497,13 @@ public class IndexSearcher { // TODO: should we make this // threaded...? the Collector could be sync'd? - + ScorerContext scorerContext = ScorerContext.def().scoreDocsInOrder(true).topScorer(true); // always use single thread: if (filter == null) { for (int i = 0; i < leafContexts.length; i++) { // search each subreader collector.setNextReader(leafContexts[i]); - Scorer scorer = weight.scorer(leafContexts[i], !collector.acceptsDocsOutOfOrder(), true); + scorerContext = scorerContext.scoreDocsInOrder(!collector.acceptsDocsOutOfOrder()); + Scorer scorer = weight.scorer(leafContexts[i], scorerContext); if (scorer != null) { scorer.score(collector); } @@ -519,7 +521,7 @@ public class IndexSearcher { assert filter != null; - Scorer scorer = weight.scorer(context, true, false); + Scorer scorer = weight.scorer(context, ScorerContext.def()); if (scorer == null) { return; } diff --git a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java index f3bad0cdc17..5fa771e46d7 100644 --- a/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MatchAllDocsQuery.java @@ -127,7 +127,7 @@ public class MatchAllDocsQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new MatchAllScorer(context.reader, similarity, this, normsField != null ? context.reader.norms(normsField) : null); } diff --git a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java index 4aa6cfc914d..d8bfb05ece6 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.ToStringUtils; @@ -168,7 +169,7 @@ public class MultiPhraseQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { if (termArrays.size() == 0) // optimize zero-term case return null; final IndexReader reader = context.reader; @@ -264,7 +265,7 @@ public class MultiPhraseQuery extends Query { fieldExpl.setDescription("fieldWeight("+getQuery()+" in "+doc+ "), product of:"); - Scorer scorer = scorer(context, true, false); + Scorer scorer = scorer(context, ScorerContext.def()); if (scorer == null) { return new Explanation(0.0f, "no matching docs"); } diff --git a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java index c465f3cb023..4c69f727400 100644 --- a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java @@ -26,6 +26,7 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.Explanation.IDFExplanation; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Bits; @@ -175,7 +176,7 @@ public class PhraseQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { if (terms.size() == 0) // optimize zero-term case return null; final IndexReader reader = context.reader; @@ -268,7 +269,7 @@ public class PhraseQuery extends Query { fieldExpl.setDescription("fieldWeight("+field+":"+query+" in "+doc+ "), product of:"); - Scorer scorer = scorer(context, true, false); + Scorer scorer = scorer(context, ScorerContext.def()); if (scorer == null) { return new Explanation(0.0f, "no matching docs"); } diff --git a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java index 31077e46683..175e36d2d45 100644 --- a/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java +++ b/lucene/src/java/org/apache/lucene/search/QueryWrapperFilter.java @@ -20,6 +20,7 @@ package org.apache.lucene.search; import java.io.IOException; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.search.Weight.ScorerContext; /** * Constrains search results to only match those which also match a provided @@ -55,7 +56,7 @@ public class QueryWrapperFilter extends Filter { return new DocIdSet() { @Override public DocIdSetIterator iterator() throws IOException { - return weight.scorer(privateContext, true, false); + return weight.scorer(privateContext, ScorerContext.def()); } @Override public boolean isCacheable() { return false; } diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index 56d0dcd63d1..64bb68dab11 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -28,6 +28,7 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.Explanation.IDFExplanation; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.PerReaderTermState; import org.apache.lucene.util.ReaderUtil; @@ -86,7 +87,7 @@ public class TermQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { final String field = term.field(); final IndexReader reader = context.reader; assert termStates.topReaderContext == ReaderUtil.getTopLevelContext(context) : "The top-reader used to create Weight is not the same as the current reader's top-reader"; diff --git a/lucene/src/java/org/apache/lucene/search/Weight.java b/lucene/src/java/org/apache/lucene/search/Weight.java index e649530e530..8c26047ab1d 100644 --- a/lucene/src/java/org/apache/lucene/search/Weight.java +++ b/lucene/src/java/org/apache/lucene/search/Weight.java @@ -49,7 +49,7 @@ import org.apache.lucene.index.IndexReader.ReaderContext; *

  24. The query normalization factor is passed to {@link #normalize(float)}. At * this point the weighting is complete. *
  25. A Scorer is constructed by - * {@link #scorer(AtomicReaderContext,boolean,boolean)}. + * {@link #scorer(AtomicReaderContext, ScorerContext)}. * * * @since 2.9 @@ -89,23 +89,11 @@ public abstract class Weight implements Serializable { * * @param context * the {@link AtomicReaderContext} for which to return the {@link Scorer}. - * @param scoreDocsInOrder - * specifies whether in-order scoring of documents is required. Note - * that if set to false (i.e., out-of-order scoring is required), - * this method can return whatever scoring mode it supports, as every - * in-order scorer is also an out-of-order one. However, an - * out-of-order scorer may not support {@link Scorer#nextDoc()} - * and/or {@link Scorer#advance(int)}, therefore it is recommended to - * request an in-order scorer if use of these methods is required. - * @param topScorer - * if true, {@link Scorer#score(Collector)} will be called; if false, - * {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will - * be called. + * @param scorercontext the {@link ScorerContext} holding the scores context variables * @return a {@link Scorer} which scores documents in/out-of order. * @throws IOException */ - public abstract Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, - boolean topScorer) throws IOException; + public abstract Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException; /** The sum of squared weights of contained query clauses. */ public abstract float sumOfSquaredWeights() throws IOException; @@ -123,4 +111,82 @@ public abstract class Weight implements Serializable { */ public boolean scoresDocsOutOfOrder() { return false; } + /** + * A struct like class encapsulating a scorer's context variables. + * ScorerContex is a strictly immutable struct that follows a + * create on modification pattern. If a context variable changes + * through one of the modifiers like {@link #topScorer(boolean)} a new + * {@link ScorerContext} instance is creates. If the modifier call doesn't + * change the instance the method call has no effect and the same instance is + * returned from the modifier. + * + * @lucene.experimental + */ + public static final class ScorerContext { + + /** + * Specifies whether in-order scoring of documents is required. Note that if + * set to false (i.e., out-of-order scoring is required), this method can + * return whatever scoring mode it supports, as every in-order scorer is + * also an out-of-order one. However, an out-of-order scorer may not support + * {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)}, therefore it + * is recommended to request an in-order scorer if use of these methods is + * required. + */ + public final boolean scoreDocsInOrder; + + /** + * if true, {@link Scorer#score(Collector)} will be called; if + * false, {@link Scorer#nextDoc()} and/or {@link Scorer#advance(int)} will + * be called instead. + */ + public final boolean topScorer; + + + private static final ScorerContext DEFAULT_CONTEXT = new ScorerContext(true, false); + + /** + * Returns a default {@link ScorerContext} template initialized with: + *
      + *
    • {@link #scoreDocsInOrder} = true
    • + *
    • {@link #topScorer} = false
    • + *
    + */ + public static ScorerContext def() { + return DEFAULT_CONTEXT; + } + + private ScorerContext(boolean scoreDocsInOrder, boolean topScorer) { + this.scoreDocsInOrder = scoreDocsInOrder; + this.topScorer = topScorer; + } + + /** + * Creates and returns a copy of this context with the given value for + * {@link #scoreDocsInOrder} and returns a new instance of + * {@link ScorerContext} iff the given value differs from the + * {@link #scoreDocsInOrder}. Otherwise, this method has no effect and + * returns this instance. + */ + public ScorerContext scoreDocsInOrder(boolean scoreDocsInOrder) { + if (this.scoreDocsInOrder == scoreDocsInOrder) { + return this; + } + return new ScorerContext(scoreDocsInOrder, topScorer); + } + + /** + * Creates and returns a copy of this context with the given value for + * {@link #topScorer} and returns a new instance of + * {@link ScorerContext} iff the given value differs from the + * {@link #topScorer}. Otherwise, this method has no effect and + * returns this instance. + */ + public ScorerContext topScorer(boolean topScorer) { + if (this.topScorer == topScorer) { + return this; + } + return new ScorerContext(scoreDocsInOrder, topScorer); + } + } } diff --git a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java index fd3bc3e81fb..812181cada4 100755 --- a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java @@ -31,6 +31,7 @@ import org.apache.lucene.search.Weight; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Similarity; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; /** @@ -240,19 +241,19 @@ public class CustomScoreQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { // Pass true for "scoresDocsInOrder", because we // require in-order scoring, even if caller does not, // since we call advance on the valSrcScorers. Pass // false for "topScorer" because we will not invoke // score(Collector) on these scorers: - Scorer subQueryScorer = subQueryWeight.scorer(context, true, false); + Scorer subQueryScorer = subQueryWeight.scorer(context, ScorerContext.def()); if (subQueryScorer == null) { return null; } Scorer[] valSrcScorers = new Scorer[valSrcWeights.length]; for(int i = 0; i < valSrcScorers.length; i++) { - valSrcScorers[i] = valSrcWeights[i].scorer(context, true, topScorer); + valSrcScorers[i] = valSrcWeights[i].scorer(context, scorerContext.scoreDocsInOrder(true)); } return new CustomScorer(similarity, context.reader, this, subQueryScorer, valSrcScorers); } diff --git a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java index 38e4c95e625..e0d93b371d4 100644 --- a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java @@ -19,6 +19,7 @@ package org.apache.lucene.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.*; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; @@ -99,7 +100,7 @@ public class ValueSourceQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new ValueSourceScorer(similarity, context, this); } diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java index 2504e7ed28b..0e8ff6c49a8 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadNearQuery.java @@ -143,8 +143,7 @@ public class PayloadNearQuery extends SpanNearQuery { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, - boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new PayloadNearSpanScorer(query.getSpans(context.reader), this, similarity, context.reader.norms(query.getField())); } diff --git a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java index 048f3affa30..fe90da15dae 100644 --- a/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java @@ -74,8 +74,7 @@ public class PayloadTermQuery extends SpanTermQuery { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, - boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new PayloadTermSpanScorer((TermSpans) query.getSpans(context.reader), this, similarity, context.reader.norms(query.getField())); } diff --git a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java index 4b360cfb8ea..f60564189da 100644 --- a/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java +++ b/lucene/src/java/org/apache/lucene/search/spans/SpanWeight.java @@ -72,7 +72,7 @@ public class SpanWeight extends Weight { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new SpanScorer(query.getSpans(context.reader), this, similarity, context.reader .norms(query.getField())); } @@ -111,7 +111,7 @@ public class SpanWeight extends Weight { fieldExpl.setDescription("fieldWeight("+field+":"+query.toString(field)+ " in "+doc+"), product of:"); - Explanation tfExpl = ((SpanScorer)scorer(context, true, false)).explain(doc); + Explanation tfExpl = ((SpanScorer)scorer(context, ScorerContext.def())).explain(doc); fieldExpl.addDetail(tfExpl); fieldExpl.addDetail(idfExpl); diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index f932e39bbe2..812bfe112f4 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.util.PriorityQueue; @@ -360,7 +361,7 @@ final class JustCompileSearch { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { throw new UnsupportedOperationException(UNSUPPORTED_MSG); } diff --git a/lucene/src/test/org/apache/lucene/search/QueryUtils.java b/lucene/src/test/org/apache/lucene/search/QueryUtils.java index d5754321591..1b30da01171 100644 --- a/lucene/src/test/org/apache/lucene/search/QueryUtils.java +++ b/lucene/src/test/org/apache/lucene/search/QueryUtils.java @@ -16,6 +16,7 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiReader; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; import org.apache.lucene.store.MockDirectoryWrapper; import org.apache.lucene.store.RAMDirectory; @@ -263,7 +264,7 @@ public class QueryUtils { try { if (scorer == null) { Weight w = q.weight(s); - scorer = w.scorer(readerContextArray[leafPtr], true, false); + scorer = w.scorer(readerContextArray[leafPtr], ScorerContext.def()); } int op = order[(opidx[0]++) % order.length]; @@ -308,7 +309,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), ScorerContext.def()); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -333,7 +334,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer((AtomicReaderContext)previousReader.getTopReaderContext() , true, false); + Scorer scorer = w.scorer((AtomicReaderContext)previousReader.getTopReaderContext(), ScorerContext.def()); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -363,7 +364,7 @@ public class QueryUtils { long startMS = System.currentTimeMillis(); for (int i=lastDoc[0]+1; i<=doc; i++) { Weight w = q.weight(s); - Scorer scorer = w.scorer(context[leafPtr], true, false); + Scorer scorer = w.scorer(context[leafPtr], ScorerContext.def()); Assert.assertTrue("query collected "+doc+" but skipTo("+i+") says no more docs!",scorer.advance(i) != DocIdSetIterator.NO_MORE_DOCS); Assert.assertEquals("query collected "+doc+" but skipTo("+i+") got to "+scorer.docID(),doc,scorer.docID()); float skipToScore = scorer.score(); @@ -390,7 +391,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), ScorerContext.def()); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); @@ -413,7 +414,7 @@ public class QueryUtils { final IndexReader previousReader = lastReader[0]; IndexSearcher indexSearcher = new IndexSearcher(previousReader); Weight w = q.weight(indexSearcher); - Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, false); + Scorer scorer = w.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), ScorerContext.def()); if (scorer != null) { boolean more = scorer.advance(lastDoc[0] + 1) != DocIdSetIterator.NO_MORE_DOCS; Assert.assertFalse("query's last doc was "+ lastDoc[0] +" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.docID(),more); diff --git a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java index 595c18c9762..4f147de3930 100644 --- a/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java +++ b/lucene/src/test/org/apache/lucene/search/TestDisjunctionMaxQuery.java @@ -27,6 +27,7 @@ import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; import java.text.DecimalFormat; @@ -168,7 +169,7 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { QueryUtils.check(random, dq, s); assertTrue(s.getTopReaderContext().isAtomic); final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), true, false); + final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), ScorerContext.def()); final boolean skipOk = ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS; if (skipOk) { fail("firsttime skipTo found a match? ... " @@ -183,7 +184,7 @@ public class TestDisjunctionMaxQuery extends LuceneTestCase { assertTrue(s.getTopReaderContext().isAtomic); QueryUtils.check(random, dq, s); final Weight dw = dq.weight(s); - final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), true, false); + final Scorer ds = dw.scorer((AtomicReaderContext)s.getTopReaderContext(), ScorerContext.def()); assertTrue("firsttime skipTo found no match", ds.advance(3) != DocIdSetIterator.NO_MORE_DOCS); assertEquals("found wrong docid", "d4", r.document(ds.docID()).get("id")); diff --git a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java index 05c34758f56..156420665b7 100644 --- a/lucene/src/test/org/apache/lucene/search/TestTermScorer.java +++ b/lucene/src/test/org/apache/lucene/search/TestTermScorer.java @@ -29,6 +29,7 @@ import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.index.SlowMultiReaderWrapper; import org.apache.lucene.index.IndexReader.AtomicReaderContext; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; public class TestTermScorer extends LuceneTestCase { @@ -72,7 +73,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); assertTrue(indexSearcher.getTopReaderContext().isAtomic); - Scorer ts = weight.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), true, true); + Scorer ts = weight.scorer((AtomicReaderContext)indexSearcher.getTopReaderContext(), ScorerContext.def().scoreDocsInOrder(true).topScorer(true)); // we have 2 documents with the term all in them, one document for all the // other values final List docs = new ArrayList(); @@ -133,7 +134,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); assertTrue(indexSearcher.getTopReaderContext().isAtomic); - Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), true, true); + Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), ScorerContext.def().scoreDocsInOrder(true).topScorer(true)); assertTrue("next did not return a doc", ts.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); assertTrue("score is not correct", ts.score() == 1.6931472f); @@ -152,7 +153,7 @@ public class TestTermScorer extends LuceneTestCase { Weight weight = termQuery.weight(indexSearcher); assertTrue(indexSearcher.getTopReaderContext().isAtomic); - Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), true, true); + Scorer ts = weight.scorer((AtomicReaderContext) indexSearcher.getTopReaderContext(), ScorerContext.def().scoreDocsInOrder(true).topScorer(true)); assertTrue("Didn't skip", ts.advance(3) != DocIdSetIterator.NO_MORE_DOCS); // The next doc should be doc 5 assertTrue("doc should be number 5", ts.docID() == 5); diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java index e5497e470f7..e95d08a3dea 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java @@ -31,6 +31,7 @@ import org.apache.lucene.search.Explanation; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Weight; import org.apache.lucene.search.Scorer; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; @@ -170,7 +171,7 @@ public class TestNearSpansOrdered extends LuceneTestCase { SpanNearQuery q = makeQuery(); Weight w = q.weight(searcher); assertTrue(searcher.getTopReaderContext().isAtomic); - Scorer s = w.scorer((AtomicReaderContext) searcher.getTopReaderContext(), true, false); + Scorer s = w.scorer((AtomicReaderContext) searcher.getTopReaderContext(), ScorerContext.def()); assertEquals(1, s.advance(1)); } /** diff --git a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java index ca83e3a67e0..09fba717028 100644 --- a/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java +++ b/lucene/src/test/org/apache/lucene/search/spans/TestSpans.java @@ -25,6 +25,7 @@ import org.apache.lucene.search.DefaultSimilarity; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.store.Directory; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.index.IndexWriter; @@ -421,7 +422,7 @@ public class TestSpans extends LuceneTestCase { } }; - Scorer spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), true, false); + Scorer spanScorer = snq.weight(searcher).scorer(new AtomicReaderContext(new SlowMultiReaderWrapper(searcher.getIndexReader())), ScorerContext.def()); assertTrue("first doc", spanScorer.nextDoc() != DocIdSetIterator.NO_MORE_DOCS); assertEquals("first doc number", spanScorer.docID(), 11); diff --git a/solr/src/java/org/apache/solr/schema/LatLonType.java b/solr/src/java/org/apache/solr/schema/LatLonType.java index a1d0fdfeab5..7ffdbf60524 100644 --- a/solr/src/java/org/apache/solr/schema/LatLonType.java +++ b/solr/src/java/org/apache/solr/schema/LatLonType.java @@ -370,13 +370,13 @@ class SpatialDistanceQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new SpatialScorer(getSimilarity(searcher), context, this); } @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { - return ((SpatialScorer)scorer(context, true, true)).explain(doc); + return ((SpatialScorer)scorer(context, ScorerContext.def().scoreDocsInOrder(true).topScorer(true))).explain(doc); } } diff --git a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java index fd63bb92fb9..6e231f8f2f6 100755 --- a/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java +++ b/solr/src/java/org/apache/solr/search/SolrConstantScoreQuery.java @@ -90,7 +90,7 @@ public class SolrConstantScoreQuery extends ConstantScoreQuery { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new ConstantScorer(similarity, context, this); } diff --git a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java index 2ceb78ba6f7..a8d4872b1e8 100755 --- a/solr/src/java/org/apache/solr/search/function/BoostedQuery.java +++ b/solr/src/java/org/apache/solr/search/function/BoostedQuery.java @@ -91,8 +91,8 @@ public class BoostedQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { - Scorer subQueryScorer = qWeight.scorer(context, true, false); + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { + Scorer subQueryScorer = qWeight.scorer(context, ScorerContext.def()); if(subQueryScorer == null) { return null; } diff --git a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java index 8cd1a6f0257..b82ccaf21eb 100644 --- a/solr/src/java/org/apache/solr/search/function/FunctionQuery.java +++ b/solr/src/java/org/apache/solr/search/function/FunctionQuery.java @@ -94,13 +94,13 @@ public class FunctionQuery extends Query { } @Override - public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + public Scorer scorer(AtomicReaderContext context, ScorerContext scorerContext) throws IOException { return new AllScorer(getSimilarity(searcher), context, this); } @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { - return ((AllScorer)scorer(context, true, true)).explain(doc); + return ((AllScorer)scorer(context, ScorerContext.def().scoreDocsInOrder(true).topScorer(true))).explain(doc); } } diff --git a/solr/src/java/org/apache/solr/search/function/QueryValueSource.java b/solr/src/java/org/apache/solr/search/function/QueryValueSource.java index f2407ab9b8c..8c52d01f029 100755 --- a/solr/src/java/org/apache/solr/search/function/QueryValueSource.java +++ b/solr/src/java/org/apache/solr/search/function/QueryValueSource.java @@ -20,6 +20,7 @@ package org.apache.solr.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.search.*; +import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ReaderUtil; import org.apache.solr.common.SolrException; @@ -111,7 +112,7 @@ class QueryDocValues extends DocValues { public float floatVal(int doc) { try { if (doc < lastDocRequested) { - scorer = weight.scorer(readerContext, true, false); + scorer = weight.scorer(readerContext, ScorerContext.def()); if (scorer==null) return defVal; scorerDoc = -1; } From 5a375116427d2a69fc29d7cbe068b0afb9d888e3 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Fri, 14 Jan 2011 06:47:28 +0000 Subject: [PATCH 064/252] removed unnecessary imports git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058865 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java | 1 - lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java | 1 - lucene/src/java/org/apache/lucene/search/PhraseQuery.java | 1 - lucene/src/java/org/apache/lucene/search/TermQuery.java | 1 - .../java/org/apache/lucene/search/function/CustomScoreQuery.java | 1 - .../java/org/apache/lucene/search/function/ValueSourceQuery.java | 1 - lucene/src/test/org/apache/lucene/search/JustCompileSearch.java | 1 - 7 files changed, 7 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java index b34b4c6c1e8..2e67f94cf3c 100644 --- a/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/ConstantScoreQuery.java @@ -20,7 +20,6 @@ package org.apache.lucene.search; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; import java.io.IOException; diff --git a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java index d8bfb05ece6..79122c2c0a6 100644 --- a/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/MultiPhraseQuery.java @@ -25,7 +25,6 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.ToStringUtils; diff --git a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java index 4c69f727400..ce86931f5df 100644 --- a/lucene/src/java/org/apache/lucene/search/PhraseQuery.java +++ b/lucene/src/java/org/apache/lucene/search/PhraseQuery.java @@ -26,7 +26,6 @@ import org.apache.lucene.index.Term; import org.apache.lucene.index.DocsAndPositionsEnum; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.Explanation.IDFExplanation; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Bits; diff --git a/lucene/src/java/org/apache/lucene/search/TermQuery.java b/lucene/src/java/org/apache/lucene/search/TermQuery.java index 64bb68dab11..798fcb082a7 100644 --- a/lucene/src/java/org/apache/lucene/search/TermQuery.java +++ b/lucene/src/java/org/apache/lucene/search/TermQuery.java @@ -28,7 +28,6 @@ import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.search.Explanation.IDFExplanation; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.PerReaderTermState; import org.apache.lucene.util.ReaderUtil; diff --git a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java index 812181cada4..a775d040b33 100755 --- a/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/CustomScoreQuery.java @@ -31,7 +31,6 @@ import org.apache.lucene.search.Weight; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Similarity; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.ToStringUtils; /** diff --git a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java index e0d93b371d4..22364163015 100644 --- a/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java +++ b/lucene/src/java/org/apache/lucene/search/function/ValueSourceQuery.java @@ -19,7 +19,6 @@ package org.apache.lucene.search.function; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.*; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.Term; import org.apache.lucene.util.ToStringUtils; diff --git a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java index 812bfe112f4..efdd3466edf 100644 --- a/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java +++ b/lucene/src/test/org/apache/lucene/search/JustCompileSearch.java @@ -21,7 +21,6 @@ import java.io.IOException; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexReader.AtomicReaderContext; -import org.apache.lucene.search.Weight.ScorerContext; import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.FieldInvertState; import org.apache.lucene.util.PriorityQueue; From 9ea3019edb7b4cc5797fc9d2d8e2c3d34b261a08 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Fri, 14 Jan 2011 11:00:42 +0000 Subject: [PATCH 065/252] LUCENE-2864: add FieldInvertState.getMaxTermFrequency git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1058939 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 4 + .../apache/lucene/index/FieldInvertState.java | 11 ++ .../index/FreqProxTermsWriterPerField.java | 4 +- .../lucene/index/TestMaxTermFrequency.java | 116 ++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 lucene/src/test/org/apache/lucene/index/TestMaxTermFrequency.java diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index c81ed4fae99..a38c96aa61d 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -737,6 +737,10 @@ New features is no longer needed and discouraged for that use case. Directly wrapping Query improves performance, as out-of-order collection is now supported. (Uwe Schindler) + +* LUCENE-2864: Add getMaxTermFrequency (maximum within-document TF) to + FieldInvertState so that it can be used in Similarity.computeNorm. + (Robert Muir) Optimizations diff --git a/lucene/src/java/org/apache/lucene/index/FieldInvertState.java b/lucene/src/java/org/apache/lucene/index/FieldInvertState.java index 321c89211c2..8c4e92ad4ea 100644 --- a/lucene/src/java/org/apache/lucene/index/FieldInvertState.java +++ b/lucene/src/java/org/apache/lucene/index/FieldInvertState.java @@ -30,6 +30,7 @@ public final class FieldInvertState { int length; int numOverlap; int offset; + int maxTermFrequency; float boost; AttributeSource attributeSource; @@ -53,6 +54,7 @@ public final class FieldInvertState { length = 0; numOverlap = 0; offset = 0; + maxTermFrequency = 0; boost = docBoost; attributeSource = null; } @@ -110,6 +112,15 @@ public final class FieldInvertState { public void setBoost(float boost) { this.boost = boost; } + + /** + * Get the maximum term-frequency encountered for any term in the field. A + * field containing "the quick brown fox jumps over the lazy dog" would have + * a value of 2, because "the" appears twice. + */ + public int getMaxTermFrequency() { + return maxTermFrequency; + } public AttributeSource getAttributeSource() { return attributeSource; diff --git a/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java b/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java index f22c484d1a5..f47d2a71bc0 100644 --- a/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java +++ b/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriterPerField.java @@ -125,6 +125,7 @@ final class FreqProxTermsWriterPerField extends TermsHashConsumerPerField implem postings.docFreqs[termID] = 1; writeProx(termID, fieldState.position); } + fieldState.maxTermFrequency = Math.max(1, fieldState.maxTermFrequency); } @Override @@ -158,11 +159,12 @@ final class FreqProxTermsWriterPerField extends TermsHashConsumerPerField implem termsHashPerField.writeVInt(0, postings.docFreqs[termID]); } postings.docFreqs[termID] = 1; + fieldState.maxTermFrequency = Math.max(1, fieldState.maxTermFrequency); postings.lastDocCodes[termID] = (docState.docID - postings.lastDocIDs[termID]) << 1; postings.lastDocIDs[termID] = docState.docID; writeProx(termID, fieldState.position); } else { - postings.docFreqs[termID]++; + fieldState.maxTermFrequency = Math.max(fieldState.maxTermFrequency, ++postings.docFreqs[termID]); writeProx(termID, fieldState.position-postings.lastPositions[termID]); } } diff --git a/lucene/src/test/org/apache/lucene/index/TestMaxTermFrequency.java b/lucene/src/test/org/apache/lucene/index/TestMaxTermFrequency.java new file mode 100644 index 00000000000..15a1fefe823 --- /dev/null +++ b/lucene/src/test/org/apache/lucene/index/TestMaxTermFrequency.java @@ -0,0 +1,116 @@ +package org.apache.lucene.index; + +/** + * 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.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.analysis.MockTokenizer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.search.DefaultSimilarity; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util._TestUtil; + +/** + * Tests the maxTermFrequency statistic in FieldInvertState + */ +public class TestMaxTermFrequency extends LuceneTestCase { + Directory dir; + IndexReader reader; + /* expected maxTermFrequency values for our documents */ + ArrayList expected = new ArrayList(); + + @Override + public void setUp() throws Exception { + super.setUp(); + dir = newDirectory(); + IndexWriterConfig config = newIndexWriterConfig(TEST_VERSION_CURRENT, + new MockAnalyzer(MockTokenizer.SIMPLE, true)); + config.setSimilarity(new TestSimilarity()); + RandomIndexWriter writer = new RandomIndexWriter(random, dir, config); + Document doc = new Document(); + Field foo = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED); + doc.add(foo); + for (int i = 0; i < 100; i++) { + foo.setValue(addValue()); + writer.addDocument(doc); + } + reader = writer.getReader(); + writer.close(); + } + + @Override + public void tearDown() throws Exception { + reader.close(); + dir.close(); + super.tearDown(); + } + + public void test() throws Exception { + byte fooNorms[] = MultiNorms.norms(reader, "foo"); + for (int i = 0; i < reader.maxDoc(); i++) + assertEquals(expected.get(i).intValue(), fooNorms[i] & 0xff); + } + + /** + * Makes a bunch of single-char tokens (the max freq will at most be 255). + * shuffles them around, and returns the whole list with Arrays.toString(). + * This works fine because we use lettertokenizer. + * puts the max-frequency term into expected, to be checked against the norm. + */ + private String addValue() { + List terms = new ArrayList(); + int maxCeiling = _TestUtil.nextInt(random, 0, 255); + int max = 0; + for (char ch = 'a'; ch <= 'z'; ch++) { + int num = _TestUtil.nextInt(random, 0, maxCeiling); + for (int i = 0; i < num; i++) + terms.add(Character.toString(ch)); + max = Math.max(max, num); + } + expected.add(max); + Collections.shuffle(terms, random); + return Arrays.toString(terms.toArray(new String[terms.size()])); + } + + /** + * Simple similarity that encodes maxTermFrequency directly as a byte + */ + class TestSimilarity extends DefaultSimilarity { + + @Override + public byte encodeNormValue(float f) { + return (byte) f; + } + + @Override + public float decodeNormValue(byte b) { + return (float) b; + } + + @Override + public float computeNorm(String field, FieldInvertState state) { + return (float) state.getMaxTermFrequency(); + } + } +} From 1bb7cd93fa19133ed7e7df4505b70ce98ddd3164 Mon Sep 17 00:00:00 2001 From: Steven Rowe Date: Fri, 14 Jan 2011 23:02:14 +0000 Subject: [PATCH 066/252] LUCENE-2611: Added Copyright Plugin configuration for Apache Software License git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059199 13f79535-47bb-0310-9956-ffa450edef68 --- .../copyright/Apache_Software_Foundation.xml | 9 +++++++ .../.idea/copyright/profiles_settings.xml | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 dev-tools/idea/.idea/copyright/Apache_Software_Foundation.xml create mode 100644 dev-tools/idea/.idea/copyright/profiles_settings.xml diff --git a/dev-tools/idea/.idea/copyright/Apache_Software_Foundation.xml b/dev-tools/idea/.idea/copyright/Apache_Software_Foundation.xml new file mode 100644 index 00000000000..b7458479239 --- /dev/null +++ b/dev-tools/idea/.idea/copyright/Apache_Software_Foundation.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/dev-tools/idea/.idea/copyright/profiles_settings.xml b/dev-tools/idea/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000000..5551fbedba0 --- /dev/null +++ b/dev-tools/idea/.idea/copyright/profiles_settings.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + From f5d5dda6c60986c76a35c8393fbc3cd86070e8e4 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 15 Jan 2011 12:24:06 +0000 Subject: [PATCH 067/252] LUCENE-2843: fix silly perf bug in FixedGapTermsIndexReader git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059313 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/index/codecs/FixedGapTermsIndexReader.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java b/lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java index c335dc6fcff..699c3c5a579 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/FixedGapTermsIndexReader.java @@ -132,7 +132,6 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase { private class IndexEnum extends FieldIndexEnum { private final FieldIndexData.CoreFieldIndex fieldIndex; private final BytesRef term = new BytesRef(); - private final BytesRef nextTerm = new BytesRef(); private long ord; public IndexEnum(FieldIndexData.CoreFieldIndex fieldIndex) { @@ -192,7 +191,7 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase { final long offset = fieldIndex.termOffsets.get(idx); final int length = (int) (fieldIndex.termOffsets.get(1+idx) - offset); - termBytesReader.fillSlice(nextTerm, fieldIndex.termBytesStart + offset, length); + termBytesReader.fillSlice(term, fieldIndex.termBytesStart + offset, length); return fieldIndex.termsStart + fieldIndex.termsDictOffsets.get(idx); } From a0c82b0f418b13f6027e39ce411fd525e232a316 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 15 Jan 2011 14:42:37 +0000 Subject: [PATCH 068/252] LUCENE-2862: add TermsEnum.totalTermFreq() and Terms.getSumTotalTermFreq() git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059344 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 3 + .../store/instantiated/InstantiatedIndex.java | 4 ++ .../instantiated/InstantiatedIndexReader.java | 17 ++++- .../instantiated/InstantiatedIndexWriter.java | 1 + .../store/instantiated/InstantiatedTerm.java | 10 +++ .../instantiated/InstantiatedTermsEnum.java | 7 +- .../store/instantiated/TestIndicesEquals.java | 5 ++ .../lucene/index/memory/MemoryIndex.java | 21 ++++++ .../org/apache/lucene/misc/HighFreqTerms.java | 31 ++++++-- .../org/apache/lucene/misc/TermStats.java | 5 ++ .../apache/lucene/misc/TestHighFreqTerms.java | 28 ++++---- .../search/FieldCacheRewriteMethod.java | 6 +- .../org/apache/lucene/index/CheckIndex.java | 37 ++++++++-- .../lucene/index/FilterIndexReader.java | 10 +++ .../lucene/index/FreqProxTermsWriter.java | 13 ++-- .../org/apache/lucene/index/IndexReader.java | 17 +++++ .../org/apache/lucene/index/MultiTerms.java | 13 ++++ .../apache/lucene/index/MultiTermsEnum.java | 13 ++++ .../java/org/apache/lucene/index/Terms.java | 20 ++++++ .../org/apache/lucene/index/TermsEnum.java | 15 +++- .../codecs/FixedGapTermsIndexWriter.java | 2 +- .../lucene/index/codecs/PostingsConsumer.java | 7 +- .../index/codecs/PostingsWriterBase.java | 2 +- .../index/codecs/PrefixCodedTermState.java | 6 +- .../index/codecs/PrefixCodedTermsReader.java | 34 ++++++--- .../index/codecs/PrefixCodedTermsWriter.java | 52 +++++++++----- .../apache/lucene/index/codecs/TermStats.java | 28 ++++++++ .../lucene/index/codecs/TermsConsumer.java | 20 +++--- .../index/codecs/TermsIndexWriterBase.java | 2 +- .../codecs/VariableGapTermsIndexWriter.java | 12 ++-- .../index/codecs/preflex/PreFlexFields.java | 11 ++- .../pulsing/PulsingPostingsWriterImpl.java | 5 +- .../codecs/sep/SepPostingsWriterImpl.java | 7 +- .../simpletext/SimpleTextFieldsReader.java | 71 ++++++++++++++----- .../simpletext/SimpleTextFieldsWriter.java | 5 +- .../standard/StandardPostingsWriter.java | 7 +- .../lucene/search/FilteredTermsEnum.java | 5 ++ .../apache/lucene/search/FuzzyTermsEnum.java | 5 ++ .../search/cache/DocTermsIndexCreator.java | 6 +- .../org/apache/lucene/TestExternalCodecs.java | 22 ++++-- .../org/apache/lucene/index/TestCodecs.java | 16 +++-- .../apache/lucene/index/TestIndexReader.java | 18 +++++ .../codecs/mockrandom/MockRandomCodec.java | 5 +- .../codecs/preflexrw/PreFlexFieldsWriter.java | 9 +-- .../apache/solr/request/UnInvertedField.java | 4 ++ 45 files changed, 511 insertions(+), 126 deletions(-) create mode 100644 lucene/src/java/org/apache/lucene/index/codecs/TermStats.java diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index a38c96aa61d..d51a1936ea0 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -359,6 +359,9 @@ New features terms dict. This impl stores the indexed terms in an FST, which is much more RAM efficient than FixedGapTermsIndex. (Mike McCandless) +* LUCENE-2862: Added TermsEnum.totalTermFreq() and + Terms.getSumTotalTermFreq(). (Mike McCandless, Robert Muir) + Optimizations * LUCENE-2410: ~20% speedup on exact (slop=0) PhraseQuery matching. diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java index 179d9c42c80..76faa4602bd 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndex.java @@ -238,6 +238,10 @@ public class InstantiatedIndex while((text = termsEnum.next()) != null) { String termText = text.utf8ToString(); InstantiatedTerm instantiatedTerm = new InstantiatedTerm(field, termText); + final long totalTermFreq = termsEnum.totalTermFreq(); + if (totalTermFreq != -1) { + instantiatedTerm.addPositionsCount(totalTermFreq); + } getTermsByFieldAndText().get(field).put(termText, instantiatedTerm); instantiatedTerm.setTermIndex(terms.size()); terms.add(instantiatedTerm); diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java index 3b191b83fc5..7cece688d33 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexReader.java @@ -398,18 +398,33 @@ public class InstantiatedIndexReader extends IndexReader { if (i < 0) { i = -i - 1; } - if (i >= orderedTerms.length || !orderedTerms[i].field().equals(field)) { + if (i >= orderedTerms.length || orderedTerms[i].field() != field) { // field does not exist return null; } final int startLoc = i; + // TODO: heavy to do this here; would be better to + // do it up front & cache + long sum = 0; + int upto = i; + while(upto < orderedTerms.length && orderedTerms[i].field() == field) { + sum += orderedTerms[i].getTotalTermFreq(); + upto++; + } + final long sumTotalTermFreq = sum; + return new Terms() { @Override public TermsEnum iterator() { return new InstantiatedTermsEnum(orderedTerms, startLoc, field); } + @Override + public long getSumTotalTermFreq() { + return sumTotalTermFreq; + } + @Override public Comparator getComparator() { return BytesRef.getUTF8SortedAsUnicodeComparator(); diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java index f5cd26dfe31..95bb1f01cd4 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedIndexWriter.java @@ -315,6 +315,7 @@ public class InstantiatedIndexWriter implements Closeable { } associatedDocuments[associatedDocuments.length - 1] = info; term.setAssociatedDocuments(associatedDocuments); + term.addPositionsCount(positions.length); // todo optimize, only if term vector? informationByTermOfCurrentDocument.put(term, info); diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTerm.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTerm.java index b893e04cd86..cdd2197c89c 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTerm.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTerm.java @@ -45,6 +45,8 @@ public class InstantiatedTerm private Term term; + private long totalTermFreq; + /** * index of term in InstantiatedIndex * @see org.apache.lucene.store.instantiated.InstantiatedIndex#getOrderedTerms() */ @@ -92,6 +94,14 @@ public class InstantiatedTerm this.associatedDocuments = associatedDocuments; } + void addPositionsCount(long count) { + totalTermFreq += count; + } + + public long getTotalTermFreq() { + return totalTermFreq; + } + /** * Finds index to the first beyond the current whose document number is * greater than or equal to target, -1 if there is no such element. diff --git a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java index 0dd4ffc2803..8628d005b60 100644 --- a/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java +++ b/lucene/contrib/instantiated/src/java/org/apache/lucene/store/instantiated/InstantiatedTermsEnum.java @@ -24,7 +24,6 @@ import org.apache.lucene.index.TermState; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; -import org.apache.lucene.index.codecs.PrefixCodedTermState; import java.io.IOException; import java.util.Arrays; @@ -110,6 +109,12 @@ public class InstantiatedTermsEnum extends TermsEnum { return terms[upto].getAssociatedDocuments().length; } + @Override + public long totalTermFreq() { + final long v = terms[upto].getTotalTermFreq(); + return v == 0 ? -1 : v; + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) { if (reuse == null || !(reuse instanceof InstantiatedDocsEnum)) { diff --git a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java index 1ad0743b635..ae091b5ec6e 100644 --- a/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java +++ b/lucene/contrib/instantiated/src/test/org/apache/lucene/store/instantiated/TestIndicesEquals.java @@ -66,6 +66,7 @@ public class TestIndicesEquals extends LuceneTestCase { // create dir data IndexWriter indexWriter = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer())); + for (int i = 0; i < 20; i++) { Document document = new Document(); assembleDocument(document, i); @@ -395,6 +396,10 @@ public class TestIndicesEquals extends LuceneTestCase { } assertTrue(aprioriTermEnum.docFreq() == testTermEnum.docFreq()); + final long totalTermFreq = aprioriTermEnum.totalTermFreq(); + if (totalTermFreq != -1) { + assertEquals(totalTermFreq, testTermEnum.totalTermFreq()); + } // compare termDocs seeking diff --git a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java index cd1df94a9c7..88049654f46 100644 --- a/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java +++ b/lucene/contrib/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java @@ -610,6 +610,8 @@ public class MemoryIndex implements Serializable { /** Term for this field's fieldName, lazily computed on demand */ public transient Term template; + private final long sumTotalTermFreq; + private static final long serialVersionUID = 2882195016849084649L; public Info(HashMap terms, int numTokens, int numOverlapTokens, float boost) { @@ -617,6 +619,15 @@ public class MemoryIndex implements Serializable { this.numTokens = numTokens; this.numOverlapTokens = numOverlapTokens; this.boost = boost; + long sum = 0; + for(Map.Entry ent : terms.entrySet()) { + sum += ent.getValue().size(); + } + sumTotalTermFreq = sum; + } + + public long getSumTotalTermFreq() { + return sumTotalTermFreq; } /** @@ -826,6 +837,11 @@ public class MemoryIndex implements Serializable { public long getUniqueTermCount() { return info.sortedTerms.length; } + + @Override + public long getSumTotalTermFreq() { + return info.getSumTotalTermFreq(); + } }; } } @@ -895,6 +911,11 @@ public class MemoryIndex implements Serializable { return 1; } + @Override + public long totalTermFreq() { + return info.sortedTerms[termUpto].getValue().size(); + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) { if (reuse == null || !(reuse instanceof MemoryDocsEnum)) { diff --git a/lucene/contrib/misc/src/java/org/apache/lucene/misc/HighFreqTerms.java b/lucene/contrib/misc/src/java/org/apache/lucene/misc/HighFreqTerms.java index c0ac082f293..77d29820660 100644 --- a/lucene/contrib/misc/src/java/org/apache/lucene/misc/HighFreqTerms.java +++ b/lucene/contrib/misc/src/java/org/apache/lucene/misc/HighFreqTerms.java @@ -176,15 +176,34 @@ public class HighFreqTerms { return ts; } - public static long getTotalTermFreq(IndexReader reader, String field, BytesRef termtext) throws Exception { - BytesRef br = termtext; + public static long getTotalTermFreq(IndexReader reader, String field, BytesRef termText) throws Exception { + long totalTF = 0; - Bits skipDocs = MultiFields.getDeletedDocs(reader); - DocsEnum de = MultiFields.getTermDocsEnum(reader, skipDocs, field, br); - // if term is not in index return totalTF of 0 - if (de == null) { + + Terms terms = MultiFields.getTerms(reader, field); + if (terms == null) { return 0; } + + TermsEnum termsEnum = terms.iterator(); + if (termsEnum.seek(termText) != TermsEnum.SeekStatus.FOUND) { + return 0; + } + + Bits skipDocs = MultiFields.getDeletedDocs(reader); + if (skipDocs == null) { + // TODO: we could do this up front, during the scan + // (next()), instead of after-the-fact here w/ seek, + // if the codec supports it and there are no del + // docs... + final long totTF = termsEnum.totalTermFreq(); + if (totTF != -1) { + return totTF; + } + } + + DocsEnum de = termsEnum.docs(skipDocs, null); + // use DocsEnum.read() and BulkResult api final DocsEnum.BulkReadResult bulkresult = de.getBulkResult(); int count; diff --git a/lucene/contrib/misc/src/java/org/apache/lucene/misc/TermStats.java b/lucene/contrib/misc/src/java/org/apache/lucene/misc/TermStats.java index b28fbdde436..08c4a808367 100644 --- a/lucene/contrib/misc/src/java/org/apache/lucene/misc/TermStats.java +++ b/lucene/contrib/misc/src/java/org/apache/lucene/misc/TermStats.java @@ -41,4 +41,9 @@ public final class TermStats { String getTermText() { return termtext.utf8ToString(); } + + @Override + public String toString() { + return("TermStats: term=" + termtext.utf8ToString() + " docFreq=" + docFreq + " totalTermFreq=" + totalTermFreq); + } } \ No newline at end of file diff --git a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestHighFreqTerms.java b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestHighFreqTerms.java index 4f164e72b7b..cb33cfa8be9 100644 --- a/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestHighFreqTerms.java +++ b/lucene/contrib/misc/src/test/org/apache/lucene/misc/TestHighFreqTerms.java @@ -17,15 +17,16 @@ package org.apache.lucene.misc; * limitations under the License. */ -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.LuceneTestCase; -import org.apache.lucene.store.Directory; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.analysis.MockTokenizer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.store.Directory; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util._TestUtil; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -41,8 +42,10 @@ public class TestHighFreqTerms extends LuceneTestCase { writer = new IndexWriter(dir, newIndexWriterConfig(random, TEST_VERSION_CURRENT, new MockAnalyzer(MockTokenizer.WHITESPACE, false)) .setMaxBufferedDocs(2)); + writer.setInfoStream(VERBOSE ? System.out : null); indexDocs(writer); reader = IndexReader.open(dir, true); + _TestUtil.checkIndex(dir); } @AfterClass @@ -75,8 +78,8 @@ public class TestHighFreqTerms extends LuceneTestCase { String field="FIELD_1"; TermStats[] terms = HighFreqTerms.getHighFreqTerms(reader, numTerms, field); for (int i = 0; i < terms.length; i++) { - if (i >0){ - assertTrue ("out of order " + terms[i-1].docFreq + "should be >= " + terms[i].docFreq,terms[i-1].docFreq >= terms[i].docFreq); + if (i > 0) { + assertTrue ("out of order " + terms[i-1].docFreq + "should be >= " + terms[i].docFreq,terms[i-1].docFreq >= terms[i].docFreq); } } } @@ -134,11 +137,12 @@ public class TestHighFreqTerms extends LuceneTestCase { TermStats[] terms = HighFreqTerms.getHighFreqTerms(reader, numTerms, field); TermStats[] termsWithTF = HighFreqTerms.sortByTotalTermFreq(reader, terms); - for (int i = 0; i < termsWithTF.length; i++) { - // check that they are sorted by descending termfreq order - if (i >0){ - assertTrue ("out of order" +termsWithTF[i-1]+ " > " +termsWithTF[i],termsWithTF[i-1].totalTermFreq > termsWithTF[i].totalTermFreq); - } + for (int i = 0; i < termsWithTF.length; i++) { + // check that they are sorted by descending termfreq + // order + if (i > 0) { + assertTrue ("out of order" +termsWithTF[i-1]+ " > " +termsWithTF[i],termsWithTF[i-1].totalTermFreq >= termsWithTF[i].totalTermFreq); + } } } diff --git a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java index 5e83c75bc9e..8539f855f9f 100644 --- a/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java +++ b/lucene/contrib/queries/src/java/org/apache/lucene/search/FieldCacheRewriteMethod.java @@ -123,7 +123,11 @@ public final class FieldCacheRewriteMethod extends MultiTermQuery.RewriteMethod public TermsEnum iterator() throws IOException { return fcsi.getTermsEnum(); } - + + @Override + public long getSumTotalTermFreq() { + return -1; + } }); assert termsEnum != null; diff --git a/lucene/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/src/java/org/apache/lucene/index/CheckIndex.java index e825c670e29..b91ec32ffd5 100644 --- a/lucene/src/java/org/apache/lucene/index/CheckIndex.java +++ b/lucene/src/java/org/apache/lucene/index/CheckIndex.java @@ -610,6 +610,8 @@ public class CheckIndex { Comparator termComp = terms.getComparator(); + long sumTotalTermFreq = 0; + while(true) { final BytesRef term = terms.next(); @@ -660,6 +662,8 @@ public class CheckIndex { } int lastDoc = -1; + int docCount = 0; + long totalTermFreq = 0; while(true) { final int doc = docs2.nextDoc(); if (doc == DocIdSetIterator.NO_MORE_DOCS) { @@ -667,6 +671,8 @@ public class CheckIndex { } final int freq = docs2.freq(); status.totPos += freq; + totalTermFreq += freq; + docCount++; if (doc <= lastDoc) { throw new RuntimeException("term " + term + ": doc " + doc + " <= lastDoc " + lastDoc); @@ -697,22 +703,39 @@ public class CheckIndex { } } } + + final long totalTermFreq2 = terms.totalTermFreq(); + final boolean hasTotalTermFreq = postings != null && totalTermFreq2 != -1; - // Now count how many deleted docs occurred in - // this term: - + // Re-count if there are deleted docs: if (reader.hasDeletions()) { final DocsEnum docsNoDel = terms.docs(null, docs); - int count = 0; + docCount = 0; + totalTermFreq = 0; while(docsNoDel.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) { - count++; + docCount++; + totalTermFreq += docsNoDel.freq(); } - if (count != docFreq) { - throw new RuntimeException("term " + term + " docFreq=" + docFreq + " != tot docs w/o deletions " + count); + } + + if (docCount != docFreq) { + throw new RuntimeException("term " + term + " docFreq=" + docFreq + " != tot docs w/o deletions " + docCount); + } + if (hasTotalTermFreq) { + sumTotalTermFreq += totalTermFreq; + if (totalTermFreq != totalTermFreq2) { + throw new RuntimeException("term " + term + " totalTermFreq=" + totalTermFreq2 + " != recomputed totalTermFreq=" + totalTermFreq); } } } + if (sumTotalTermFreq != 0) { + final long v = fields.terms(field).getSumTotalTermFreq(); + if (v != -1 && sumTotalTermFreq != v) { + throw new RuntimeException("sumTotalTermFreq for field " + field + "=" + v + " != recomputed sumTotalTermFreq=" + sumTotalTermFreq); + } + } + // Test seek to last term: if (lastTerm != null) { if (terms.seek(lastTerm) != TermsEnum.SeekStatus.FOUND) { diff --git a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java index ffe82b017dc..a5e830fdeaf 100644 --- a/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/FilterIndexReader.java @@ -99,6 +99,11 @@ public class FilterIndexReader extends IndexReader { public long getUniqueTermCount() throws IOException { return in.getUniqueTermCount(); } + + @Override + public long getSumTotalTermFreq() throws IOException { + return in.getSumTotalTermFreq(); + } } /** Base class for filtering {@link TermsEnum} implementations. */ @@ -155,6 +160,11 @@ public class FilterIndexReader extends IndexReader { return in.docFreq(); } + @Override + public long totalTermFreq() { + return in.totalTermFreq(); + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { return in.docs(skipDocs, reuse); diff --git a/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriter.java b/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriter.java index d749d24b555..7d9df0a661d 100644 --- a/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/FreqProxTermsWriter.java @@ -20,13 +20,14 @@ package org.apache.lucene.index; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.Comparator; -import org.apache.lucene.index.codecs.PostingsConsumer; import org.apache.lucene.index.codecs.FieldsConsumer; +import org.apache.lucene.index.codecs.PostingsConsumer; import org.apache.lucene.index.codecs.TermsConsumer; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CollectionUtil; @@ -165,6 +166,7 @@ final class FreqProxTermsWriter extends TermsHashConsumer { // multiple threads and interacting with the // TermsConsumer, only calling out to us (passing us the // DocsConsumer) to handle delivery of docs/positions + long sumTotalTermFreq = 0; while(numFields > 0) { // Get the next term to merge @@ -197,6 +199,7 @@ final class FreqProxTermsWriter extends TermsHashConsumer { // which all share the same term. Now we must // interleave the docID streams. int numDocs = 0; + long totTF = 0; while(numToMerge > 0) { FreqProxFieldMergeState minState = termStates[0]; @@ -222,6 +225,7 @@ final class FreqProxTermsWriter extends TermsHashConsumer { // omitTermFreqAndPositions == false so we do write positions & // payload int position = 0; + totTF += termDocFreq; for(int j=0;j> 1; @@ -286,9 +290,10 @@ final class FreqProxTermsWriter extends TermsHashConsumer { } assert numDocs > 0; - termsConsumer.finishTerm(text, numDocs); + termsConsumer.finishTerm(text, new TermStats(numDocs, totTF)); + sumTotalTermFreq += totTF; } - termsConsumer.finish(); + termsConsumer.finish(sumTotalTermFreq); } } diff --git a/lucene/src/java/org/apache/lucene/index/IndexReader.java b/lucene/src/java/org/apache/lucene/index/IndexReader.java index 95f4977f177..eb953c687ba 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexReader.java +++ b/lucene/src/java/org/apache/lucene/index/IndexReader.java @@ -997,6 +997,23 @@ public abstract class IndexReader implements Cloneable,Closeable { return terms.docFreq(term); } + /** Returns the number of documents containing the term + * t. This method returns 0 if the term or + * field does not exists. This method does not take into + * account deleted documents that have not yet been merged + * away. */ + public long totalTermFreq(String field, BytesRef term) throws IOException { + final Fields fields = fields(); + if (fields == null) { + return 0; + } + final Terms terms = fields.terms(field); + if (terms == null) { + return 0; + } + return terms.totalTermFreq(term); + } + /** This may return null if the field does not exist.*/ public Terms terms(String field) throws IOException { final Fields fields = fields(); diff --git a/lucene/src/java/org/apache/lucene/index/MultiTerms.java b/lucene/src/java/org/apache/lucene/index/MultiTerms.java index 4e265c056e6..2da5db54df8 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiTerms.java +++ b/lucene/src/java/org/apache/lucene/index/MultiTerms.java @@ -76,6 +76,19 @@ public final class MultiTerms extends Terms { } } + @Override + public long getSumTotalTermFreq() throws IOException { + long sum = 0; + for(Terms terms : subs) { + final long v = terms.getSumTotalTermFreq(); + if (v == -1) { + return -1; + } + sum += v; + } + return sum; + } + @Override public Comparator getComparator() { return termComp; diff --git a/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java b/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java index 1f4794f3f9f..ded70270901 100644 --- a/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/index/MultiTermsEnum.java @@ -265,6 +265,19 @@ public final class MultiTermsEnum extends TermsEnum { return sum; } + @Override + public long totalTermFreq() { + long sum = 0; + for(int i=0;i= 0; - final long termsStartPointer = in.readLong(); + final long termsStartPointer = in.readVLong(); final FieldInfo fieldInfo = fieldInfos.fieldInfo(field); - if (numTerms > 0) { - assert !fields.containsKey(fieldInfo.name); - fields.put(fieldInfo.name, new FieldReader(fieldInfo, numTerms, termsStartPointer)); - } + final long sumTotalTermFreq = fieldInfo.omitTermFreqAndPositions ? -1 : in.readVLong(); + assert !fields.containsKey(fieldInfo.name); + fields.put(fieldInfo.name, new FieldReader(fieldInfo, numTerms, termsStartPointer, sumTotalTermFreq)); } success = true; } finally { @@ -245,12 +244,14 @@ public class PrefixCodedTermsReader extends FieldsProducer { final long numTerms; final FieldInfo fieldInfo; final long termsStartPointer; + final long sumTotalTermFreq; - FieldReader(FieldInfo fieldInfo, long numTerms, long termsStartPointer) { + FieldReader(FieldInfo fieldInfo, long numTerms, long termsStartPointer, long sumTotalTermFreq) { assert numTerms > 0; this.fieldInfo = fieldInfo; this.numTerms = numTerms; this.termsStartPointer = termsStartPointer; + this.sumTotalTermFreq = sumTotalTermFreq; } @Override @@ -273,6 +274,11 @@ public class PrefixCodedTermsReader extends FieldsProducer { return numTerms; } + @Override + public long getSumTotalTermFreq() { + return sumTotalTermFreq; + } + // Iterates through terms in this field, not supporting ord() private final class SegmentTermsEnum extends TermsEnum { private final IndexInput in; @@ -295,6 +301,7 @@ public class PrefixCodedTermsReader extends FieldsProducer { bytesReader = new DeltaBytesReader(in); fieldTerm.field = fieldInfo.name; state = postingsReader.newTermState(); + state.totalTermFreq = -1; state.ord = -1; } @@ -494,6 +501,10 @@ public class PrefixCodedTermsReader extends FieldsProducer { state.docFreq = (in.readVInt() << 6) | (b & 0x3F); } + if (!fieldInfo.omitTermFreqAndPositions) { + state.totalTermFreq = state.docFreq + in.readVLong(); + } + postingsReader.readTerm(in, fieldInfo, state, isIndexTerm); @@ -511,6 +522,11 @@ public class PrefixCodedTermsReader extends FieldsProducer { return state.docFreq; } + @Override + public long totalTermFreq() { + return state.totalTermFreq; + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { final DocsEnum docsEnum = postingsReader.docs(fieldInfo, state, skipDocs, reuse); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsWriter.java b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsWriter.java index fa87f7f19d3..2be4ce1834d 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermsWriter.java @@ -60,7 +60,7 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { final FieldInfos fieldInfos; FieldInfo currentField; private final TermsIndexWriterBase termsIndexWriter; - private final List fields = new ArrayList(); + private final List fields = new ArrayList(); private final Comparator termComp; public PrefixCodedTermsWriter( @@ -96,7 +96,7 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { assert currentField == null || currentField.name.compareTo(field.name) < 0; currentField = field; TermsIndexWriterBase.FieldWriter fieldIndexWriter = termsIndexWriter.addField(field); - TermsConsumer terms = new TermsWriter(fieldIndexWriter, field, postingsWriter); + final TermsWriter terms = new TermsWriter(fieldIndexWriter, field, postingsWriter); fields.add(terms); return terms; } @@ -105,16 +105,26 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { public void close() throws IOException { try { - final int fieldCount = fields.size(); + + int nonZeroCount = 0; + for(TermsWriter field : fields) { + if (field.numTerms > 0) { + nonZeroCount++; + } + } final long dirStart = out.getFilePointer(); - out.writeInt(fieldCount); - for(int i=0;i 0) { + out.writeVInt(field.fieldInfo.number); + out.writeVLong(field.numTerms); + out.writeVLong(field.termsStartPointer); + if (!field.fieldInfo.omitTermFreqAndPositions) { + out.writeVLong(field.sumTotalTermFreq); + } + } } writeTrailer(dirStart); } finally { @@ -142,6 +152,7 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { private final long termsStartPointer; private long numTerms; private final TermsIndexWriterBase.FieldWriter fieldIndexWriter; + long sumTotalTermFreq; TermsWriter( TermsIndexWriterBase.FieldWriter fieldIndexWriter, @@ -169,12 +180,12 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { } @Override - public void finishTerm(BytesRef text, int numDocs) throws IOException { + public void finishTerm(BytesRef text, TermStats stats) throws IOException { - assert numDocs > 0; + assert stats.docFreq > 0; //System.out.println("finishTerm term=" + fieldInfo.name + ":" + text.utf8ToString() + " fp=" + out.getFilePointer()); - final boolean isIndexTerm = fieldIndexWriter.checkIndexTerm(text, numDocs); + final boolean isIndexTerm = fieldIndexWriter.checkIndexTerm(text, stats); termWriter.write(text); final int highBit = isIndexTerm ? 0x80 : 0; @@ -182,23 +193,28 @@ public class PrefixCodedTermsWriter extends FieldsConsumer { // This is a vInt, except, we steal top bit to record // whether this was an indexed term: - if ((numDocs & ~0x3F) == 0) { + if ((stats.docFreq & ~0x3F) == 0) { // Fast case -- docFreq fits in 6 bits - out.writeByte((byte) (highBit | numDocs)); + out.writeByte((byte) (highBit | stats.docFreq)); } else { // Write bottom 6 bits of docFreq, then write the // remainder as vInt: - out.writeByte((byte) (highBit | 0x40 | (numDocs & 0x3F))); - out.writeVInt(numDocs >>> 6); + out.writeByte((byte) (highBit | 0x40 | (stats.docFreq & 0x3F))); + out.writeVInt(stats.docFreq >>> 6); } - postingsWriter.finishTerm(numDocs, isIndexTerm); + if (!fieldInfo.omitTermFreqAndPositions) { + assert stats.totalTermFreq >= stats.docFreq; + out.writeVLong(stats.totalTermFreq - stats.docFreq); + } + postingsWriter.finishTerm(stats, isIndexTerm); numTerms++; } // Finishes all terms in this field @Override - public void finish() throws IOException { + public void finish(long sumTotalTermFreq) throws IOException { // EOF marker: + this.sumTotalTermFreq = sumTotalTermFreq; out.writeVInt(DeltaBytesWriter.TERM_EOF); fieldIndexWriter.finish(); } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/TermStats.java b/lucene/src/java/org/apache/lucene/index/codecs/TermStats.java new file mode 100644 index 00000000000..bb2b6f34d27 --- /dev/null +++ b/lucene/src/java/org/apache/lucene/index/codecs/TermStats.java @@ -0,0 +1,28 @@ +package org.apache.lucene.index.codecs; + +/** + * 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. + */ + +public class TermStats { + public final int docFreq; + public final long totalTermFreq; + + public TermStats(int docFreq, long totalTermFreq) { + this.docFreq = docFreq; + this.totalTermFreq = totalTermFreq; + } +} diff --git a/lucene/src/java/org/apache/lucene/index/codecs/TermsConsumer.java b/lucene/src/java/org/apache/lucene/index/codecs/TermsConsumer.java index 48fc7e01660..7c9095ec756 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/TermsConsumer.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/TermsConsumer.java @@ -38,10 +38,10 @@ public abstract class TermsConsumer { public abstract PostingsConsumer startTerm(BytesRef text) throws IOException; /** Finishes the current term; numDocs must be > 0. */ - public abstract void finishTerm(BytesRef text, int numDocs) throws IOException; + public abstract void finishTerm(BytesRef text, TermStats stats) throws IOException; /** Called when we are done adding terms to this field */ - public abstract void finish() throws IOException; + public abstract void finish(long sumTotalTermFreq) throws IOException; /** Return the BytesRef Comparator used to sort terms * before feeding to this API. */ @@ -55,6 +55,7 @@ public abstract class TermsConsumer { BytesRef term; assert termsEnum != null; + long sumTotalTermFreq = 0; if (mergeState.fieldInfo.omitTermFreqAndPositions) { if (docsEnum == null) { @@ -69,9 +70,9 @@ public abstract class TermsConsumer { if (docsEnumIn != null) { docsEnum.reset(docsEnumIn); final PostingsConsumer postingsConsumer = startTerm(term); - final int numDocs = postingsConsumer.merge(mergeState, docsEnum); - if (numDocs > 0) { - finishTerm(term, numDocs); + final TermStats stats = postingsConsumer.merge(mergeState, docsEnum); + if (stats.docFreq > 0) { + finishTerm(term, stats); } } } @@ -94,14 +95,15 @@ public abstract class TermsConsumer { } } final PostingsConsumer postingsConsumer = startTerm(term); - final int numDocs = postingsConsumer.merge(mergeState, postingsEnum); - if (numDocs > 0) { - finishTerm(term, numDocs); + final TermStats stats = postingsConsumer.merge(mergeState, postingsEnum); + if (stats.docFreq > 0) { + finishTerm(term, stats); + sumTotalTermFreq += stats.totalTermFreq; } } } } - finish(); + finish(sumTotalTermFreq); } } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java b/lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java index e74cd1a52d0..37985013951 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/TermsIndexWriterBase.java @@ -28,7 +28,7 @@ public abstract class TermsIndexWriterBase { public abstract void setTermsOutput(IndexOutput out); public abstract class FieldWriter { - public abstract boolean checkIndexTerm(BytesRef text, int docFreq) throws IOException; + public abstract boolean checkIndexTerm(BytesRef text, TermStats stats) throws IOException; public abstract void finish() throws IOException; } diff --git a/lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java b/lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java index 12195e813ae..059bf573bec 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/VariableGapTermsIndexWriter.java @@ -59,7 +59,7 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase { public static abstract class IndexTermSelector { // Called sequentially on every term being written, // returning true if this term should be indexed - public abstract boolean isIndexTerm(BytesRef term, int docFreq); + public abstract boolean isIndexTerm(BytesRef term, TermStats stats); } /** Same policy as {@link FixedGapTermsIndexWriter} */ @@ -74,7 +74,7 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase { } @Override - public boolean isIndexTerm(BytesRef term, int docFreq) { + public boolean isIndexTerm(BytesRef term, TermStats stats) { if (count >= interval) { count = 0; return true; @@ -99,8 +99,8 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase { } @Override - public boolean isIndexTerm(BytesRef term, int docFreq) { - if (docFreq >= docFreqThresh || count >= interval) { + public boolean isIndexTerm(BytesRef term, TermStats stats) { + if (stats.docFreq >= docFreqThresh || count >= interval) { count = 0; return true; } else { @@ -214,8 +214,8 @@ public class VariableGapTermsIndexWriter extends TermsIndexWriterBase { } @Override - public boolean checkIndexTerm(BytesRef text, int docFreq) throws IOException { - if (policy.isIndexTerm(text, docFreq) || first) { + public boolean checkIndexTerm(BytesRef text, TermStats stats) throws IOException { + if (policy.isIndexTerm(text, stats) || first) { first = false; //System.out.println("VGW: index term=" + text.utf8ToString() + " fp=" + termsOut.getFilePointer()); final int lengthSave = text.length; diff --git a/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java b/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java index 3f54b0b9037..fe90eac93be 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java @@ -33,7 +33,6 @@ import org.apache.lucene.index.FieldsEnum; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentInfo; import org.apache.lucene.index.Term; -import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; import org.apache.lucene.index.CompoundFileReader; @@ -263,6 +262,11 @@ public class PreFlexFields extends FieldsProducer { return BytesRef.getUTF8SortedAsUTF16Comparator(); } } + + @Override + public long getSumTotalTermFreq() { + return -1; + } } private class PreTermsEnum extends TermsEnum { @@ -938,6 +942,11 @@ public class PreFlexFields extends FieldsProducer { return termEnum.docFreq(); } + @Override + public long totalTermFreq() { + return -1; + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { PreDocsEnum docsEnum; diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java index 32f647d0adf..a018122c567 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java @@ -21,6 +21,7 @@ import java.io.IOException; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.codecs.PostingsWriterBase; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.store.RAMOutputStream; import org.apache.lucene.util.BytesRef; @@ -177,7 +178,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { /** Called when we are done adding docs to this term */ @Override - public void finishTerm(int docCount, boolean isIndexTerm) throws IOException { + public void finishTerm(TermStats stats, boolean isIndexTerm) throws IOException { //System.out.println("PW finishTerm docCount=" + docCount); assert pendingCount > 0 || pendingCount == -1; @@ -186,7 +187,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { if (pendingCount == -1) { termsOut.writeByte((byte) 0); - wrappedPostingsWriter.finishTerm(docCount, pendingIsIndexTerm); + wrappedPostingsWriter.finishTerm(stats, pendingIsIndexTerm); pendingIsIndexTerm = false; } else { diff --git a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java index 6be97d22f9d..7e1fb17787c 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/sep/SepPostingsWriterImpl.java @@ -25,6 +25,7 @@ import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.index.codecs.PostingsWriterBase; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.store.IndexOutput; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; @@ -239,11 +240,11 @@ public final class SepPostingsWriterImpl extends PostingsWriterBase { /** Called when we are done adding docs to this term */ @Override - public void finishTerm(int docCount, boolean isIndexTerm) throws IOException { + public void finishTerm(TermStats stats, boolean isIndexTerm) throws IOException { // TODO: -- wasteful we are counting this in two places? - assert docCount > 0; - assert docCount == df; + assert stats.docFreq > 0; + assert stats.docFreq == df; docIndex.write(termsOut, isIndexTerm); diff --git a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java index 673f2261335..e40fba2f44e 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsReader.java @@ -21,7 +21,6 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.index.codecs.FieldsProducer; import org.apache.lucene.index.SegmentReadState; import org.apache.lucene.index.FieldsEnum; -import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.DocsEnum; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -119,28 +118,31 @@ class SimpleTextFieldsReader extends FieldsProducer { private final IndexInput in; private final boolean omitTF; private int docFreq; + private long totalTermFreq; private long docsStart; private boolean ended; - private final BytesRefFSTEnum> fstEnum; + private final BytesRefFSTEnum>> fstEnum; - public SimpleTextTermsEnum(FST> fst, boolean omitTF) throws IOException { + public SimpleTextTermsEnum(FST>> fst, boolean omitTF) throws IOException { this.in = (IndexInput) SimpleTextFieldsReader.this.in.clone(); this.omitTF = omitTF; - fstEnum = new BytesRefFSTEnum>(fst); + fstEnum = new BytesRefFSTEnum>>(fst); } public SeekStatus seek(BytesRef text, boolean useCache /* ignored */) throws IOException { //System.out.println("seek to text=" + text.utf8ToString()); - final BytesRefFSTEnum.InputOutput> result = fstEnum.seekCeil(text); + final BytesRefFSTEnum.InputOutput>> result = fstEnum.seekCeil(text); if (result == null) { //System.out.println(" end"); return SeekStatus.END; } else { //System.out.println(" got text=" + term.utf8ToString()); - PairOutputs.Pair pair = result.output; - docsStart = pair.output1; - docFreq = pair.output2.intValue(); + PairOutputs.Pair> pair1 = result.output; + PairOutputs.Pair pair2 = pair1.output2; + docsStart = pair1.output1; + docFreq = pair2.output1.intValue(); + totalTermFreq = pair2.output2; if (result.input.equals(text)) { //System.out.println(" match docsStart=" + docsStart); @@ -155,11 +157,13 @@ class SimpleTextFieldsReader extends FieldsProducer { @Override public BytesRef next() throws IOException { assert !ended; - final BytesRefFSTEnum.InputOutput> result = fstEnum.next(); + final BytesRefFSTEnum.InputOutput>> result = fstEnum.next(); if (result != null) { - final PairOutputs.Pair pair = result.output; - docsStart = pair.output1; - docFreq = pair.output2.intValue(); + PairOutputs.Pair> pair1 = result.output; + PairOutputs.Pair pair2 = pair1.output2; + docsStart = pair1.output1; + docFreq = pair2.output1.intValue(); + totalTermFreq = pair2.output2; return result.input; } else { return null; @@ -186,6 +190,11 @@ class SimpleTextFieldsReader extends FieldsProducer { return docFreq; } + @Override + public long totalTermFreq() { + return totalTermFreq; + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { SimpleTextDocsEnum docsEnum; @@ -438,8 +447,9 @@ class SimpleTextFieldsReader extends FieldsProducer { private class SimpleTextTerms extends Terms { private final long termsStart; private final boolean omitTF; - private FST> fst; - + private long sumTotalTermFreq; + private FST>> fst; + private int termCount; private final BytesRef scratch = new BytesRef(10); public SimpleTextTerms(String field, long termsStart) throws IOException { @@ -450,24 +460,38 @@ class SimpleTextFieldsReader extends FieldsProducer { private void loadTerms() throws IOException { PositiveIntOutputs posIntOutputs = PositiveIntOutputs.getSingleton(false); - Builder> b = new Builder>(FST.INPUT_TYPE.BYTE1, 0, 0, true, new PairOutputs(posIntOutputs, posIntOutputs)); + final Builder>> b; + b = new Builder>>(FST.INPUT_TYPE.BYTE1, + 0, + 0, + true, + new PairOutputs>(posIntOutputs, + new PairOutputs(posIntOutputs, posIntOutputs))); IndexInput in = (IndexInput) SimpleTextFieldsReader.this.in.clone(); in.seek(termsStart); final BytesRef lastTerm = new BytesRef(10); long lastDocsStart = -1; int docFreq = 0; + long totalTermFreq = 0; while(true) { readLine(in, scratch); if (scratch.equals(END) || scratch.startsWith(FIELD)) { if (lastDocsStart != -1) { - b.add(lastTerm, new PairOutputs.Pair(lastDocsStart, Long.valueOf(docFreq))); + b.add(lastTerm, new PairOutputs.Pair>(lastDocsStart, + new PairOutputs.Pair((long) docFreq, + posIntOutputs.get(totalTermFreq)))); + sumTotalTermFreq += totalTermFreq; } break; } else if (scratch.startsWith(DOC)) { docFreq++; + } else if (scratch.startsWith(POS)) { + totalTermFreq++; } else if (scratch.startsWith(TERM)) { if (lastDocsStart != -1) { - b.add(lastTerm, new PairOutputs.Pair(lastDocsStart, Long.valueOf(docFreq))); + b.add(lastTerm, new PairOutputs.Pair>(lastDocsStart, + new PairOutputs.Pair((long) docFreq, + posIntOutputs.get(totalTermFreq)))); } lastDocsStart = in.getFilePointer(); final int len = scratch.length - TERM.length; @@ -477,6 +501,9 @@ class SimpleTextFieldsReader extends FieldsProducer { System.arraycopy(scratch.bytes, TERM.length, lastTerm.bytes, 0, len); lastTerm.length = len; docFreq = 0; + sumTotalTermFreq += totalTermFreq; + totalTermFreq = 0; + termCount++; } } fst = b.finish(); @@ -502,6 +529,16 @@ class SimpleTextFieldsReader extends FieldsProducer { public Comparator getComparator() { return BytesRef.getUTF8SortedAsUnicodeComparator(); } + + @Override + public long getUniqueTermCount() { + return (long) termCount; + } + + @Override + public long getSumTotalTermFreq() { + return sumTotalTermFreq; + } } @Override diff --git a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsWriter.java b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsWriter.java index ae6338943e0..128da45c9b7 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/simpletext/SimpleTextFieldsWriter.java @@ -22,6 +22,7 @@ import org.apache.lucene.util.UnicodeUtil; import org.apache.lucene.index.codecs.FieldsConsumer; import org.apache.lucene.index.codecs.TermsConsumer; import org.apache.lucene.index.codecs.PostingsConsumer; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.store.IndexOutput; @@ -84,11 +85,11 @@ class SimpleTextFieldsWriter extends FieldsConsumer { } @Override - public void finishTerm(BytesRef term, int numDocs) throws IOException { + public void finishTerm(BytesRef term, TermStats stats) throws IOException { } @Override - public void finish() throws IOException { + public void finish(long sumTotalTermFreq) throws IOException { } @Override diff --git a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsWriter.java b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsWriter.java index 6dafdcda728..8f580e57282 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/standard/StandardPostingsWriter.java @@ -28,6 +28,7 @@ import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.index.IndexFileNames; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.codecs.PostingsWriterBase; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; @@ -184,12 +185,12 @@ public final class StandardPostingsWriter extends PostingsWriterBase { /** Called when we are done adding docs to this term */ @Override - public void finishTerm(int docCount, boolean isIndexTerm) throws IOException { - assert docCount > 0; + public void finishTerm(TermStats stats, boolean isIndexTerm) throws IOException { + assert stats.docFreq > 0; // TODO: wasteful we are counting this (counting # docs // for this term) in two places? - assert docCount == df; + assert stats.docFreq == df; if (isIndexTerm) { // Write absolute at seek points diff --git a/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java b/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java index 7353b9c3cdf..3415c9057d0 100644 --- a/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/search/FilteredTermsEnum.java @@ -126,6 +126,11 @@ public abstract class FilteredTermsEnum extends TermsEnum { return tenum.docFreq(); } + @Override + public long totalTermFreq() { + return tenum.totalTermFreq(); + } + /** This enum does not support seeking! * @throws UnsupportedOperationException */ diff --git a/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java b/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java index f8e67b267f3..c18d7643470 100644 --- a/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java +++ b/lucene/src/java/org/apache/lucene/search/FuzzyTermsEnum.java @@ -244,6 +244,11 @@ public final class FuzzyTermsEnum extends TermsEnum { public int docFreq() { return actualEnum.docFreq(); } + + @Override + public long totalTermFreq() { + return actualEnum.totalTermFreq(); + } @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java b/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java index 314a3a2da72..61e80998b57 100644 --- a/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java +++ b/lucene/src/java/org/apache/lucene/search/cache/DocTermsIndexCreator.java @@ -28,7 +28,6 @@ import org.apache.lucene.index.OrdTermState; import org.apache.lucene.index.TermState; import org.apache.lucene.index.Terms; import org.apache.lucene.index.TermsEnum; -import org.apache.lucene.index.codecs.PrefixCodedTermState; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.FieldCache.DocTermsIndex; import org.apache.lucene.util.ArrayUtil; @@ -321,6 +320,11 @@ public class DocTermsIndexCreator extends EntryCreatorWithOptions throw new UnsupportedOperationException(); } + @Override + public long totalTermFreq() { + return -1; + } + @Override public DocsEnum docs(Bits skipDocs, DocsEnum reuse) throws IOException { throw new UnsupportedOperationException(); diff --git a/lucene/src/test/org/apache/lucene/TestExternalCodecs.java b/lucene/src/test/org/apache/lucene/TestExternalCodecs.java index 0b97c1bef31..a1ecf79ac68 100644 --- a/lucene/src/test/org/apache/lucene/TestExternalCodecs.java +++ b/lucene/src/test/org/apache/lucene/TestExternalCodecs.java @@ -102,6 +102,8 @@ public class TestExternalCodecs extends LuceneTestCase { static class RAMField extends Terms { final String field; final SortedMap termToDocs = new TreeMap(); + long sumTotalTermFreq; + RAMField(String field) { this.field = field; } @@ -111,6 +113,11 @@ public class TestExternalCodecs extends LuceneTestCase { return termToDocs.size(); } + @Override + public long getSumTotalTermFreq() { + return sumTotalTermFreq; + } + @Override public TermsEnum iterator() { return new RAMTermsEnum(RAMOnlyCodec.RAMField.this); @@ -124,6 +131,7 @@ public class TestExternalCodecs extends LuceneTestCase { static class RAMTerm { final String term; + long totalTermFreq; final List docs = new ArrayList(); public RAMTerm(String term) { this.term = term; @@ -189,14 +197,16 @@ public class TestExternalCodecs extends LuceneTestCase { } @Override - public void finishTerm(BytesRef text, int numDocs) { - assert numDocs > 0; - assert numDocs == current.docs.size(); + public void finishTerm(BytesRef text, TermStats stats) { + assert stats.docFreq > 0; + assert stats.docFreq == current.docs.size(); + current.totalTermFreq = stats.totalTermFreq; field.termToDocs.put(current.term, current); } @Override - public void finish() { + public void finish(long sumTotalTermFreq) { + field.sumTotalTermFreq = sumTotalTermFreq; } } @@ -331,6 +341,10 @@ public class TestExternalCodecs extends LuceneTestCase { } @Override + public long totalTermFreq() { + return ramField.termToDocs.get(current).totalTermFreq; + } + public DocsEnum docs(Bits skipDocs, DocsEnum reuse) { return new RAMDocsEnum(ramField.termToDocs.get(current), skipDocs); } diff --git a/lucene/src/test/org/apache/lucene/index/TestCodecs.java b/lucene/src/test/org/apache/lucene/index/TestCodecs.java index f21baadca49..cabf1d330d7 100644 --- a/lucene/src/test/org/apache/lucene/index/TestCodecs.java +++ b/lucene/src/test/org/apache/lucene/index/TestCodecs.java @@ -30,6 +30,7 @@ import org.apache.lucene.index.codecs.FieldsConsumer; import org.apache.lucene.index.codecs.FieldsProducer; import org.apache.lucene.index.codecs.PostingsConsumer; import org.apache.lucene.index.codecs.TermsConsumer; +import org.apache.lucene.index.codecs.TermStats; import org.apache.lucene.index.codecs.mocksep.MockSepCodec; import org.apache.lucene.index.codecs.preflex.PreFlexCodec; import org.apache.lucene.search.DocIdSetIterator; @@ -97,9 +98,11 @@ public class TestCodecs extends LuceneTestCase { public void write(final FieldsConsumer consumer) throws Throwable { Arrays.sort(terms); final TermsConsumer termsConsumer = consumer.addField(fieldInfo); - for (final TermData term : terms) - term.write(termsConsumer); - termsConsumer.finish(); + long sumTotalTermCount = 0; + for (final TermData term : terms) { + sumTotalTermCount += term.write(termsConsumer); + } + termsConsumer.finish(sumTotalTermCount); } } @@ -131,8 +134,9 @@ public class TestCodecs extends LuceneTestCase { return text.compareTo(((TermData) o).text); } - public void write(final TermsConsumer termsConsumer) throws Throwable { + public long write(final TermsConsumer termsConsumer) throws Throwable { final PostingsConsumer postingsConsumer = termsConsumer.startTerm(text); + long totTF = 0; for(int i=0;i 0) { + public void finishTerm(BytesRef text, TermStats stats) throws IOException { + if (stats.docFreq > 0) { long skipPointer = skipListWriter.writeSkip(freqOut); - termInfo.docFreq = numDocs; + termInfo.docFreq = stats.docFreq; termInfo.skipOffset = (int) (skipPointer - termInfo.freqPointer); //System.out.println(" w finish term=" + text.utf8ToString() + " fnum=" + fieldInfo.number); termsOut.add(fieldInfo.number, @@ -197,7 +198,7 @@ class PreFlexFieldsWriter extends FieldsConsumer { } @Override - public void finish() throws IOException { + public void finish(long sumTotalTermCount) throws IOException { } @Override diff --git a/solr/src/java/org/apache/solr/request/UnInvertedField.java b/solr/src/java/org/apache/solr/request/UnInvertedField.java index d724961cb22..79c909bea21 100755 --- a/solr/src/java/org/apache/solr/request/UnInvertedField.java +++ b/solr/src/java/org/apache/solr/request/UnInvertedField.java @@ -1000,6 +1000,10 @@ class NumberedTermsEnum extends TermsEnum { return tenum.docFreq(); } + @Override + public long totalTermFreq() { + return tenum.totalTermFreq(); + } public BytesRef skipTo(BytesRef target) throws IOException { From bcbf1d462c85bc3a2bea23459b82c321706a6509 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Sat, 15 Jan 2011 15:38:49 +0000 Subject: [PATCH 069/252] LUCENE-2862: fix false failure git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059360 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/index/TestIndexReader.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java index a459fe6b3ab..632e8cf37d5 100644 --- a/lucene/src/test/org/apache/lucene/index/TestIndexReader.java +++ b/lucene/src/test/org/apache/lucene/index/TestIndexReader.java @@ -29,7 +29,7 @@ import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.SortedSet; - +import org.junit.Assume; import org.apache.lucene.analysis.MockAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; @@ -1877,10 +1877,15 @@ public class TestIndexReader extends LuceneTestCase IndexReader r = writer.getReader(); writer.close(); Terms terms = MultiFields.getTerms(r, "f"); - assertEquals(1, terms.totalTermFreq(new BytesRef("b"))); - assertEquals(2, terms.totalTermFreq(new BytesRef("a"))); - assertEquals(1, terms.totalTermFreq(new BytesRef("b"))); - r.close(); - dir.close(); + try { + // Make sure codec impls totalTermFreq (eg PreFlex doesn't) + Assume.assumeTrue(terms.totalTermFreq(new BytesRef("b")) != -1); + assertEquals(1, terms.totalTermFreq(new BytesRef("b"))); + assertEquals(2, terms.totalTermFreq(new BytesRef("a"))); + assertEquals(1, terms.totalTermFreq(new BytesRef("b"))); + } finally { + r.close(); + dir.close(); + } } } From d08d4645287598f87e56ce62980a13e64623107a Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Sat, 15 Jan 2011 16:46:35 +0000 Subject: [PATCH 070/252] LUCENE-2862: use the stats instead of an extra byte in pulsing git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059371 13f79535-47bb-0310-9956-ffa450edef68 --- .../codecs/pulsing/PulsingPostingsReaderImpl.java | 7 +++++-- .../codecs/pulsing/PulsingPostingsWriterImpl.java | 12 +++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java index ac497a4e5a8..8a36a22082a 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsReaderImpl.java @@ -54,6 +54,7 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { public void init(IndexInput termsIn) throws IOException { CodecUtil.checkHeader(termsIn, PulsingPostingsWriterImpl.CODEC, PulsingPostingsWriterImpl.VERSION_START, PulsingPostingsWriterImpl.VERSION_START); + maxPositions = termsIn.readVInt(); wrappedPostingsReader.init(termsIn); } @@ -115,8 +116,10 @@ public class PulsingPostingsReaderImpl extends PostingsReaderBase { termState.pendingIndexTerm |= isIndexTerm; - // TODO: wasteful to use whole byte for this (need just a 1 bit); - if (termsIn.readByte() == 1) { + // total TF, but in the omitTFAP case its computed based on docFreq. + long count = fieldInfo.omitTermFreqAndPositions ? termState.docFreq : termState.totalTermFreq; + + if (count <= maxPositions) { // Inlined into terms dict -- just read the byte[] blob in, // but don't decode it now (we only decode when a DocsEnum diff --git a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java index a018122c567..94c39c12173 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/pulsing/PulsingPostingsWriterImpl.java @@ -27,10 +27,10 @@ import org.apache.lucene.store.RAMOutputStream; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.CodecUtil; -// TODO: we now pulse entirely according to docFreq of the -// term; it might be better to eg pulse by "net bytes used" -// so that a term that has only 1 doc but zillions of -// positions would not be inlined. Though this is +// TODO: we pulse based on total TF of the term, +// it might be better to eg pulse by "net bytes used" +// so that a term that has only 1 posting but a huge +// payload would not be inlined. Though this is // presumably rare in practice... /** @lucene.experimental */ @@ -86,6 +86,7 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { public void start(IndexOutput termsOut) throws IOException { this.termsOut = termsOut; CodecUtil.writeHeader(termsOut, CODEC, VERSION_CURRENT); + termsOut.writeVInt(pending.length); // encode maxPositions in header wrappedPostingsWriter.start(termsOut); } @@ -186,7 +187,6 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { pendingIsIndexTerm |= isIndexTerm; if (pendingCount == -1) { - termsOut.writeByte((byte) 0); wrappedPostingsWriter.finishTerm(stats, pendingIsIndexTerm); pendingIsIndexTerm = false; } else { @@ -195,8 +195,6 @@ public final class PulsingPostingsWriterImpl extends PostingsWriterBase { // term, so we fully inline our postings data into // terms dict, now: - termsOut.writeByte((byte) 1); - // TODO: it'd be better to share this encoding logic // in some inner codec that knows how to write a // single doc / single position, etc. This way if a From 12a35431a943f7f98282495a963ceefaa5978eb2 Mon Sep 17 00:00:00 2001 From: Koji Sekiguchi Date: Sun, 16 Jan 2011 00:12:58 +0000 Subject: [PATCH 071/252] SOLR-2282: fix concurrency for distributed search test git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059426 13f79535-47bb-0310-9956-ffa450edef68 --- solr/contrib/clustering/CHANGES.txt | 4 ++-- .../handler/clustering/carrot2/CarrotClusteringEngine.java | 2 +- .../clustering/carrot2/LuceneLanguageModelFactory.java | 2 +- .../clustering/DistributedClusteringComponentTest.java | 3 --- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/solr/contrib/clustering/CHANGES.txt b/solr/contrib/clustering/CHANGES.txt index 80ae3136914..a350571fb4f 100644 --- a/solr/contrib/clustering/CHANGES.txt +++ b/solr/contrib/clustering/CHANGES.txt @@ -18,9 +18,9 @@ $Id$ This release of C2 also does not have a specific Lucene dependency. (Stanislaw Osinski, gsingers) * SOLR-2282: Add distributed search support for search result clustering. - (Brad Giaccio, koji) + (Brad Giaccio, Dawid Weiss, Stanislaw Osinski, rmuir, koji) ================== Release 1.4.0 ================== Solr Clustering will be released for the first time in Solr 1.4. See http://wiki.apache.org/solr/ClusteringComponent - for details on using. \ No newline at end of file + for details on using. diff --git a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/CarrotClusteringEngine.java b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/CarrotClusteringEngine.java index 55f38515997..126ea09c744 100644 --- a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/CarrotClusteringEngine.java +++ b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/CarrotClusteringEngine.java @@ -124,7 +124,7 @@ public class CarrotClusteringEngine extends SearchClusteringEngine { // is included in the code base of Solr, so that it's possible to refactor // the Lucene APIs the factory relies on if needed. initAttributes.put("PreprocessingPipeline.languageModelFactory", - new LuceneLanguageModelFactory()); + LuceneLanguageModelFactory.class); this.controller.init(initAttributes); this.idFieldName = core.getSchema().getUniqueKeyField().getName(); diff --git a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java index ddb3d59bce8..8efd3ab1be6 100644 --- a/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java +++ b/solr/contrib/clustering/src/main/java/org/apache/solr/handler/clustering/carrot2/LuceneLanguageModelFactory.java @@ -200,7 +200,7 @@ public class LuceneLanguageModelFactory extends DefaultLanguageModelFactory { logger .warn( "Could not instantiate Lucene stemmer for Arabic, clustering quality " - + "of Chinese content may be degraded. For best quality clusters, " + + "of Arabic content may be degraded. For best quality clusters, " + "make sure Lucene's Arabic analyzer JAR is in the classpath", e); } diff --git a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java index 51c9726d95f..758d829f7cd 100644 --- a/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java +++ b/solr/contrib/clustering/src/test/java/org/apache/solr/handler/clustering/DistributedClusteringComponentTest.java @@ -20,9 +20,6 @@ package org.apache.solr.handler.clustering; import org.apache.solr.BaseDistributedSearchTestCase; import org.apache.solr.common.params.CommonParams; -import org.junit.Ignore; - -@Ignore("FIXME: test fails on hudson") public class DistributedClusteringComponentTest extends BaseDistributedSearchTestCase { From 88b63174acbefedcd5264dc2a4492279a6b267cb Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Sun, 16 Jan 2011 02:28:24 +0000 Subject: [PATCH 072/252] LUCENE-2846: remove dead code git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059435 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/index/SegmentReader.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/SegmentReader.java b/lucene/src/java/org/apache/lucene/index/SegmentReader.java index 498b98275ca..e8c5160d367 100644 --- a/lucene/src/java/org/apache/lucene/index/SegmentReader.java +++ b/lucene/src/java/org/apache/lucene/index/SegmentReader.java @@ -335,29 +335,6 @@ public class SegmentReader extends IndexReader implements Cloneable { } } - // Load bytes but do not cache them if they were not - // already cached - public synchronized void bytes(byte[] bytesOut, int offset, int len) throws IOException { - assert refCount > 0 && (origNorm == null || origNorm.refCount > 0); - if (bytes != null) { - // Already cached -- copy from cache: - assert len <= maxDoc(); - System.arraycopy(bytes, 0, bytesOut, offset, len); - } else { - // Not cached - if (origNorm != null) { - // Ask origNorm to load - origNorm.bytes(bytesOut, offset, len); - } else { - // We are orig -- read ourselves from disk: - synchronized(in) { - in.seek(normSeek); - in.readBytes(bytesOut, offset, len, false); - } - } - } - } - // Load & cache full bytes array. Returns bytes. public synchronized byte[] bytes() throws IOException { assert refCount > 0 && (origNorm == null || origNorm.refCount > 0); From 15a72e7698194082c42cc42937b086ec9b1071e7 Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Sun, 16 Jan 2011 14:17:36 +0000 Subject: [PATCH 073/252] OneComparatorFieldValueHitQueue redundantly checks array size - it is alredy guaranteed to be of the right one by FVHQ.create() git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059569 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/lucene/search/FieldValueHitQueue.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java b/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java index 10f85620cf6..394d13539ed 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java +++ b/lucene/src/java/org/apache/lucene/search/FieldValueHitQueue.java @@ -57,9 +57,6 @@ public abstract class FieldValueHitQueue extends PriorityQueue Date: Mon, 17 Jan 2011 01:43:37 +0000 Subject: [PATCH 074/252] LUCENE-2847: remove obselete warning git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059719 13f79535-47bb-0310-9956-ffa450edef68 --- .../lucene/analysis/standard/StandardTokenizer.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizer.java b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizer.java index 4a43225a46f..5b2b84a59fa 100644 --- a/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizer.java +++ b/modules/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizer.java @@ -34,14 +34,6 @@ import org.apache.lucene.util.Version; * Unicode Text Segmentation algorithm, as specified in * Unicode Standard Annex #29. *

    - * WARNING: Because JFlex does not support Unicode supplementary - * characters (characters above the Basic Multilingual Plane, which contains - * those up to and including U+FFFF), this scanner will not recognize them - * properly. If you need to be able to process text containing supplementary - * characters, consider using the ICU4J-backed implementation in modules/analysis/icu - * (org.apache.lucene.analysis.icu.segmentation.ICUTokenizer) - * instead of this class, since the ICU4J-backed implementation does not have - * this limitation. *

    Many applications have specific tokenizer needs. If this tokenizer does * not suit your application, please consider copying this source code * directory to your project and maintaining your own grammar-based tokenizer. From 39fad978a0c6acefa98650bcd4eacb688793c115 Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Mon, 17 Jan 2011 04:47:03 +0000 Subject: [PATCH 075/252] LUCENE-2701: port to trunk git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059751 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 7 +++--- .../lucene/index/LogByteSizeMergePolicy.java | 22 +++++++++++++++++++ .../lucene/index/LogDocMergePolicy.java | 3 ++- .../apache/lucene/index/LogMergePolicy.java | 19 +++++++++++----- .../lucene/index/TestSizeBoundedOptimize.java | 2 +- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index d51a1936ea0..602bc020cfc 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -507,9 +507,10 @@ Changes in runtime behavior usage, allowing applications to accidentally open two writers on the same directory. (Mike McCandless) -* LUCENE-2701: maxMergeMB and maxMergeDocs constraints set on LogMergePolicy now - affect optimize() as well (as opposed to only regular merges). This means that - you can run optimize() and too large segments won't be merged. (Shai Erera) +* LUCENE-2701: maxMergeMBForOptimize and maxMergeDocs constraints set on + LogMergePolicy now affect optimize() as well (as opposed to only regular + merges). This means that you can run optimize() and too large segments won't + be merged. (Shai Erera) API Changes diff --git a/lucene/src/java/org/apache/lucene/index/LogByteSizeMergePolicy.java b/lucene/src/java/org/apache/lucene/index/LogByteSizeMergePolicy.java index 520cb4a8f16..7ef2902099f 100644 --- a/lucene/src/java/org/apache/lucene/index/LogByteSizeMergePolicy.java +++ b/lucene/src/java/org/apache/lucene/index/LogByteSizeMergePolicy.java @@ -30,9 +30,14 @@ public class LogByteSizeMergePolicy extends LogMergePolicy { * or larger will never be merged. @see setMaxMergeMB */ public static final double DEFAULT_MAX_MERGE_MB = 2048; + /** Default maximum segment size. A segment of this size + * or larger will never be merged during optimize. @see setMaxMergeMBForOptimize */ + public static final double DEFAULT_MAX_MERGE_MB_FOR_OPTIMIZE = Long.MAX_VALUE; + public LogByteSizeMergePolicy() { minMergeSize = (long) (DEFAULT_MIN_MERGE_MB*1024*1024); maxMergeSize = (long) (DEFAULT_MAX_MERGE_MB*1024*1024); + maxMergeSizeForOptimize = (long) (DEFAULT_MAX_MERGE_MB_FOR_OPTIMIZE*1024*1024); } @Override @@ -63,6 +68,23 @@ public class LogByteSizeMergePolicy extends LogMergePolicy { return ((double) maxMergeSize)/1024/1024; } + /**

    Determines the largest segment (measured by total + * byte size of the segment's files, in MB) that may be + * merged with other segments during optimize. Setting + * it low will leave the index with more than 1 segment, + * even if {@link IndexWriter#optimize()} is called.*/ + public void setMaxMergeMBForOptimize(double mb) { + maxMergeSizeForOptimize = (long) (mb*1024*1024); + } + + /** Returns the largest segment (measured by total byte + * size of the segment's files, in MB) that may be merged + * with other segments during optimize. + * @see #setMaxMergeMBForOptimize */ + public double getMaxMergeMBForOptimize() { + return ((double) maxMergeSizeForOptimize)/1024/1024; + } + /** Sets the minimum size for the lowest level segments. * Any segments below this size are considered to be on * the same level (even if they vary drastically in size) diff --git a/lucene/src/java/org/apache/lucene/index/LogDocMergePolicy.java b/lucene/src/java/org/apache/lucene/index/LogDocMergePolicy.java index a86111c3f46..42ec5136145 100644 --- a/lucene/src/java/org/apache/lucene/index/LogDocMergePolicy.java +++ b/lucene/src/java/org/apache/lucene/index/LogDocMergePolicy.java @@ -31,9 +31,10 @@ public class LogDocMergePolicy extends LogMergePolicy { public LogDocMergePolicy() { minMergeSize = DEFAULT_MIN_MERGE_DOCS; - // maxMergeSize is never used by LogDocMergePolicy; set + // maxMergeSize(ForOptimize) are never used by LogDocMergePolicy; set // it to Long.MAX_VALUE to disable it maxMergeSize = Long.MAX_VALUE; + maxMergeSizeForOptimize = Long.MAX_VALUE; } @Override diff --git a/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java b/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java index 357460c1d9d..f0bbd79ba48 100644 --- a/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java +++ b/lucene/src/java/org/apache/lucene/index/LogMergePolicy.java @@ -63,6 +63,9 @@ public abstract class LogMergePolicy extends MergePolicy { protected long minMergeSize; protected long maxMergeSize; + // Although the core MPs set it explicitly, we must default in case someone + // out there wrote his own LMP ... + protected long maxMergeSizeForOptimize = Long.MAX_VALUE; protected int maxMergeDocs = DEFAULT_MAX_MERGE_DOCS; protected double noCFSRatio = DEFAULT_NO_CFS_RATIO; @@ -240,9 +243,9 @@ public abstract class LogMergePolicy extends MergePolicy { int start = last - 1; while (start >= 0) { SegmentInfo info = infos.info(start); - if (size(info) > maxMergeSize || sizeDocs(info) > maxMergeDocs) { + if (size(info) > maxMergeSizeForOptimize || sizeDocs(info) > maxMergeDocs) { if (verbose()) { - message("optimize: skip segment=" + info + ": size is > maxMergeSize (" + maxMergeSize + ") or sizeDocs is > maxMergeDocs (" + maxMergeDocs + ")"); + message("optimize: skip segment=" + info + ": size is > maxMergeSize (" + maxMergeSizeForOptimize + ") or sizeDocs is > maxMergeDocs (" + maxMergeDocs + ")"); } // need to skip that segment + add a merge for the 'right' segments, // unless there is only 1 which is optimized. @@ -326,9 +329,12 @@ public abstract class LogMergePolicy extends MergePolicy { } /** Returns the merges necessary to optimize the index. - * This merge policy defines "optimized" to mean only one - * segment in the index, where that segment has no - * deletions pending nor separate norms, and it is in + * This merge policy defines "optimized" to mean only the + * requested number of segments is left in the index, and + * respects the {@link #maxMergeSizeForOptimize} setting. + * By default, and assuming {@code maxNumSegments=1}, only + * one segment will be left in the index, where that segment + * has no deletions pending nor separate norms, and it is in * compound file format if the current useCompoundFile * setting is true. This method returns multiple merges * (mergeFactor at a time) so the {@link MergeScheduler} @@ -382,7 +388,7 @@ public abstract class LogMergePolicy extends MergePolicy { boolean anyTooLarge = false; for (int i = 0; i < last; i++) { SegmentInfo info = infos.info(i); - if (size(info) > maxMergeSize || sizeDocs(info) > maxMergeDocs) { + if (size(info) > maxMergeSizeForOptimize || sizeDocs(info) > maxMergeDocs) { anyTooLarge = true; break; } @@ -588,6 +594,7 @@ public abstract class LogMergePolicy extends MergePolicy { sb.append("minMergeSize=").append(minMergeSize).append(", "); sb.append("mergeFactor=").append(mergeFactor).append(", "); sb.append("maxMergeSize=").append(maxMergeSize).append(", "); + sb.append("maxMergeSizeForOptimize=").append(maxMergeSizeForOptimize).append(", "); sb.append("calibrateSizeByDeletes=").append(calibrateSizeByDeletes).append(", "); sb.append("maxMergeDocs=").append(maxMergeDocs).append(", "); sb.append("useCompoundFile=").append(useCompoundFile); diff --git a/lucene/src/test/org/apache/lucene/index/TestSizeBoundedOptimize.java b/lucene/src/test/org/apache/lucene/index/TestSizeBoundedOptimize.java index 75455ac93c8..c1d768276e2 100644 --- a/lucene/src/test/org/apache/lucene/index/TestSizeBoundedOptimize.java +++ b/lucene/src/test/org/apache/lucene/index/TestSizeBoundedOptimize.java @@ -63,7 +63,7 @@ public class TestSizeBoundedOptimize extends LuceneTestCase { conf = newWriterConfig(); LogByteSizeMergePolicy lmp = new LogByteSizeMergePolicy(); - lmp.setMaxMergeMB((min + 1) / (1 << 20)); + lmp.setMaxMergeMBForOptimize((min + 1) / (1 << 20)); conf.setMergePolicy(lmp); writer = new IndexWriter(dir, conf); From 6e66286f9dc2f8af53b34d377be5b28ec27e420a Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 11:01:51 +0000 Subject: [PATCH 076/252] SOLR-2259: warn if you are using a deprecated matchVersion constant git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059866 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/solr/analysis/BaseTokenStreamFactory.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java b/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java index ec9614f1a58..f2977a4d42e 100644 --- a/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java +++ b/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java @@ -30,6 +30,8 @@ import org.apache.lucene.analysis.core.StopFilter; import org.apache.lucene.analysis.util.CharArraySet; import org.apache.lucene.util.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Simple abstract implementation that handles init arg processing, is not really @@ -45,6 +47,8 @@ abstract class BaseTokenStreamFactory { /** the luceneVersion arg */ protected Version luceneMatchVersion = null; + public static final Logger log = LoggerFactory.getLogger(BaseTokenStreamFactory.class); + public void init(Map args) { this.args=args; String matchVersion = args.get(IndexSchema.LUCENE_MATCH_VERSION_PARAM); @@ -64,6 +68,10 @@ abstract class BaseTokenStreamFactory { if (luceneMatchVersion == null) { throw new RuntimeException("Configuration Error: Factory '" + this.getClass().getName() + "' needs a 'luceneMatchVersion' parameter"); + } else if (!luceneMatchVersion.onOrAfter(Version.LUCENE_40)) { + log.warn(getClass().getSimpleName() + " is using deprecated " + luceneMatchVersion + + " emulation. You should at some point declare and reindex to at least 4.0, because " + + "3.x emulation is deprecated and will be removed in 5.0"); } } From 56026e37a230eed3b81e0a9cb361f3b288d1d16d Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 12:34:39 +0000 Subject: [PATCH 077/252] SOLR-1930: remove analysis API deprecations git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059901 13f79535-47bb-0310-9956-ffa450edef68 --- .../resources/solr-extraction/conf/schema.xml | 5 +- .../solr/analysis/BufferedTokenStream.java | 197 ------------------ .../analysis/EnglishPorterFilterFactory.java | 58 ------ .../analysis/PatternTokenizerFactory.java | 65 ------ .../solr/conf/schema-copyfield-test.xml | 5 +- .../solr/conf/schema-required-fields.xml | 5 +- solr/src/test-files/solr/conf/schema.xml | 5 +- solr/src/test-files/solr/conf/schema12.xml | 19 +- .../EnglishPorterFilterFactoryTest.java | 106 ---------- .../SnowballPorterFilterFactoryTest.java | 32 --- .../analysis/TestBufferedTokenStream.java | 92 -------- 11 files changed, 22 insertions(+), 567 deletions(-) delete mode 100644 solr/src/java/org/apache/solr/analysis/BufferedTokenStream.java delete mode 100644 solr/src/java/org/apache/solr/analysis/EnglishPorterFilterFactory.java delete mode 100644 solr/src/test/org/apache/solr/analysis/EnglishPorterFilterFactoryTest.java delete mode 100644 solr/src/test/org/apache/solr/analysis/TestBufferedTokenStream.java diff --git a/solr/contrib/extraction/src/test/resources/solr-extraction/conf/schema.xml b/solr/contrib/extraction/src/test/resources/solr-extraction/conf/schema.xml index 4d53a8f3391..8cc3aaaebe5 100644 --- a/solr/contrib/extraction/src/test/resources/solr-extraction/conf/schema.xml +++ b/solr/contrib/extraction/src/test/resources/solr-extraction/conf/schema.xml @@ -210,13 +210,14 @@ - + - + + diff --git a/solr/src/java/org/apache/solr/analysis/BufferedTokenStream.java b/solr/src/java/org/apache/solr/analysis/BufferedTokenStream.java deleted file mode 100644 index 0633aa92cb3..00000000000 --- a/solr/src/java/org/apache/solr/analysis/BufferedTokenStream.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * 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. - */ - -package org.apache.solr.analysis; - -import org.apache.lucene.analysis.Token; -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.TokenFilter; -import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; -import org.apache.lucene.analysis.tokenattributes.FlagsAttribute; -import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; -import org.apache.lucene.analysis.tokenattributes.PayloadAttribute; -import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; -import org.apache.lucene.analysis.tokenattributes.TypeAttribute; -import org.apache.lucene.util.AttributeSource; // javadoc @link - -import java.io.IOException; -import java.util.LinkedList; - -/** - * Handles input and output buffering of TokenStream - * - *

    - * // Example of a class implementing the rule "A" "B" => "Q" "B"
    - * class MyTokenStream extends BufferedTokenStream {
    - *   public MyTokenStream(TokenStream input) {super(input);}
    - *   protected Token process(Token t) throws IOException {
    - *     if ("A".equals(t.termText())) {
    - *       Token t2 = read();
    - *       if (t2!=null && "B".equals(t2.termText())) t.setTermText("Q");
    - *       if (t2!=null) pushBack(t2);
    - *     }
    - *     return t;
    - *   }
    - * }
    - *
    - * // Example of a class implementing "A" "B" => "A" "A" "B"
    - * class MyTokenStream extends BufferedTokenStream {
    - *   public MyTokenStream(TokenStream input) {super(input);}
    - *   protected Token process(Token t) throws IOException {
    - *     if ("A".equals(t.termText()) && "B".equals(peek(1).termText()))
    - *       write((Token)t.clone());
    - *     return t;
    - *   }
    - * }
    - * 
    - * - * NOTE: BufferedTokenStream does not clone() any Tokens. This is instead the - * responsibility of the implementing subclass. In the "A" "B" => "A" "A" "B" - * example above, the subclass must clone the additional "A" it creates. - * - * @deprecated This class does not support custom attributes. Extend TokenFilter instead, - * using {@link AttributeSource#captureState()} and {@link AttributeSource#restoreState(State)} - * which support all attributes. - */ -@Deprecated -public abstract class BufferedTokenStream extends TokenFilter { - // in the future, might be faster if we implemented as an array based CircularQueue - private final LinkedList inQueue = new LinkedList(); - private final LinkedList outQueue = new LinkedList(); - - private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); - private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class); - private final TypeAttribute typeAtt = addAttribute(TypeAttribute.class); - private final FlagsAttribute flagsAtt = addAttribute(FlagsAttribute.class); - private final PayloadAttribute payloadAtt = addAttribute(PayloadAttribute.class); - private final PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class); - - public BufferedTokenStream(TokenStream input) { - super(input); - } - - /** - * Process a token. Subclasses may read more tokens from the input stream, - * write more tokens to the output stream, or simply return the next token - * to be output. Subclasses may return null if the token is to be dropped. - * If a subclass writes tokens to the output stream and returns a - * non-null Token, the returned Token is considered to be at the head of - * the token output stream. - */ - protected abstract Token process(Token t) throws IOException; - - public final boolean incrementToken() throws IOException { - while (true) { - if (!outQueue.isEmpty()) return writeToken(outQueue.removeFirst()); - Token t = read(); - if (null == t) return false; - Token out = process(t); - if (null != out) return writeToken(out); - // loop back to top in case process() put something on the output queue - } - } - - /** - * Read a token from the buffered input stream. - * @return null at EOS - */ - protected Token read() throws IOException { - if (inQueue.isEmpty()) { - Token t = readToken(); - return t; - } - return inQueue.removeFirst(); - } - - /** - * Push a token back into the buffered input stream, such that it will - * be returned by a future call to read() - */ - protected void pushBack(Token t) { - inQueue.addFirst(t); - } - - /** - * Peek n tokens ahead in the buffered input stream, without modifying - * the stream. - * @param n Number of tokens into the input stream to peek, 1 based ... - * 0 is invalid - * @return a Token which exists in the input stream, any modifications - * made to this Token will be "real" if/when the Token is - * read() from the stream. - */ - protected Token peek(int n) throws IOException { - int fillCount = n-inQueue.size(); - for (int i=0; i < fillCount; i++) { - Token t = readToken(); - if (null==t) return null; - inQueue.addLast(t); - } - return inQueue.get(n-1); - } - - /** old api emulation for back compat */ - private Token readToken() throws IOException { - if (!input.incrementToken()) { - return null; - } else { - Token token = new Token(); - token.copyBuffer(termAtt.buffer(), 0, termAtt.length()); - token.setOffset(offsetAtt.startOffset(), offsetAtt.endOffset()); - token.setType(typeAtt.type()); - token.setFlags(flagsAtt.getFlags()); - token.setPositionIncrement(posIncAtt.getPositionIncrement()); - token.setPayload(payloadAtt.getPayload()); - return token; - } - } - - /** old api emulation for back compat */ - private boolean writeToken(Token token) throws IOException { - clearAttributes(); - termAtt.copyBuffer(token.buffer(), 0, token.length()); - offsetAtt.setOffset(token.startOffset(), token.endOffset()); - typeAtt.setType(token.type()); - flagsAtt.setFlags(token.getFlags()); - posIncAtt.setPositionIncrement(token.getPositionIncrement()); - payloadAtt.setPayload(token.getPayload()); - return true; - } - - /** - * Write a token to the buffered output stream - */ - protected void write(Token t) { - outQueue.addLast(t); - } - - /** - * Provides direct Iterator access to the buffered output stream. - * Modifying any token in this Iterator will affect the resulting stream. - */ - protected Iterable output() { - return outQueue; - } - - @Override - public void reset() throws IOException { - super.reset(); - inQueue.clear(); - outQueue.clear(); - } - -} diff --git a/solr/src/java/org/apache/solr/analysis/EnglishPorterFilterFactory.java b/solr/src/java/org/apache/solr/analysis/EnglishPorterFilterFactory.java deleted file mode 100644 index f9e1ff7bcc8..00000000000 --- a/solr/src/java/org/apache/solr/analysis/EnglishPorterFilterFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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. - */ - -package org.apache.solr.analysis; - -import org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter; -import org.apache.lucene.analysis.TokenFilter; -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.snowball.SnowballFilter; -import org.apache.lucene.analysis.util.CharArraySet; -import org.apache.solr.common.ResourceLoader; -import org.apache.solr.util.plugin.ResourceLoaderAware; - -import java.io.IOException; - -/** - * @version $Id$ - * - * @deprecated Use SnowballPorterFilterFactory with language="English" instead - */ -@Deprecated -public class EnglishPorterFilterFactory extends BaseTokenFilterFactory implements ResourceLoaderAware { - public static final String PROTECTED_TOKENS = "protected"; - - public void inform(ResourceLoader loader) { - String wordFiles = args.get(PROTECTED_TOKENS); - if (wordFiles != null) { - try { - protectedWords = getWordSet(loader, wordFiles, false); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - private CharArraySet protectedWords = null; - - public TokenFilter create(TokenStream input) { - if (protectedWords != null) - input = new KeywordMarkerFilter(input, protectedWords); - return new SnowballFilter(input, new org.tartarus.snowball.ext.EnglishStemmer()); - } - -} diff --git a/solr/src/java/org/apache/solr/analysis/PatternTokenizerFactory.java b/solr/src/java/org/apache/solr/analysis/PatternTokenizerFactory.java index c87a8b81d49..d83c97ee3b2 100644 --- a/solr/src/java/org/apache/solr/analysis/PatternTokenizerFactory.java +++ b/solr/src/java/org/apache/solr/analysis/PatternTokenizerFactory.java @@ -19,13 +19,9 @@ package org.apache.solr.analysis; import java.io.IOException; import java.io.Reader; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.lucene.analysis.Token; import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.pattern.PatternTokenizer; import org.apache.solr.common.SolrException; @@ -104,65 +100,4 @@ public class PatternTokenizerFactory extends BaseTokenizerFactory throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, ex ); } } - - /** - * This behaves just like String.split( ), but returns a list of Tokens - * rather then an array of strings - * NOTE: This method is not used in 1.4. - * @deprecated - */ - @Deprecated - public static List split( Matcher matcher, String input ) - { - int index = 0; - int lastNonEmptySize = Integer.MAX_VALUE; - ArrayList matchList = new ArrayList(); - - // Add segments before each match found - while(matcher.find()) { - String match = input.subSequence(index, matcher.start()).toString(); - matchList.add( new Token( match, index, matcher.start()) ); - index = matcher.end(); - if( match.length() > 0 ) { - lastNonEmptySize = matchList.size(); - } - } - - // If no match is found, return the full string - if (index == 0) { - matchList.add( new Token( input, 0, input.length()) ); - } - else { - String match = input.subSequence(index, input.length()).toString(); - matchList.add( new Token( match, index, input.length()) ); - if( match.length() > 0 ) { - lastNonEmptySize = matchList.size(); - } - } - - // Don't use trailing empty strings. This behavior matches String.split(); - if( lastNonEmptySize < matchList.size() ) { - return matchList.subList( 0, lastNonEmptySize ); - } - return matchList; - } - - /** - * Create tokens from the matches in a matcher - * NOTE: This method is not used in 1.4. - * @deprecated - */ - @Deprecated - public static List group( Matcher matcher, String input, int group ) - { - ArrayList matchList = new ArrayList(); - while(matcher.find()) { - Token t = new Token( - matcher.group(group), - matcher.start(group), - matcher.end(group) ); - matchList.add( t ); - } - return matchList; - } } diff --git a/solr/src/test-files/solr/conf/schema-copyfield-test.xml b/solr/src/test-files/solr/conf/schema-copyfield-test.xml index 2332e8c5ac4..d294af661c2 100644 --- a/solr/src/test-files/solr/conf/schema-copyfield-test.xml +++ b/solr/src/test-files/solr/conf/schema-copyfield-test.xml @@ -202,13 +202,14 @@ - + - + + diff --git a/solr/src/test-files/solr/conf/schema-required-fields.xml b/solr/src/test-files/solr/conf/schema-required-fields.xml index 1535c8a72b9..f17948476f7 100644 --- a/solr/src/test-files/solr/conf/schema-required-fields.xml +++ b/solr/src/test-files/solr/conf/schema-required-fields.xml @@ -193,13 +193,14 @@ - + - + + diff --git a/solr/src/test-files/solr/conf/schema.xml b/solr/src/test-files/solr/conf/schema.xml index cf10b9e71ab..05fa45e7196 100644 --- a/solr/src/test-files/solr/conf/schema.xml +++ b/solr/src/test-files/solr/conf/schema.xml @@ -236,13 +236,14 @@ - + - + + diff --git a/solr/src/test-files/solr/conf/schema12.xml b/solr/src/test-files/solr/conf/schema12.xml index 2d89dcc00c8..eadcfdc4a12 100755 --- a/solr/src/test-files/solr/conf/schema12.xml +++ b/solr/src/test-files/solr/conf/schema12.xml @@ -252,13 +252,14 @@ - + - + + @@ -286,14 +287,14 @@ - + - + @@ -303,14 +304,14 @@ - + - + @@ -375,7 +376,7 @@ - + @@ -384,7 +385,7 @@ - + @@ -397,7 +398,7 @@ - + diff --git a/solr/src/test/org/apache/solr/analysis/EnglishPorterFilterFactoryTest.java b/solr/src/test/org/apache/solr/analysis/EnglishPorterFilterFactoryTest.java deleted file mode 100644 index a0357ac6d98..00000000000 --- a/solr/src/test/org/apache/solr/analysis/EnglishPorterFilterFactoryTest.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.apache.solr.analysis; - -/** - * Copyright 2004 The Apache Software Foundation - * - * Licensed 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 org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.Tokenizer; -import org.apache.lucene.analysis.core.WhitespaceTokenizer; -import org.apache.solr.common.ResourceLoader; -import org.apache.solr.common.util.StrUtils; -import org.tartarus.snowball.ext.EnglishStemmer; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.ArrayList; -import java.util.Collections; - -public class EnglishPorterFilterFactoryTest extends BaseTokenTestCase { - - public void test() throws IOException { - EnglishStemmer stemmer = new EnglishStemmer(); - String[] test = {"The", "fledgling", "banks", "were", "counting", "on", "a", "big", "boom", "in", "banking"}; - String[] gold = new String[test.length]; - for (int i = 0; i < test.length; i++) { - stemmer.setCurrent(test[i]); - stemmer.stem(); - gold[i] = stemmer.getCurrent(); - } - - EnglishPorterFilterFactory factory = new EnglishPorterFilterFactory(); - Map args = new HashMap(DEFAULT_VERSION_PARAM); - - factory.init(args); - factory.inform(new LinesMockSolrResourceLoader(new ArrayList())); - Tokenizer tokenizer = new WhitespaceTokenizer(DEFAULT_VERSION, - new StringReader(StrUtils.join(Arrays.asList(test), ' '))); - TokenStream stream = factory.create(tokenizer); - assertTokenStreamContents(stream, gold); - } - - public void testProtected() throws Exception { - EnglishStemmer stemmer = new EnglishStemmer(); - String[] test = {"The", "fledgling", "banks", "were", "counting", "on", "a", "big", "boom", "in", "banking"}; - String[] gold = new String[test.length]; - for (int i = 0; i < test.length; i++) { - if (test[i].equals("fledgling") == false && test[i].equals("banks") == false) { - stemmer.setCurrent(test[i]); - stemmer.stem(); - gold[i] = stemmer.getCurrent(); - } else { - gold[i] = test[i]; - } - } - - EnglishPorterFilterFactory factory = new EnglishPorterFilterFactory(); - Map args = new HashMap(DEFAULT_VERSION_PARAM); - args.put(EnglishPorterFilterFactory.PROTECTED_TOKENS, "who-cares.txt"); - factory.init(args); - List lines = new ArrayList(); - Collections.addAll(lines, "banks", "fledgling"); - factory.inform(new LinesMockSolrResourceLoader(lines)); - Tokenizer tokenizer = new WhitespaceTokenizer(DEFAULT_VERSION, - new StringReader(StrUtils.join(Arrays.asList(test), ' '))); - TokenStream stream = factory.create(tokenizer); - assertTokenStreamContents(stream, gold); - } - - class LinesMockSolrResourceLoader implements ResourceLoader { - List lines; - - LinesMockSolrResourceLoader(List lines) { - this.lines = lines; - } - - public List getLines(String resource) throws IOException { - return lines; - } - - public Object newInstance(String cname, String... subpackages) { - return null; - } - - public InputStream openResource(String resource) throws IOException { - return null; - } - } -} - diff --git a/solr/src/test/org/apache/solr/analysis/SnowballPorterFilterFactoryTest.java b/solr/src/test/org/apache/solr/analysis/SnowballPorterFilterFactoryTest.java index 5475d3ed857..3d364f7eba1 100644 --- a/solr/src/test/org/apache/solr/analysis/SnowballPorterFilterFactoryTest.java +++ b/solr/src/test/org/apache/solr/analysis/SnowballPorterFilterFactoryTest.java @@ -33,7 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ArrayList; -import java.util.Collections; public class SnowballPorterFilterFactoryTest extends BaseTokenTestCase { @@ -59,37 +58,6 @@ public class SnowballPorterFilterFactoryTest extends BaseTokenTestCase { assertTokenStreamContents(stream, gold); } - /** - * Tests the protected words mechanism of EnglishPorterFilterFactory - */ - @Deprecated - public void testProtectedOld() throws Exception { - EnglishStemmer stemmer = new EnglishStemmer(); - String[] test = {"The", "fledgling", "banks", "were", "counting", "on", "a", "big", "boom", "in", "banking"}; - String[] gold = new String[test.length]; - for (int i = 0; i < test.length; i++) { - if (test[i].equals("fledgling") == false && test[i].equals("banks") == false) { - stemmer.setCurrent(test[i]); - stemmer.stem(); - gold[i] = stemmer.getCurrent(); - } else { - gold[i] = test[i]; - } - } - - EnglishPorterFilterFactory factory = new EnglishPorterFilterFactory(); - Map args = new HashMap(DEFAULT_VERSION_PARAM); - args.put(SnowballPorterFilterFactory.PROTECTED_TOKENS, "who-cares.txt"); - factory.init(args); - List lines = new ArrayList(); - Collections.addAll(lines, "banks", "fledgling"); - factory.inform(new LinesMockSolrResourceLoader(lines)); - Tokenizer tokenizer = new WhitespaceTokenizer(DEFAULT_VERSION, - new StringReader(StrUtils.join(Arrays.asList(test), ' '))); - TokenStream stream = factory.create(tokenizer); - assertTokenStreamContents(stream, gold); - } - class LinesMockSolrResourceLoader implements ResourceLoader { List lines; diff --git a/solr/src/test/org/apache/solr/analysis/TestBufferedTokenStream.java b/solr/src/test/org/apache/solr/analysis/TestBufferedTokenStream.java deleted file mode 100644 index 6c4baa44e86..00000000000 --- a/solr/src/test/org/apache/solr/analysis/TestBufferedTokenStream.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * 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. - */ - -package org.apache.solr.analysis; - -import org.apache.lucene.analysis.Token; -import org.apache.lucene.analysis.TokenStream; -import org.apache.lucene.analysis.Tokenizer; -import org.apache.lucene.analysis.core.WhitespaceTokenizer; -import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; - -import java.io.IOException; -import java.io.StringReader; - -/** - * Test that BufferedTokenStream behaves as advertised in subclasses. - */ -public class TestBufferedTokenStream extends BaseTokenTestCase { - - /** Example of a class implementing the rule "A" "B" => "Q" "B" */ - public static class AB_Q_Stream extends BufferedTokenStream { - public AB_Q_Stream(TokenStream input) {super(input);} - protected Token process(Token t) throws IOException { - if ("A".equals(new String(t.buffer(), 0, t.length()))) { - Token t2 = read(); - if (t2!=null && "B".equals(new String(t2.buffer(), 0, t2.length()))) t.setEmpty().append("Q"); - if (t2!=null) pushBack(t2); - } - return t; - } - } - - /** Example of a class implementing "A" "B" => "A" "A" "B" */ - public static class AB_AAB_Stream extends BufferedTokenStream { - public AB_AAB_Stream(TokenStream input) {super(input);} - protected Token process(Token t) throws IOException { - if ("A".equals(new String(t.buffer(), 0, t.length())) && - "B".equals(new String(peek(1).buffer(), 0, peek(1).length()))) - write((Token)t.clone()); - return t; - } - } - - public void testABQ() throws Exception { - final String input = "How now A B brown A cow B like A B thing?"; - final String expected = "How now Q B brown A cow B like Q B thing?"; - TokenStream ts = new AB_Q_Stream - (new WhitespaceTokenizer(DEFAULT_VERSION, new StringReader(input))); - assertTokenStreamContents(ts, expected.split("\\s")); - } - - public void testABAAB() throws Exception { - final String input = "How now A B brown A cow B like A B thing?"; - final String expected = "How now A A B brown A cow B like A A B thing?"; - TokenStream ts = new AB_AAB_Stream - (new WhitespaceTokenizer(DEFAULT_VERSION, new StringReader(input))); - assertTokenStreamContents(ts, expected.split("\\s")); - } - - public void testReset() throws Exception { - final String input = "How now A B brown A cow B like A B thing?"; - Tokenizer tokenizer = new WhitespaceTokenizer(DEFAULT_VERSION, new StringReader(input)); - TokenStream ts = new AB_AAB_Stream(tokenizer); - CharTermAttribute term = ts.addAttribute(CharTermAttribute.class); - assertTrue(ts.incrementToken()); - assertEquals("How", term.toString()); - assertTrue(ts.incrementToken()); - assertEquals("now", term.toString()); - assertTrue(ts.incrementToken()); - assertEquals("A", term.toString()); - // reset back to input, - // if reset() does not work correctly then previous buffered tokens will remain - tokenizer.reset(new StringReader(input)); - ts.reset(); - assertTrue(ts.incrementToken()); - assertEquals("How", term.toString()); - } -} From 9906198ff3d65f8c9b7e99462aab19feb5334790 Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Mon, 17 Jan 2011 12:49:28 +0000 Subject: [PATCH 078/252] LUCENE-2755: documentation updates, formatting and tiny mods to CMS (trunk) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059905 13f79535-47bb-0310-9956-ffa450edef68 --- .../index/ConcurrentMergeScheduler.java | 66 +++++++++++-------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java b/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java index b33aa6c1098..6f394532ac8 100644 --- a/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java +++ b/lucene/src/java/org/apache/lucene/index/ConcurrentMergeScheduler.java @@ -142,8 +142,12 @@ public class ConcurrentMergeScheduler extends MergeScheduler { } }; - /** Called whenever the running merges have changed, to - * pause & unpause threads. */ + /** + * Called whenever the running merges have changed, to pause & unpause + * threads. This method sorts the merge threads by their merge size in + * descending order and then pauses/unpauses threads from first to lsat -- + * that way, smaller merges are guaranteed to run before larger ones. + */ protected synchronized void updateMergeThreads() { // Only look at threads that are alive & not in the @@ -164,6 +168,7 @@ public class ConcurrentMergeScheduler extends MergeScheduler { threadIdx++; } + // Sort the merge threads in descending order. CollectionUtil.mergeSort(activeMerges, compareByMergeDocCount); int pri = mergeThreadPriority; @@ -175,12 +180,8 @@ public class ConcurrentMergeScheduler extends MergeScheduler { continue; } - final boolean doPause; - if (threadIdx < activeMergeCount-maxThreadCount) { - doPause = true; - } else { - doPause = false; - } + // pause the thread if maxThreadCount is smaller than the number of merge threads. + final boolean doPause = threadIdx < activeMergeCount - maxThreadCount; if (verbose()) { if (doPause != merge.getPause()) { @@ -205,13 +206,26 @@ public class ConcurrentMergeScheduler extends MergeScheduler { } } - private boolean verbose() { + /** + * Returns true if verbosing is enabled. This method is usually used in + * conjunction with {@link #message(String)}, like that: + * + *
    +   * if (verbose()) {
    +   *   message("your message");
    +   * }
    +   * 
    + */ + protected boolean verbose() { return writer != null && writer.verbose(); } - private void message(String message) { - if (verbose()) - writer.message("CMS: " + message); + /** + * Outputs the given message - this method assumes {@link #verbose()} was + * called and returned true. + */ + protected void message(String message) { + writer.message("CMS: " + message); } private synchronized void initMergeThreadPriority() { @@ -231,10 +245,10 @@ public class ConcurrentMergeScheduler extends MergeScheduler { /** Wait for any running merge threads to finish */ public void sync() { - while(true) { + while (true) { MergeThread toSync = null; - synchronized(this) { - for(MergeThread t : mergeThreads) { + synchronized (this) { + for (MergeThread t : mergeThreads) { if (t.isAlive()) { toSync = t; break; @@ -253,21 +267,20 @@ public class ConcurrentMergeScheduler extends MergeScheduler { } } - private synchronized int mergeThreadCount() { + /** + * Returns the number of merge threads that are alive. Note that this number + * is ≤ {@link #mergeThreads} size. + */ + protected synchronized int mergeThreadCount() { int count = 0; - final int numThreads = mergeThreads.size(); - for(int i=0;i Date: Mon, 17 Jan 2011 13:20:54 +0000 Subject: [PATCH 079/252] synchronize CHANGES.txt git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059914 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/CHANGES.txt | 252 ++++++++++++++++++++++++++------------------- 1 file changed, 147 insertions(+), 105 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 602bc020cfc..e0fd2c2b208 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -89,19 +89,9 @@ Changes in backwards compatibility policy * LUCENE-2484: Removed deprecated TermAttribute. Use CharTermAttribute and TermToBytesRefAttribute instead. (Uwe Schindler) -* LUCENE-2602: The default (LogByteSizeMergePolicy) merge policy now - takes deletions into account by default. You can disable this by - calling setCalibrateSizeByDeletes(false) on the merge policy. (Mike - McCandless) - * LUCENE-2600: Remove IndexReader.isDeleted in favor of IndexReader.getDeletedDocs(). (Mike McCandless) -* LUCENE-2529, LUCENE-2668: Position increment gap and offset gap of empty - values in multi-valued field has been changed for some cases in index. - If you index empty fields and uses positions/offsets information on that - fields, reindex is recommended. (David Smiley, Koji Sekiguchi) - * LUCENE-2667: FuzzyQuery's defaults have changed for more performant behavior: the minimum similarity is 2 edit distances from the word, and the priority queue size is 50. To support this, FuzzyQuery now allows @@ -140,21 +130,6 @@ Changes in backwards compatibility policy Changes in Runtime Behavior -* LUCENE-2650, LUCENE-2825: The behavior of FSDirectory.open has changed. On 64-bit - Windows and Solaris systems that support unmapping, FSDirectory.open returns - MMapDirectory. Additionally the behavior of MMapDirectory has been - changed to enable unmapping by default if supported by the JRE. - (Mike McCandless, Uwe Schindler, Robert Muir) - -* LUCENE-2790: LogMergePolicy.useCompoundFile's logic now factors in noCFSRatio - to determine whether the passed in segment should be compound. - (Shai Erera, Earwin Burrfoot) - -* LUCENE-2805: IndexWriter now increments the index version on every change to - the index instead of for every commit. Committing or closing the IndexWriter - without any changes to the index will not cause any index version increment. - (Simon Willnauer, Mike McCandless) - * LUCENE-2846: omitNorms now behaves like omitTermFrequencyAndPositions, if you omitNorms(true) for field "a" for 1000 documents, but then add a document with omitNorms(false) for field "a", all documents for field "a" will have no norms. @@ -181,17 +156,6 @@ API Changes deleted docs (getDeletedDocs), providing a new Bits interface to directly query by doc ID. -* LUCENE-2402: IndexWriter.deleteUnusedFiles now deletes unreferenced commit - points too. If you use an IndexDeletionPolicy which holds onto index commits - (such as SnapshotDeletionPolicy), you can call this method to remove those - commit points when they are not needed anymore (instead of waiting for the - next commit). (Shai Erera) - -* LUCENE-2674: A new idfExplain method was added to Similarity, that - accepts an incoming docFreq. If you subclass Similarity, make sure - you also override this method on upgrade. (Robert Muir, Mike - McCandless) - * LUCENE-2691: IndexWriter.getReader() has been made package local and is now exposed via open and reopen methods on IndexReader. The semantics of the call is the same as it was prior to the API change. @@ -199,9 +163,6 @@ API Changes * LUCENE-2566: QueryParser: Unary operators +,-,! will not be treated as operators if they are followed by whitespace. (yonik) - -* LUCENE-2778: RAMDirectory now exposes newRAMFile() which allows to override - and return a different RAMFile implementation. (Shai Erera) * LUCENE-2831: Weight#scorer, Weight#explain, Filter#getDocIdSet, Collector#setNextReader & FieldComparator#setNextReader now expect an @@ -253,10 +214,6 @@ New features data and payloads in 5 separate files instead of the 2 used by standard codec), and int block (really a "base" for using block-based compressors like PForDelta for storing postings data). - -* LUCENE-2385: Moved NoDeletionPolicy from benchmark to core. NoDeletionPolicy - can be used to prevent commits from ever getting deleted from the index. - (Shai Erera) * LUCENE-1458, LUCENE-2111: The in-memory terms index used by standard codec is more RAM efficient: terms data is stored as block byte @@ -271,16 +228,6 @@ New features applications that have many unique terms, since it reduces how often a new segment must be flushed given a fixed RAM buffer size. -* LUCENE-1585: IndexWriter now accepts a PayloadProcessorProvider which can - return a DirPayloadProcessor for a given Directory, which returns a - PayloadProcessor for a given Term. The PayloadProcessor will be used to - process the payloads of the segments as they are merged (e.g. if one wants to - rewrite payloads of external indexes as they are added, or of local ones). - (Shai Erera, Michael Busch, Mike McCandless) - -* LUCENE-2440: Add support for custom ExecutorService in - ParallelMultiSearcher (Edward Drapkin via Mike McCandless) - * LUCENE-2489: Added PerFieldCodecWrapper (in oal.index.codecs) which lets you set the Codec per field (Mike McCandless) @@ -291,17 +238,6 @@ New features SegmentInfosReader to allow customization of SegmentInfos data. (Andrzej Bialecki) -* LUCENE-2559: Added SegmentReader.reopen methods (John Wang via Mike - McCandless) - -* LUCENE-2590: Added Scorer.visitSubScorers, and Scorer.freq. Along - with a custom Collector these experimental methods make it possible - to gather the hit-count per sub-clause and per document while a - search is running. (Simon Willnauer, Mike McCandless) - -* LUCENE-2636: Added MultiCollector which allows running the search with several - Collectors. (Shai Erera) - * LUCENE-2504: FieldComparator.setNextReader now returns a FieldComparator instance. You can "return this", to just reuse the same instance, or you can return a comparator optimized to the new @@ -364,17 +300,6 @@ New features Optimizations -* LUCENE-2410: ~20% speedup on exact (slop=0) PhraseQuery matching. - (Mike McCandless) - -* LUCENE-2531: Fix issue when sorting by a String field that was - causing too many fallbacks to compare-by-value (instead of by-ord). - (Mike McCandless) - -* LUCENE-2574: IndexInput exposes copyBytes(IndexOutput, long) to allow for - efficient copying by sub-classes. Optimized copy is implemented for RAM and FS - streams. (Shai Erera) - * LUCENE-2588: Don't store unnecessary suffixes when writing the terms index, saving RAM in IndexReader; change default terms index interval from 128 to 32, because the terms index now requires much @@ -389,11 +314,6 @@ Optimizations MultiTermQuery now stores TermState per leaf reader during rewrite to re- seek the term dictionary in TermQuery / TermWeight. (Simon Willnauer, Mike McCandless, Robert Muir) - -Documentation - -* LUCENE-2579: Fix oal.search's package.html description of abstract - methods. (Santiago M. Mola via Mike McCandless) Bug fixes @@ -404,14 +324,6 @@ Bug fixes with more document deletions is requested before a reader with fewer deletions, provided they share some segments. (yonik) -* LUCENE-2802: NRT DirectoryReader returned incorrect values from - getVersion, isOptimized, getCommitUserData, getIndexCommit and isCurrent due - to a mutable reference to the IndexWriters SegmentInfos. - (Simon Willnauer, Earwin Burrfoot) - -* LUCENE-2860: Fixed SegmentInfo.sizeInBytes to factor includeDocStores when it - decides whether to return the cached computed size or not. (Shai Erera) - ======================= Lucene 3.x (not yet released) ======================= Changes in backwards compatibility policy @@ -476,10 +388,33 @@ Changes in backwards compatibility policy * LUCENE-2733: Removed public constructors of utility classes with only static methods to prevent instantiation. (Uwe Schindler) -* LUCENE-2753: IndexReader and DirectoryReader .listCommits() now return a List - instead of a Collection, guaranteeing the commits are sorted from oldest to - latest. (Shai Erera) +* LUCENE-2602: The default (LogByteSizeMergePolicy) merge policy now + takes deletions into account by default. You can disable this by + calling setCalibrateSizeByDeletes(false) on the merge policy. (Mike + McCandless) + +* LUCENE-2529, LUCENE-2668: Position increment gap and offset gap of empty + values in multi-valued field has been changed for some cases in index. + If you index empty fields and uses positions/offsets information on that + fields, reindex is recommended. (David Smiley, Koji Sekiguchi) +* LUCENE-2804: Directory.setLockFactory new declares throwing an IOException. + (Shai Erera, Robert Muir) + +* LUCENE-2837: Added deprecations noting that in 4.0, Searcher and + Searchable are collapsed into IndexSearcher; contrib/remote and + MultiSearcher have been removed. (Mike McCandless) + +* LUCENE-2854: Deprecated SimilarityDelegator and + Similarity.lengthNorm; the latter is now final, forcing any custom + Similarity impls to cutover to the more general computeNorm (Robert + Muir, Mike McCandless) + +* LUCENE-2674: A new idfExplain method was added to Similarity, that + accepts an incoming docFreq. If you subclass Similarity, make sure + you also override this method on upgrade. (Robert Muir, Mike + McCandless) + Changes in runtime behavior * LUCENE-1923: Made IndexReader.toString() produce something @@ -495,7 +430,7 @@ Changes in runtime behavior invokes a merge on the incoming and target segments, but instead copies the segments to the target index. You can call maybeMerge or optimize after this method completes, if you need to. - + In addition, Directory.copyTo* were removed in favor of copy which takes the target Directory, source and target files as arguments, and copies the source file to the target Directory under the target file name. (Shai Erera) @@ -512,6 +447,33 @@ Changes in runtime behavior merges). This means that you can run optimize() and too large segments won't be merged. (Shai Erera) +* LUCENE-2753: IndexReader and DirectoryReader .listCommits() now return a List, + guaranteeing the commits are sorted from oldest to latest. (Shai Erera) + +* LUCENE-2785: TopScoreDocCollector, TopFieldCollector and + the IndexSearcher search methods that take an int nDocs will now + throw IllegalArgumentException if nDocs is 0. Instead, you should + use the newly added TotalHitCountCollector. (Mike McCandless) + +* LUCENE-2790: LogMergePolicy.useCompoundFile's logic now factors in noCFSRatio + to determine whether the passed in segment should be compound. + (Shai Erera, Earwin Burrfoot) + +* LUCENE-2805: IndexWriter now increments the index version on every change to + the index instead of for every commit. Committing or closing the IndexWriter + without any changes to the index will not cause any index version increment. + (Simon Willnauer, Mike McCandless) + +* LUCENE-2650, LUCENE-2825: The behavior of FSDirectory.open has changed. On 64-bit + Windows and Solaris systems that support unmapping, FSDirectory.open returns + MMapDirectory. Additionally the behavior of MMapDirectory has been + changed to enable unmapping by default if supported by the JRE. + (Mike McCandless, Uwe Schindler, Robert Muir) + +* LUCENE-2829: Improve the performance of "primary key" lookup use + case (running a TermQuery that matches one document) on a + multi-segment index. (Robert Muir, Mike McCandless) + API Changes * LUCENE-2076: Rename FSDirectory.getFile -> getDirectory. (George @@ -522,7 +484,7 @@ API Changes custom Similarity can alter how norms are encoded, though they must still be encoded as a single byte (Johan Kindgren via Mike McCandless) - + * LUCENE-2103: NoLockFactory should have a private constructor; until Lucene 4.0 the default one will be deprecated. (Shai Erera via Uwe Schindler) @@ -594,17 +556,42 @@ API Changes (such as SnapshotDeletionPolicy), you can call this method to remove those commit points when they are not needed anymore (instead of waiting for the next commit). (Shai Erera) - -* LUCENE-2455: IndexWriter.addIndexesNoOptimize was renamed to addIndexes. - IndexFileNames.segmentFileName now takes another parameter to accommodate - custom file names. You should use this method to name all your files. - (Shai Erera) * LUCENE-2481: SnapshotDeletionPolicy.snapshot() and release() were replaced with equivalent ones that take a String (id) as argument. You can pass whatever ID you want, as long as you use the same one when calling both. (Shai Erera) +* LUCENE-2356: Add IndexWriterConfig.set/getReaderTermIndexDivisor, to + set what IndexWriter passes for termsIndexDivisor to the readers it + opens internally when apply deletions or creating a near-real-time + reader. (Earwin Burrfoot via Mike McCandless) + +* LUCENE-2167,LUCENE-2699,LUCENE-2763,LUCENE-2847: StandardTokenizer/Analyzer + in common/standard/ now implement the Word Break rules from the Unicode 6.0.0 + Text Segmentation algorithm (UAX#29), covering the full range of Unicode code + points, including values from U+FFFF to U+10FFFF + + ClassicTokenizer/Analyzer retains the old (pre-Lucene 3.1) StandardTokenizer/ + Analyzer implementation and behavior. Only the Unicode Basic Multilingual + Plane (code points from U+0000 to U+FFFF) is covered. + + UAX29URLEmailTokenizer tokenizes URLs and E-mail addresses according to the + relevant RFCs, in addition to implementing the UAX#29 Word Break rules. + (Steven Rowe, Robert Muir, Uwe Schindler) + +* LUCENE-2778: RAMDirectory now exposes newRAMFile() which allows to override + and return a different RAMFile implementation. (Shai Erera) + +* LUCENE-2785: Added TotalHitCountCollector whose sole purpose is to + count the number of hits matching the query. (Mike McCandless) + +* LUCENE-2846: Deprecated IndexReader.setNorm(int, String, float). This method + is only syntactic sugar for setNorm(int, String, byte), but using the global + Similarity.getDefault().encodeNormValue(). Use the byte-based method instead + to ensure that the norm is encoded with your Similarity. + (Robert Muir, Mike McCandless) + Bug fixes * LUCENE-2249: ParallelMultiSearcher should shut down thread pool on @@ -625,10 +612,6 @@ Bug fixes a prior (corrupt) index missing its segments_N file. (Mike McCandless) -* LUCENE-2534: fix over-sharing bug in - MultiTermsEnum.docs/AndPositionsEnum. (Robert Muir, Mike - McCandless) - * LUCENE-2458: QueryParser no longer automatically forms phrase queries, assuming whitespace tokenization. Previously all CJK queries, for example, would be turned into phrase queries. The old behavior is preserved with @@ -647,7 +630,22 @@ Bug fixes can cause the same document to score to differently depending on what segment it resides in. (yonik) -* LUCENE-2272: Fix explain in PayloadNearQuery and also fix scoring issue (Peter Keegan via Grant Ingersoll) +* LUCENE-2272: Fix explain in PayloadNearQuery and also fix scoring issue (Peter Keegan via Grant Ingersoll) + +* LUCENE-2732: Fix charset problems in XML loading in + HyphenationCompoundWordTokenFilter. (Uwe Schindler) + +* LUCENE-2802: NRT DirectoryReader returned incorrect values from + getVersion, isOptimized, getCommitUserData, getIndexCommit and isCurrent due + to a mutable reference to the IndexWriters SegmentInfos. + (Simon Willnauer, Earwin Burrfoot) + +* LUCENE-2852: Fixed corner case in RAMInputStream that would hit a + false EOF after seeking to EOF then seeking back to same block you + were just in and then calling readBytes (Robert Muir, Mike McCandless) + +* LUCENE-2860: Fixed SegmentInfo.sizeInBytes to factor includeDocStores when it + decides whether to return the cached computed size or not. (Shai Erera) New features @@ -720,6 +718,16 @@ New features can be used to prevent commits from ever getting deleted from the index. (Shai Erera) +* LUCENE-1585: IndexWriter now accepts a PayloadProcessorProvider which can + return a DirPayloadProcessor for a given Directory, which returns a + PayloadProcessor for a given Term. The PayloadProcessor will be used to + process the payloads of the segments as they are merged (e.g. if one wants to + rewrite payloads of external indexes as they are added, or of local ones). + (Shai Erera, Michael Busch, Mike McCandless) + +* LUCENE-2440: Add support for custom ExecutorService in + ParallelMultiSearcher (Edward Drapkin via Mike McCandless) + * LUCENE-2295: Added a LimitTokenCountAnalyzer / LimitTokenCountFilter to wrap any other Analyzer and provide the same functionality as MaxFieldLength provided on IndexWriter. This patch also fixes a bug @@ -727,9 +735,17 @@ New features * LUCENE-2526: Don't throw NPE from MultiPhraseQuery.toString when it's empty. (Ross Woolf via Mike McCandless) + +* LUCENE-2559: Added SegmentReader.reopen methods (John Wang via Mike + McCandless) -* LUCENE-2671: Add SortField.setMissingValue( v ) to enable sorting - behavior for documents that do not include the given field. (ryan) +* LUCENE-2590: Added Scorer.visitSubScorers, and Scorer.freq. Along + with a custom Collector these experimental methods make it possible + to gather the hit-count per sub-clause and per document while a + search is running. (Simon Willnauer, Mike McCandless) + +* LUCENE-2636: Added MultiCollector which allows running the search with several + Collectors. (Shai Erera) * LUCENE-2754, LUCENE-2757: Added a wrapper around MultiTermQueries to add span support: SpanMultiTermQueryWrapper. @@ -748,6 +764,9 @@ New features Optimizations +* LUCENE-2494: Use CompletionService in ParallelMultiSearcher instead of + simple polling for results. (Edward Drapkin, Simon Willnauer) + * LUCENE-2075: Terms dict cache is now shared across threads instead of being stored separately in thread local storage. Also fixed terms dict so that the cache is used when seeking the thread local @@ -810,6 +829,17 @@ Optimizations (getStrings, getStringIndex), consume quite a bit less RAM in most cases. (Mike McCandless) +* LUCENE-2410: ~20% speedup on exact (slop=0) PhraseQuery matching. + (Mike McCandless) + +* LUCENE-2531: Fix issue when sorting by a String field that was + causing too many fallbacks to compare-by-value (instead of by-ord). + (Mike McCandless) + +* LUCENE-2574: IndexInput exposes copyBytes(IndexOutput, long) to allow for + efficient copying by sub-classes. Optimized copy is implemented for RAM and FS + streams. (Shai Erera) + * LUCENE-2719: Improved TermsHashPerField's sorting to use a better quick sort algorithm that dereferences the pivot element not on every compare call. Also replaced lots of sorting code in Lucene @@ -889,6 +919,18 @@ Test Cases as Eclipse and IntelliJ. (Paolo Castagna, Steven Rowe via Robert Muir) +* LUCENE-2804: add newFSDirectory to LuceneTestCase to create a FSDirectory at + random. (Shai Erera, Robert Muir) + +Documentation + +* LUCENE-2579: Fix oal.search's package.html description of abstract + methods. (Santiago M. Mola via Mike McCandless) + +* LUCENE-2625: Add a note to IndexReader.termDocs() with additional verbiage + that the TermEnum must be seeked since it is unpositioned. + (Adriano Crestani via Robert Muir) + ================== Release 2.9.4 / 3.0.3 2010-12-03 ==================== Changes in runtime behavior From 9aefaf7b2b31fc1c889604579e70b47b295da31b Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 14:45:21 +0000 Subject: [PATCH 080/252] synchronized contrib/CHANGES.txt git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059936 13f79535-47bb-0310-9956-ffa450edef68 --- lucene/contrib/CHANGES.txt | 117 ++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 54 deletions(-) diff --git a/lucene/contrib/CHANGES.txt b/lucene/contrib/CHANGES.txt index 25ada890702..1200f293bd1 100644 --- a/lucene/contrib/CHANGES.txt +++ b/lucene/contrib/CHANGES.txt @@ -4,53 +4,39 @@ Lucene contrib change Log Build - * LUCENE-2413: Moved the demo out of lucene core and into contrib/demo. - (Robert Muir) - * LUCENE-2845: Moved contrib/benchmark to modules. New Features - * LUCENE-2604: Added RegexpQuery support to contrib/queryparser. - (Simon Willnauer, Robert Muir) + * LUCENE-2604: Added RegexpQuery support to contrib/queryparser. + (Simon Willnauer, Robert Muir) - * LUCENE-2500: Added DirectIOLinuxDirectory, a Linux-specific - Directory impl that uses the O_DIRECT flag to bypass the buffer - cache. This is useful to prevent segment merging from evicting - pages from the buffer cache, since fadvise/madvise do not seem. - (Michael McCandless) + * LUCENE-2373: Added a Codec implementation that works with append-only + filesystems (such as e.g. Hadoop DFS). SegmentInfos writing/reading + code is refactored to support append-only FS, and to allow for future + customization of per-segment information. (Andrzej Bialecki) - * LUCENE-2373: Added a Codec implementation that works with append-only - filesystems (such as e.g. Hadoop DFS). SegmentInfos writing/reading - code is refactored to support append-only FS, and to allow for future - customization of per-segment information. (Andrzej Bialecki) + * LUCENE-2479: Added ability to provide a sort comparator for spelling suggestions along + with two implementations. The existing comparator (score, then frequency) is the default (Grant Ingersoll) - * LUCENE-2479: Added ability to provide a sort comparator for spelling suggestions along - with two implementations. The existing comparator (score, then frequency) is the default (Grant Ingersoll) - - * LUCENE-2608: Added the ability to specify the accuracy at method time in the SpellChecker. The per class - method is also still available. (Grant Ingersoll) + * LUCENE-2608: Added the ability to specify the accuracy at method time in the SpellChecker. The per class + method is also still available. (Grant Ingersoll) - * LUCENE-2507: Added DirectSpellChecker, which retrieves correction candidates directly - from the term dictionary using levenshtein automata. (Robert Muir) + * LUCENE-2507: Added DirectSpellChecker, which retrieves correction candidates directly + from the term dictionary using levenshtein automata. (Robert Muir) - * LUCENE-2791: Added WindowsDirectory, a Windows-specific Directory impl - that doesn't synchronize on the file handle. This can be useful to - avoid the performance problems of SimpleFSDirectory and NIOFSDirectory. - (Robert Muir, Simon Willnauer, Uwe Schindler, Michael McCandless) - - * LUCENE-2836: Add FieldCacheRewriteMethod, which rewrites MultiTermQueries - using the FieldCache's TermsEnum. (Robert Muir) + * LUCENE-2836: Add FieldCacheRewriteMethod, which rewrites MultiTermQueries + using the FieldCache's TermsEnum. (Robert Muir) API Changes - * LUCENE-2606: Changed RegexCapabilities interface to fix thread - safety, serialization, and performance problems. If you have - written a custom RegexCapabilities it will need to be updated - to the new API. (Robert Muir, Uwe Schindler) + * LUCENE-2606: Changed RegexCapabilities interface to fix thread + safety, serialization, and performance problems. If you have + written a custom RegexCapabilities it will need to be updated + to the new API. (Robert Muir, Uwe Schindler) - * LUCENE-2638 MakeHighFreqTerms.TermStats public to make it more useful - for API use. (Andrzej Bialecki) + * LUCENE-2638 MakeHighFreqTerms.TermStats public to make it more useful + for API use. (Andrzej Bialecki) ======================= Lucene 3.x (not yet released) ======================= @@ -100,6 +86,11 @@ Changes in runtime behavior Bug fixes + * LUCENE-2855: contrib queryparser was using CharSequence as key in some internal + Map instances, which was leading to incorrect behaviour, since some CharSequence + implementors do not override hashcode and equals methods. Now the internal Maps + are using String instead. (Adriano Crestani) + * LUCENE-2068: Fixed ReverseStringFilter which was not aware of supplementary characters. During reverse the filter created unpaired surrogates, which will be replaced by U+FFFD by the indexer, but not at query time. The filter @@ -117,41 +108,45 @@ Bug fixes default. (Robert Muir, Uwe Schindler, Simon Willnauer) * LUCENE-2184: Fixed bug with handling best fit value when the proper best fit value is - not an indexed field. Note, this change affects the APIs. (Grant Ingersoll) + not an indexed field. Note, this change affects the APIs. (Grant Ingersoll) * LUCENE-2359: Fix bug in CartesianPolyFilterBuilder related to handling of behavior around - the 180th meridian (Grant Ingersoll) + the 180th meridian (Grant Ingersoll) * LUCENE-2404: Fix bugs with position increment and empty tokens in ThaiWordFilter. For matchVersion >= 3.1 the filter also no longer lowercases. ThaiAnalyzer will use a separate LowerCaseFilter instead. (Uwe Schindler, Robert Muir) -* LUCENE-2615: Fix DirectIOLinuxDirectory to not assign bogus - permissions to newly created files, and to not silently hardwire - buffer size to 1 MB. (Mark Miller, Robert Muir, Mike McCandless) + * LUCENE-2615: Fix DirectIOLinuxDirectory to not assign bogus + permissions to newly created files, and to not silently hardwire + buffer size to 1 MB. (Mark Miller, Robert Muir, Mike McCandless) -* LUCENE-2629: Fix gennorm2 task for generating ICUFoldingFilter's .nrm file. This allows - you to customize its normalization/folding, by editing the source data files in src/data - and regenerating a new .nrm with 'ant gennorm2'. (David Bowen via Robert Muir) + * LUCENE-2629: Fix gennorm2 task for generating ICUFoldingFilter's .nrm file. This allows + you to customize its normalization/folding, by editing the source data files in src/data + and regenerating a new .nrm with 'ant gennorm2'. (David Bowen via Robert Muir) -* LUCENE-2653: ThaiWordFilter depends on the JRE having a Thai dictionary, which is not - always the case. If the dictionary is unavailable, the filter will now throw - UnsupportedOperationException in the constructor. (Robert Muir) + * LUCENE-2653: ThaiWordFilter depends on the JRE having a Thai dictionary, which is not + always the case. If the dictionary is unavailable, the filter will now throw + UnsupportedOperationException in the constructor. (Robert Muir) -* LUCENE-589: Fix contrib/demo for international documents. - (Curtis d'Entremont via Robert Muir) + * LUCENE-589: Fix contrib/demo for international documents. + (Curtis d'Entremont via Robert Muir) -* LUCENE-2246: Fix contrib/demo for Turkish html documents. - (Selim Nadi via Robert Muir) + * LUCENE-2246: Fix contrib/demo for Turkish html documents. + (Selim Nadi via Robert Muir) -* LUCENE-590: Demo HTML parser gives incorrect summaries when title is repeated as a heading - (Curtis d'Entremont via Robert Muir) + * LUCENE-590: Demo HTML parser gives incorrect summaries when title is repeated as a heading + (Curtis d'Entremont via Robert Muir) -* LUCENE-591: The demo indexer now indexes meta keywords. - (Curtis d'Entremont via Robert Muir) + * LUCENE-591: The demo indexer now indexes meta keywords. + (Curtis d'Entremont via Robert Muir) API Changes + * LUCENE-2867: Some contrib queryparser methods that receives CharSequence as + identifier, such as QueryNode#unsetTag(CharSequence), were deprecated and + will be removed on version 4. (Adriano Crestani) + * LUCENE-2147: Spatial GeoHashUtils now always decode GeoHash strings with full precision. GeoHash#decode_exactly(String) was merged into GeoHash#decode(String). (Chris Male, Simon Willnauer) @@ -192,6 +187,12 @@ API Changes New features + * LUCENE-2500: Added DirectIOLinuxDirectory, a Linux-specific + Directory impl that uses the O_DIRECT flag to bypass the buffer + cache. This is useful to prevent segment merging from evicting + pages from the buffer cache, since fadvise/madvise do not seem. + (Michael McCandless) + * LUCENE-2306: Add NumericRangeFilter and NumericRangeQuery support to XMLQueryParser. (Jingkei Ly, via Mark Harwood) @@ -281,6 +282,11 @@ New features BooleanModifiersQueryNodeProcessor, for example instead of GroupQueryNodeProcessor. (Adriano Crestani via Robert Muir) + * LUCENE-2791: Added WindowsDirectory, a Windows-specific Directory impl + that doesn't synchronize on the file handle. This can be useful to + avoid the performance problems of SimpleFSDirectory and NIOFSDirectory. + (Robert Muir, Simon Willnauer, Uwe Schindler, Michael McCandless) + * LUCENE-2842: Add analyzer for Galician. Also adds the RSLP (Orengo) stemmer for Portuguese. (Robert Muir) @@ -305,7 +311,10 @@ Build (Robert Muir) * LUCENE-2833: Upgrade contrib/ant's jtidy jar file to r938 (Robert Muir) - + + * LUCENE-2413: Moved the demo out of lucene core and into contrib/demo. + (Robert Muir) + Optimizations * LUCENE-2157: DelimitedPayloadTokenFilter no longer copies the buffer From 9e3180bf126cfbdc30d38ca1498c24ed71432e5f Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 15:18:46 +0000 Subject: [PATCH 081/252] synchronize CHANGES.txt git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1059948 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 370 ++++++++++++++++++++++++++--------------------- 1 file changed, 208 insertions(+), 162 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index cb1d6450d84..2f56f6ccdca 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -30,6 +30,163 @@ Carrot2 3.4.2 Velocity 1.6.4 and Velocity Tools 2.0 +Upgrading from Solr 3.1-dev +---------------------- + +* The Lucene index format has changed and as a result, once you upgrade, + previous versions of Solr will no longer be able to read your indices. + In a master/slave configuration, all searchers/slaves should be upgraded + before the master. If the master were to be updated first, the older + searchers would not be able to read the new index format. + +* Setting abortOnConfigurationError=false is no longer supported + (since it has never worked properly). Solr will now warn you if + you attempt to set this configuration option at all. (see SOLR-1846) + +* The default logic for the 'mm' param of the 'dismax' QParser has + been changed. If no 'mm' param is specified (either in the query, + or as a default in solrconfig.xml) then the effective value of the + 'q.op' param (either in the query or as a default in solrconfig.xml + or from the 'defaultOperator' option in schema.xml) is used to + influence the behavior. If q.op is effectively "AND" then mm=100%. + If q.op is effectively "OR" then mm=0%. Users who wish to force the + legacy behavior should set a default value for the 'mm' param in + their solrconfig.xml file. + +Detailed Change List +---------------------- + +New Features +---------------------- + +* SOLR-571: The autowarmCount for LRUCaches (LRUCache and FastLRUCache) now + supports "percentages" which get evaluated relative the current size of + the cache when warming happens. + (Tomas Fernandez Lobbe and hossman) + +* SOLR-1915: DebugComponent now supports using a NamedList to model + Explanation objects in it's responses instead of + Explanation.toString (hossman) + +* SOLR-1932: New relevancy function queries: termfreq, tf, docfreq, idf + norm, maxdoc, numdocs. (yonik) + +* SOLR-1682: (SOLR-236, SOLR-237, SOLR-1773, SOLR-1311) Search grouping / Field collapsing. + (Martijn van Groningen, Emmanuel Keller, Shalin Shekhar Mangar, + Koji Sekiguchi, Iv锟絥 de Prado, Ryan McKinley, Marc Sturlese, Peter Karich, + Bojan Smid, Charles Hornberger, Dieter Grad, Dmitry Lihachev, Doug Steigerwald, + Karsten Sperling, Michael Gundlach, Oleg Gnatovskiy, Thomas Traeger, + Harish Agarwal, yonik) + +* SOLR-1665: Add debug component options for timings, results and query info only (gsingers, hossman, yonik) + +* SOLR-2113: Add TermQParserPlugin, registered as "term". This is useful + when generating filter queries from terms returned from field faceting or + the terms component. Example: fq={!term f=weight}1.5 (hossman, yonik) + +* SOLR-2001: The query component will substitute an empty query that matches + no documents if the query parser returns null. This also prevents an + exception from being thrown by the default parser if "q" is missing. (yonik) + +* SOLR-2112: Solrj API now supports streaming results. (ryan) + +* SOLR-792: Adding PivotFacetComponent for Hierarchical faceting + (erik, Jeremy Hinegardner, Thibaut Lassalle, ryan) + +* LUCENE-2507: Added DirectSolrSpellChecker, which uses Lucene's DirectSpellChecker + to retrieve correction candidates directly from the term dictionary using + levenshtein automata. (rmuir) + +* SOLR-1873: SolrCloud - added shared/central config and core/shard managment via zookeeper, + built-in load balancing, and infrastructure for future SolrCloud work. + (yonik, Mark Miller) + +* SOLR-1729: Evaluation of NOW for date math is done only once per request for + consistency, and is also propagated to shards in distributed search. + Adding a parameter NOW= to the request will override the + current time. (Peter Sturge, yonik) + +Optimizations +---------------------- + +* SOLR-1875: Per-segment field faceting for single valued string fields. + Enable with facet.method=fcs, control the number of threads used with + the "threads" local param on the facet.field param. This algorithm will + only be faster in the presence of rapid index changes. (yonik) + +* SOLR-1904: When facet.enum.cache.minDf > 0 and the base doc set is a + SortedIntSet, convert to HashDocSet for better performance. (yonik) + +* SOLR-1843: A new "rootName" attribute is now available when + configuring in solrconfig.xml. If this attribute is set, + Solr will use it as the root name for all MBeans Solr exposes via + JMX. The default root name is "solr" followed by the core name. + (Constantijn Visinescu, hossman) + +* SOLR-2092: Speed up single-valued and multi-valued "fc" faceting. Typical + improvement is 5%, but can be much greater (up to 10x faster) when facet.offset + is very large (deep paging). (yonik) + +Bug Fixes +---------------------- + +* SOLR-1908: Fixed SignatureUpdateProcessor to fail to initialize on + invalid config. Specificly: a signatureField that does not exist, + or overwriteDupes=true with a signatureField that is not indexed. + (hossman) + +* SOLR-1824: IndexSchema will now fail to initialize if there is a + problem initializing one of the fields or field types. (hossman) + +* SOLR-1928: TermsComponent didn't correctly break ties for non-text + fields sorted by count. (yonik) + +* SOLR-2107: MoreLikeThisHandler doesn't work with alternate qparsers. (yonik) + +* SOLR-2108: Fixed false positives when using wildcard queries on fields with reversed + wildcard support. For example, a query of *zemog* would match documents that contain + 'gomez'. (Landon Kuhn via Robert Muir) + +* SOLR-1962: SolrCore#initIndex should not use a mix of indexPath and newIndexPath (Mark Miller) + +* SOLR-2275: fix DisMax 'mm' parsing to be tolerant of whitespace + (Erick Erickson via hossman) + +Other Changes +---------------------- + +* SOLR-1846: Eliminate support for the abortOnConfigurationError + option. It has never worked very well, and in recent versions of + Solr hasn't worked at all. (hossman) + +* SOLR-1889: The default logic for the 'mm' param of DismaxQParser and + ExtendedDismaxQParser has been changed to be determined based on the + effective value of the 'q.op' param (hossman) + +* SOLR-1946: Misc improvements to the SystemInfoHandler: /admin/system + (hossman) + +* SOLR-2289: Tweak spatial coords for example docs so they are a bit + more spread out (Erick Erickson via hossman) + +* SOLR-2288: Small tweaks to eliminate compiler warnings. primarily + using Generics where applicable in method/object declatations, and + adding @SuppressWarnings("unchecked") when appropriate (hossman) + +Documentation +---------------------- + +* SOLR-2232: Improved README info on solr.solr.home in examples + (Eric Pugh and hossman) + +================== 3.1.0-dev ================== +Versions of Major Components +--------------------- +Apache Lucene trunk +Apache Tika 0.8-SNAPSHOT +Carrot2 3.4.2 + + Upgrading from Solr 1.4 ---------------------- @@ -66,25 +223,10 @@ Upgrading from Solr 1.4 * SOLR-1876: All Analyzers and TokenStreams are now final to enforce the decorator pattern. (rmuir, uschindler) -* Setting abortOnConfigurationError=false is no longer supported - (since it has never worked properly). Solr will now warn you if - you attempt to set this configuration option at all. (see SOLR-1846) - -* The default logic for the 'mm' param of the 'dismax' QParser has - been changed. If no 'mm' param is specified (either in the query, - or as a default in solrconfig.xml) then the effective value of the - 'q.op' param (either in the query or as a default in solrconfig.xml - or from the 'defaultOperator' option in schema.xml) is used to - influence the behavior. If q.op is effectively "AND" then mm=100%. - If q.op is effectively "OR" then mm=0%. Users who wish to force the - legacy behavior should set a default value for the 'mm' param in - their solrconfig.xml file. - * LUCENE-2608: Added the ability to specify the accuracy on a per request basis. - Implementations of SolrSpellChecker must change over to the new SolrSpellChecker - abstract methods using the new SpellingOptions class. While this change is not - backward compatible, it should be trivial to migrate as the SpellingOptions class - just encapsulates the parameters that were passed in to the methods before the change. (gsingers) + It is recommended that implementations of SolrSpellChecker should change over to the new SolrSpellChecker + methods using the new SpellingOptions class, but are not required to. While this change is + backward compatible, the trunk version of Solr has already dropped support for all but the SpellingOptions method. (gsingers) * readercycle script was removed. (SOLR-2046) @@ -95,10 +237,10 @@ New Features ---------------------- * SOLR-1302: Added several new distance based functions, including - Great Circle (haversine) for geo search, Manhattan, Euclidean - and String (using the StringDistance methods in the Lucene spellchecker). + Great Circle (haversine), Manhattan, Euclidean and String (using the + StringDistance methods in the Lucene spellchecker). Also added geohash(), deg() and rad() convenience functions. - See http://wiki.apache.org/solr/FunctionQuery. (yonik, gsingers) + See http://wiki.apache.org/solr/FunctionQuery. (gsingers) * SOLR-1553: New dismax parser implementation (accessible as "edismax") that supports full lucene syntax, improved reserved char escaping, @@ -130,12 +272,10 @@ New Features * SOLR-1653: Add PatternReplaceCharFilter (koji) -* SOLR-1131: FieldTypes can now output multiple Fields per Type and still be - searched. This can be handy for hiding the details of a particular - implementation such as in the spatial case. - (Chris Mattmann, shalin, noble, gsingers, yonik) +* SOLR-1131: FieldTypes can now output multiple Fields per Type and still be searched. This can be handy for hiding the details of a particular + implementation such as in the spatial case. (Chris Mattmann, shalin, noble, gsingers, yonik) -* SOLR-1586: Add support for Geohash FieldType (Chris Mattmann, gsingers) +* SOLR-1586: Add support for Geohash and Spatial Tile FieldType (Chris Mattmann, gsingers) * SOLR-1697: PluginInfo should load plugins w/o class attribute also (noble) @@ -167,41 +307,18 @@ New Features * SOLR-1740: ShingleFilterFactory supports the "minShingleSize" and "tokenSeparator" parameters for controlling the minimum shingle size produced by the filter, and the separator string that it uses, respectively. (Steven Rowe via rmuir) - + * SOLR-744: ShingleFilterFactory supports the "outputUnigramsIfNoShingles" parameter, to output unigrams if the number of input tokens is fewer than minShingleSize, and no shingles can be generated. (Chris Harris via Steven Rowe) - -* SOLR-571: The autowarmCount for LRUCaches (LRUCache and FastLRUCache) now - supports "percentages" which get evaluated relative the current size of - the cache when warming happens. - (Tomas Fernandez Lobbe and hossman) - -* SOLR-397: Date Faceting now supports a "facet.date.include" param - for specifying when the upper & lower end points of computed date - ranges should be included in the range. Legal values are: "all", - "lower", "upper", "edge", and "outer". For backwards compatibility - the default value is the set: [lower,upper,edge], so that al ranges - between start and ed are inclusive of their endpoints, but the - "before" and "after" ranges are not. - -* SOLR-945: JSON update handler that accepts add, delete, commit - commands in JSON format. (Ryan McKinley, yonik) * SOLR-1923: PhoneticFilterFactory now has support for the Caverphone algorithm. (rmuir) - -* SOLR-1915: DebugComponent now supports using a NamedList to model - Explanation objects in it's responses instead of - Explanation.toString (hossman) -* SOLR-1932: New relevancy function queries: termfreq, tf, docfreq, idf - norm, maxdoc, numdocs. (yonik) - * SOLR-1957: The VelocityResponseWriter contrib moved to core. - Example search UI now available at http://localhost:8983/solr/browse - (ehatcher) + Example search UI now available at http://localhost:8983/solr/browse + (ehatcher) * SOLR-1974: Add LimitTokenCountFilterFactory. (koji) @@ -217,11 +334,17 @@ New Features * SOLR-1984: Add HyphenationCompoundWordTokenFilterFactory. (PB via rmuir) -* SOLR-1568: Added native filtering support via geofilt for spatial field - types LatLonType, PointType, GeohashField. - See http://wiki.apache.org/solr/SpatialSearch for examples. - (yonik, gsingers) - +* SOLR-397: Date Faceting now supports a "facet.date.include" param + for specifying when the upper & lower end points of computed date + ranges should be included in the range. Legal values are: "all", + "lower", "upper", "edge", and "outer". For backwards compatibility + the default value is the set: [lower,upper,edge], so that al ranges + between start and ed are inclusive of their endpoints, but the + "before" and "after" ranges are not. + +* SOLR-945: JSON update handler that accepts add, delete, commit + commands in JSON format. (Ryan McKinley, yonik) + * SOLR-2015: Add a boolean attribute autoGeneratePhraseQueries to TextField. autoGeneratePhraseQueries="true" (the default) causes the query parser to generate phrase queries if multiple tokens are generated from a single @@ -245,57 +368,36 @@ New Features * SOLR-2053: Add support for custom comparators in Solr spellchecker, per LUCENE-2479 (gsingers) -* SOLR-1682: (SOLR-236, SOLR-237, SOLR-1773, SOLR-1311) Search grouping / Field collapsing. - (Martijn van Groningen, Emmanuel Keller, Shalin Shekhar Mangar, - Koji Sekiguchi, Iv锟絥 de Prado, Ryan McKinley, Marc Sturlese, Peter Karich, - Bojan Smid, Charles Hornberger, Dieter Grad, Dmitry Lihachev, Doug Steigerwald, - Karsten Sperling, Michael Gundlach, Oleg Gnatovskiy, Thomas Traeger, - Harish Agarwal, yonik) - -* SOLR-1316: Create autosuggest component. - (Ankul Garg, Jason Rutherglen, Shalin Shekhar Mangar, gsingers, Robert Muir, ab) +* SOLR-2049: Add hl.multiValuedSeparatorChar for FastVectorHighlighter, per LUCENE-2603. (koji) * SOLR-2059: Add "types" attribute to WordDelimiterFilterFactory, which allows you to customize how WordDelimiterFilter tokenizes text with a configuration file. (Peter Karich, rmuir) -* SOLR-1665: Add debug component options for timings, results and query info only (gsingers, hossman, yonik) - * SOLR-2099: Add ability to throttle rsync based replication using rsync option --bwlimit. (Brandon Evans via koji) -* SOLR-2113: Add TermQParserPlugin, registered as "term". This is useful - when generating filter queries from terms returned from field faceting or - the terms component. Example: fq={!term f=weight}1.5 (hossman, yonik) +* SOLR-1316: Create autosuggest component. + (Ankul Garg, Jason Rutherglen, Shalin Shekhar Mangar, Grant Ingersoll, Robert Muir, ab) -* SOLR-2001: The query component will substitute an empty query that matches - no documents if the query parser returns null. This also prevents an - exception from being thrown by the default parser if "q" is missing. (yonik) +* SOLR-1568: Added "native" filtering support for PointType, GeohashField. Added LatLonType with filtering support too. See + http://wiki.apache.org/solr/SpatialSearch and the example. Refactored some items in Lucene spatial. + Removed SpatialTileField as the underlying CartesianTier is broken beyond repair and is going to be moved. (gsingers) -* SOLR-2112: Solrj API now supports streaming results. (ryan) - -* SOLR-792: Adding PivotFacetComponent for Hierarchical faceting - (erik, Jeremy Hinegardner, Thibaut Lassalle, ryan) * SOLR-2128: Full parameter substitution for function queries. Example: q=add($v1,$v2)&v1=mul(popularity,5)&v2=20.0 (yonik) -* SOLR-2133: Function query parser can now parse multiple comma separated +* SOLR-2133: Function query parser can now parse multiple coma separated value sources. It also now fails if there is extra unexpected text after parsing the functions, instead of silently ignoring it. This allows expressions like q=dist(2,vector(1,2),$pt)&pt=3,4 (yonik) -* LUCENE-2507: Added DirectSolrSpellChecker, which uses Lucene's DirectSpellChecker - to retrieve correction candidates directly from the term dictionary using - levenshtein automata. (rmuir) +* SOLR-2157: Suggester should return alpha-sorted results when onlyMorePopular=false (ab) * SOLR-2010: Added ability to verify that spell checking collations have actual results in the index. (James Dyer via gsingers) - -* SOLR-1873: SolrCloud - added shared/central config and core/shard managment via zookeeper, - built-in load balancing, and infrastructure for future SolrCloud work. - (yonik, Mark Miller) * SOLR-2210: Add icu-based tokenizer and filters to contrib/analysis-extras (rmuir) @@ -309,11 +411,6 @@ New Features * SOLR-2237: Added StempelPolishStemFilterFactory to contrib/analysis-extras (rmuir) -* SOLR-1729: Evaluation of NOW for date math is done only once per request for - consistency, and is also propagated to shards in distributed search. - Adding a parameter NOW= to the request will override the - current time. (Peter Sturge, yonik) - * SOLR-2188: Added "maxTokenLength" argument to the factories for ClassicTokenizer, StandardTokenizer, and UAX29URLEmailTokenizer. (Steven Rowe) @@ -326,36 +423,17 @@ Optimizations * SOLR-1874: Optimize PatternReplaceFilter for better performance. (rmuir, uschindler) -* SOLR-1875: Per-segment field faceting for single valued string fields. - Enable with facet.method=fcs, control the number of threads used with - the "threads" local param on the facet.field param. This algorithm will - only be faster in the presence of rapid index changes. (yonik) - -* SOLR-1904: When facet.enum.cache.minDf > 0 and the base doc set is a - SortedIntSet, convert to HashDocSet for better performance. (yonik) - -* SOLR-1843: A new "rootName" attribute is now available when - configuring in solrconfig.xml. If this attribute is set, - Solr will use it as the root name for all MBeans Solr exposes via - JMX. The default root name is "solr" followed by the core name. - (Constantijn Visinescu, hossman) - * SOLR-1968: speed up initial filter cache population for facet.method=enum and also big terms for multi-valued facet.method=fc. The resulting speedup for the first facet request is anywhere from 30% to 32x, depending on how many - terms are in the field and how many documents match per term. (yonik) + terms are in the field and how many documents match per term. (yonik) * SOLR-2089: Speed up UnInvertedField faceting (facet.method=fc for multi-valued fields) when facet.limit is both high, and a high enough percentage of the number of unique terms in the field. Extreme cases yield speedups over 3x. (yonik) -* SOLR-2046: Simplify legacy replication scripts by adding common functions - to scripts-util. (koji) - -* SOLR-2092: Speed up single-valued and multi-valued "fc" faceting. Typical - improvement is 5%, but can be much greater (up to 10x faster) when facet.offset - is very large (deep paging). (yonik) +* SOLR-2046: add common functions to scripts-util. (koji) * SOLR-2200: Improve the performance of DataImportHandler for large delta-import updates. (Mark Waddle via rmuir) @@ -436,8 +514,8 @@ Bug Fixes * SOLR-1711: SolrJ - StreamingUpdateSolrServer had a race condition that could halt the streaming of documents. The original patch to fix this (never officially released) introduced another hanging bug due to - connections not being released. (Attila Babo, Erik Hetzner via yonik) - + connections not being released. (Attila Babo, Erik Hetzner via yonik) + * SOLR-1748, SOLR-1747, SOLR-1746, SOLR-1745, SOLR-1744: Streams and Readers retrieved from ContentStreams are not closed in various places, resulting in file descriptor leaks. @@ -470,19 +548,6 @@ Bug Fixes * SOLR-1706: fixed WordDelimiterFilter for certain combinations of options where it would output incorrect tokens. (Robert Muir, Chris Male) -* SOLR-1902: Exposed SolrResourceLoader's class loader for use by Tika - -* SOLR-1908: Fixed SignatureUpdateProcessor to fail to initialize on - invalid config. Specificly: a signatureField that does not exist, - or overwriteDupes=true with a signatureField that is not indexed. - (hossman) - -* SOLR-1824: IndexSchema will now fail to initialize if there is a - problem initializing one of the fields or field types. (hossman) - -* SOLR-1928: TermsComponent didn't correctly break ties for non-text - fields sorted by count. (yonik) - * SOLR-1936: The JSON response format needed to escape unicode code point U+2028 - 'LINE SEPARATOR' (Robert Hofstra, yonik) @@ -508,6 +573,8 @@ Bug Fixes by making SolreCore close the UpdateHandler before closing the SearchExecutor. (NarasimhaRaju, hossman) +* SOLR-1902: Upgraded Tika to 0.8-SNAPSHOT (gsingers) + * SOLR-2036: Avoid expensive fieldCache ram estimation for the admin stats page. (yonik) @@ -520,7 +587,9 @@ Bug Fixes to be removed before it was finished being copied. This did not affect normal master/slave replication. (Peter Sturge via yonik) -* SOLR-2107: MoreLikeThisHandler doesn't work with alternate qparsers. (yonik) +* SOLR-2114: Fixed parsing error in hsin function. The function signature has changed slightly. (gsingers) + +* SOLR-2083: SpellCheckComponent misreports suggestions when distributed (James Dyer via gsingers) * SOLR-2111: Change exception handling in distributed faceting to work more like non-distributed faceting, change facet_counts/exception from a String @@ -532,29 +601,22 @@ Bug Fixes substitution/dereferencing. Properly encode local params in distributed faceting. (yonik) -* SOLR-2083: SpellCheckComponent misreports suggestions when distributed (James Dyer via gsingers) - -* SOLR-2108: Fixed false positives when using wildcard queries on fields with reversed - wildcard support. For example, a query of *zemog* would match documents that contain - 'gomez'. (Landon Kuhn via Robert Muir) - * SOLR-2135: Fix behavior of ConcurrentLRUCache when asking for getLatestAccessedItems(0) or getOldestAccessedItems(0). (David Smiley via hossman) * SOLR-2148: Highlighter doesn't support q.alt. (koji) -* SOLR-2157 Suggester should return alpha-sorted results when onlyMorePopular=false (ab) - * SOLR-1794: Dataimport of CLOB fields fails when getCharacterStream() is defined in a superclass. (Gunnar Gauslaa Bergem via rmuir) +* SOLR-2180: It was possible for EmbeddedSolrServer to leave searchers + open if a request threw an exception. (yonik) + * SOLR-2173: Suggester should always rebuild Lookup data if Lookup.load fails. (ab) * SOLR-2190: change xpath from RSS 0.9 to 1.0 in slashdot sample. (koji) -* SOLR-1962: SolrCore#initIndex should not use a mix of indexPath and newIndexPath (Mark Miller) - * SOLR-2057: DataImportHandler never calls UpdateRequestProcessor.finish() (Drew Farris via koji) @@ -564,6 +626,10 @@ Bug Fixes true/on/yes (for TRUE) and false/off/no (for FALSE) can be used for sub-options (debug, verbose, synchronous, commit, clean, optimize) for full/delta-import commands. (koji) +* SOLR-2081: BaseResponseWriter.isStreamingDocs causes + SingleResponseWriter.end to be called 2x + (Chris A. Mattmann via hossman) + * SOLR-2252: When a child entity in nested entities is rootEntity="true", delta-import doesn't work. (koji) @@ -576,8 +642,6 @@ Bug Fixes addresses "commitWithin" option on Update requests. (noble, hossman, and Maxim Valyanskiy) -* SOLR-2275: fix DisMax 'mm' parsing to be tolerant of whitespace - (Erick Erickson via hossman) Other Changes ---------------------- @@ -593,6 +657,8 @@ Other Changes * SOLR-1592: Refactor XMLWriter startTag to allow arbitrary attributes to be written (Chris A. Mattmann via noble) +* SOLR-1561: Added Lucene 2.9.1 spatial contrib jar to lib. (gsingers) + * SOLR-1570: Log warnings if uniqueKey is multi-valued or not stored (hossman, shalin) * SOLR-1558: QueryElevationComponent only works if the uniqueKey field is @@ -654,20 +720,9 @@ Other Changes beginning of input files, these are often created by editors such as Windows Notepad. (rmuir, hossman) -* SOLR-1846: Eliminate support for the abortOnConfigurationError - option. It has never worked very well, and in recent versions of - Solr hasn't worked at all. (hossman) - * SOLR-1938: ElisionFilterFactory will use a default set of French contractions - if you do not supply a custom articles file. (rmuir) - -* SOLR-1889: The default logic for the 'mm' param of DismaxQParser and - ExtendedDismaxQParser has been changed to be determined based on the - effective value of the 'q.op' param (hossman) - -* SOLR-1946: Misc improvements to the SystemInfoHandler: /admin/system - (hossman) - + if you do not supply a custom articles file. (rmuir) + * SOLR-2003: SolrResourceLoader will report any encoding errors, rather than silently using replacement characters for invalid inputs (blargy via rmuir) @@ -683,12 +738,6 @@ Other Changes * SOLR-2213: Upgrade to jQuery 1.4.3 (Erick Erickson via ryan) -* SOLR-2289: Tweak spatial coords for example docs so they are a bit - more spread out (Erick Erickson via hossman) - -* SOLR-2288: Small tweaks to eliminate compiler warnings. primarily - using Generics where applicable in method/object declatations, and - adding @SuppressWarnings("unchecked") when appropriate (hossman) Build ---------------------- @@ -711,9 +760,6 @@ Documentation * SOLR-1792: Documented peculiar behavior of TestHarness.LocalRequestFactory (hossman) -* SOLR-2232: Improved README info on solr.solr.home in examples - (Eric Pugh and hossman) - ================== Release 1.4.0 ================== Release Date: See http://lucene.apache.org/solr for the official release date. From 6a53e4b75cf7bfae3544bc9a3afdfd7cad0faaf9 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 17:35:00 +0000 Subject: [PATCH 082/252] SOLR-2261: merge CHANGES.txt entry git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060019 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 2f56f6ccdca..741efb4c2a6 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -642,6 +642,9 @@ Bug Fixes addresses "commitWithin" option on Update requests. (noble, hossman, and Maxim Valyanskiy) +* SOLR-2261: fix velocity template layout.vm that referred to an older + version of jquery. (Eric Pugh via rmuir) + Other Changes ---------------------- From aed4a3972d719bd03b5ecbcaa7ca5d56af72d674 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 17:50:04 +0000 Subject: [PATCH 083/252] SOLR-2259: warn if you are using a deprecated analysis factory git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060023 13f79535-47bb-0310-9956-ffa450edef68 --- .../solr/analysis/ArabicLetterTokenizerFactory.java | 8 +++++++- .../org/apache/solr/analysis/BaseTokenStreamFactory.java | 4 ++++ .../org/apache/solr/analysis/ChineseFilterFactory.java | 7 +++++++ .../org/apache/solr/analysis/ChineseTokenizerFactory.java | 7 +++++++ .../solr/analysis/RussianLetterTokenizerFactory.java | 3 ++- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/solr/src/java/org/apache/solr/analysis/ArabicLetterTokenizerFactory.java b/solr/src/java/org/apache/solr/analysis/ArabicLetterTokenizerFactory.java index 75e0341aeed..b36ecee382b 100644 --- a/solr/src/java/org/apache/solr/analysis/ArabicLetterTokenizerFactory.java +++ b/solr/src/java/org/apache/solr/analysis/ArabicLetterTokenizerFactory.java @@ -19,6 +19,7 @@ package org.apache.solr.analysis; import org.apache.lucene.analysis.ar.ArabicLetterTokenizer; import java.io.Reader; +import java.util.Map; /** @@ -28,8 +29,13 @@ import java.io.Reader; @Deprecated public class ArabicLetterTokenizerFactory extends BaseTokenizerFactory{ - public ArabicLetterTokenizer create(Reader input) { + public void init(Map args) { + super.init(args); assureMatchVersion(); + warnDeprecated("Use StandardTokenizerFactory instead."); + } + + public ArabicLetterTokenizer create(Reader input) { return new ArabicLetterTokenizer(luceneMatchVersion, input); } } diff --git a/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java b/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java index f2977a4d42e..632b5dddbc4 100644 --- a/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java +++ b/solr/src/java/org/apache/solr/analysis/BaseTokenStreamFactory.java @@ -75,6 +75,10 @@ abstract class BaseTokenStreamFactory { } } + protected final void warnDeprecated(String message) { + log.warn(getClass().getSimpleName() + " is deprecated. " + message); + } + // TODO: move these somewhere that tokenizers and others // can also use them... protected int getInt(String name) { diff --git a/solr/src/java/org/apache/solr/analysis/ChineseFilterFactory.java b/solr/src/java/org/apache/solr/analysis/ChineseFilterFactory.java index 7e2857c48d3..6ffb67971b9 100644 --- a/solr/src/java/org/apache/solr/analysis/ChineseFilterFactory.java +++ b/solr/src/java/org/apache/solr/analysis/ChineseFilterFactory.java @@ -18,6 +18,8 @@ package org.apache.solr.analysis; +import java.util.Map; + import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.cn.ChineseFilter; @@ -27,6 +29,11 @@ import org.apache.lucene.analysis.cn.ChineseFilter; */ @Deprecated public class ChineseFilterFactory extends BaseTokenFilterFactory { + public void init(Map args) { + super.init(args); + warnDeprecated("Use StopFilterFactory instead."); + } + public ChineseFilter create(TokenStream in) { return new ChineseFilter(in); } diff --git a/solr/src/java/org/apache/solr/analysis/ChineseTokenizerFactory.java b/solr/src/java/org/apache/solr/analysis/ChineseTokenizerFactory.java index 2f0a4e83cc2..978882e2a65 100644 --- a/solr/src/java/org/apache/solr/analysis/ChineseTokenizerFactory.java +++ b/solr/src/java/org/apache/solr/analysis/ChineseTokenizerFactory.java @@ -20,6 +20,8 @@ package org.apache.solr.analysis; import java.io.Reader; +import java.util.Map; + import org.apache.lucene.analysis.cn.ChineseTokenizer; /** @@ -28,6 +30,11 @@ import org.apache.lucene.analysis.cn.ChineseTokenizer; */ @Deprecated public class ChineseTokenizerFactory extends BaseTokenizerFactory { + public void init(Map args) { + super.init(args); + warnDeprecated("Use StandardTokenizerFactory instead."); + } + public ChineseTokenizer create(Reader in) { return new ChineseTokenizer(in); } diff --git a/solr/src/java/org/apache/solr/analysis/RussianLetterTokenizerFactory.java b/solr/src/java/org/apache/solr/analysis/RussianLetterTokenizerFactory.java index fd0ab7e3d96..587f082c7de 100644 --- a/solr/src/java/org/apache/solr/analysis/RussianLetterTokenizerFactory.java +++ b/solr/src/java/org/apache/solr/analysis/RussianLetterTokenizerFactory.java @@ -37,10 +37,11 @@ public class RussianLetterTokenizerFactory extends BaseTokenizerFactory { throw new SolrException(ErrorCode.SERVER_ERROR, "The charset parameter is no longer supported. " + "Please process your documents as Unicode instead."); + assureMatchVersion(); + warnDeprecated("Use StandardTokenizerFactory instead."); } public RussianLetterTokenizer create(Reader in) { - assureMatchVersion(); return new RussianLetterTokenizer(luceneMatchVersion,in); } } From 5fac196404e7b2937df83cd4e805b2276a42fda9 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 19:51:01 +0000 Subject: [PATCH 084/252] SOLR-2269: contrib entries in solr/CHANGES.txt should go solr/contrib/*/CHANGES.txt git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060057 13f79535-47bb-0310-9956-ffa450edef68 --- solr/CHANGES.txt | 23 --- solr/contrib/analysis-extras/CHANGES.txt | 30 +++ solr/contrib/clustering/CHANGES.txt | 5 +- solr/contrib/clustering/DISABLED-README.txt | 7 - solr/contrib/clustering/build.xml.disabled | 191 -------------------- solr/contrib/dataimporthandler/CHANGES.txt | 12 ++ solr/contrib/extraction/CHANGES.txt | 6 +- 7 files changed, 51 insertions(+), 223 deletions(-) create mode 100644 solr/contrib/analysis-extras/CHANGES.txt delete mode 100644 solr/contrib/clustering/DISABLED-README.txt delete mode 100644 solr/contrib/clustering/build.xml.disabled diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 741efb4c2a6..c106675e2c3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -399,18 +399,6 @@ New Features * SOLR-2010: Added ability to verify that spell checking collations have actual results in the index. (James Dyer via gsingers) -* SOLR-2210: Add icu-based tokenizer and filters to contrib/analysis-extras (rmuir) - -* SOLR-1336: Add SmartChinese (word segmentation for Simplified Chinese) - tokenizer and filters to contrib/analysis-extras (rmuir) - -* SOLR-2211,LUCENE-2763: Added UAX29URLEmailTokenizerFactory, which implements - UAX#29, a unicode algorithm with good results for most languages, as well as - URL and E-mail tokenization according to the relevant RFCs. - (Tom Burton-West via rmuir) - -* SOLR-2237: Added StempelPolishStemFilterFactory to contrib/analysis-extras (rmuir) - * SOLR-2188: Added "maxTokenLength" argument to the factories for ClassicTokenizer, StandardTokenizer, and UAX29URLEmailTokenizer. (Steven Rowe) @@ -435,9 +423,6 @@ Optimizations * SOLR-2046: add common functions to scripts-util. (koji) -* SOLR-2200: Improve the performance of DataImportHandler for large delta-import - updates. (Mark Waddle via rmuir) - Bug Fixes ---------------------- * SOLR-1432: Make the new ValueSource.getValues(context,reader) delegate @@ -573,8 +558,6 @@ Bug Fixes by making SolreCore close the UpdateHandler before closing the SearchExecutor. (NarasimhaRaju, hossman) -* SOLR-1902: Upgraded Tika to 0.8-SNAPSHOT (gsingers) - * SOLR-2036: Avoid expensive fieldCache ram estimation for the admin stats page. (yonik) @@ -630,9 +613,6 @@ Bug Fixes SingleResponseWriter.end to be called 2x (Chris A. Mattmann via hossman) -* SOLR-2252: When a child entity in nested entities is rootEntity="true", delta-import doesn't work. - (koji) - * SOLR-2219: The init() method of every SolrRequestHandler was being called twice. (ambikeshwar singh and hossman) @@ -714,9 +694,6 @@ Other Changes "defaultSearchField" as the default value for the "qf" param instead of failing with an error when "qf" is not specified. (hossman) -* SOLR-1821: Fix TimeZone-dependent test failure in TestEvaluatorBag. - (Chris Male via rmuir) - * SOLR-1851: luceneAutoCommit no longer has any effect - it has been remove (Mark Miller) * SOLR-1865: SolrResourceLoader.getLines ignores Byte Order Markers (BOMs) at the diff --git a/solr/contrib/analysis-extras/CHANGES.txt b/solr/contrib/analysis-extras/CHANGES.txt new file mode 100644 index 00000000000..e512decaa99 --- /dev/null +++ b/solr/contrib/analysis-extras/CHANGES.txt @@ -0,0 +1,30 @@ + Apache Solr - Analysis Extras + Release Notes + +Introduction +------------ +The analysis-extras plugin provides additional analyzers that rely +upon large dependencies/dictionaries. + +It includes integration with ICU for multilingual support, and +analyzers for Chinese and Polish. + + +$Id$ +================== Release 4.0-dev ================== + +(No Changes) + +================== Release 3.1-dev ================== + +* SOLR-2210: Add icu-based tokenizer and filters to contrib/analysis-extras (rmuir) + +* SOLR-1336: Add SmartChinese (word segmentation for Simplified Chinese) + tokenizer and filters to contrib/analysis-extras (rmuir) + +* SOLR-2211,LUCENE-2763: Added UAX29URLEmailTokenizerFactory, which implements + UAX#29, a unicode algorithm with good results for most languages, as well as + URL and E-mail tokenization according to the relevant RFCs. + (Tom Burton-West via rmuir) + +* SOLR-2237: Added StempelPolishStemFilterFactory to contrib/analysis-extras (rmuir) diff --git a/solr/contrib/clustering/CHANGES.txt b/solr/contrib/clustering/CHANGES.txt index a350571fb4f..2bf66fa5f01 100644 --- a/solr/contrib/clustering/CHANGES.txt +++ b/solr/contrib/clustering/CHANGES.txt @@ -7,8 +7,11 @@ See http://wiki.apache.org/solr/ClusteringComponent CHANGES $Id$ +================== Release 4.0.0-dev ================== -================== Release XXXX ================== +(No Changes) + +================== Release 3.1.0-dev ================== * SOLR-1684: Switch to use the SolrIndexSearcher.doc(int, Set) method b/c it can use the document cache (gsingers) diff --git a/solr/contrib/clustering/DISABLED-README.txt b/solr/contrib/clustering/DISABLED-README.txt deleted file mode 100644 index 8a43dbda63d..00000000000 --- a/solr/contrib/clustering/DISABLED-README.txt +++ /dev/null @@ -1,7 +0,0 @@ -In trunk this contrib module is currently disabled, as it uses the external -(binary) Carrot2 library (as trunk is free to change its API, this module fails -with linking exceptions). - -After a stable branch of Lucene is created from trunk, rename -'build.xml.disabled' back to 'build.xml' after replacing the Carrot2 -JARs by updated versions. diff --git a/solr/contrib/clustering/build.xml.disabled b/solr/contrib/clustering/build.xml.disabled deleted file mode 100644 index c5cb3af4548..00000000000 --- a/solr/contrib/clustering/build.xml.disabled +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - - - - - Clustering Integraton - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tests failed! - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/solr/contrib/dataimporthandler/CHANGES.txt b/solr/contrib/dataimporthandler/CHANGES.txt index dcd0185895b..0391b5816a8 100644 --- a/solr/contrib/dataimporthandler/CHANGES.txt +++ b/solr/contrib/dataimporthandler/CHANGES.txt @@ -9,6 +9,10 @@ HTTP data sources quick and easy. $Id$ ================== 4.0.0-dev ================== + +(No Changes) + +================== 3.1.0-dev ================== Upgrading from Solr 1.4 ---------------------- @@ -44,6 +48,9 @@ New Features Optimizations ---------------------- +* SOLR-2200: Improve the performance of DataImportHandler for large delta-import + updates. (Mark Waddle via rmuir) + Bug Fixes ---------------------- * SOLR-1638: Fixed NullPointerException during import if uniqueKey is not specified @@ -68,9 +75,14 @@ Bug Fixes * SOLR-2310: getTimeElapsedSince() returns incorrect hour value when the elapse is over 60 hours (tom liu via koji) +* SOLR-2252: When a child entity in nested entities is rootEntity="true", delta-import doesn't work. + (koji) + Other Changes ---------------------- +* SOLR-1821: Fix TimeZone-dependent test failure in TestEvaluatorBag. + (Chris Male via rmuir) Build ---------------------- diff --git a/solr/contrib/extraction/CHANGES.txt b/solr/contrib/extraction/CHANGES.txt index 86d23bda34c..4309db21b21 100644 --- a/solr/contrib/extraction/CHANGES.txt +++ b/solr/contrib/extraction/CHANGES.txt @@ -24,9 +24,13 @@ Current Version: Tika 0.8 (released 11/07/2010) $Id:$ +================== Release 4.0-dev ================== + +(No Changes) + ================== Release 3.1-dev ================== -* Upgraded to Tika 0.8 and changed deprecated parse call +* SOLR-1902: Upgraded to Tika 0.8 and changed deprecated parse call * SOLR-1756: The date.format setting causes ClassCastException when enabled and the config code that parses this setting does not properly use the same iterator instance. (Christoph Brill, Mark Miller) From fcd36f577089d664b5cf2c9f8b7a2a0e529c9bc0 Mon Sep 17 00:00:00 2001 From: Robert Muir Date: Mon, 17 Jan 2011 21:25:46 +0000 Subject: [PATCH 085/252] clear javadocs warnings git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060098 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/lucene/index/codecs/PrefixCodedTermState.java | 1 + .../java/org/apache/lucene/search/FieldComparator.java | 2 +- lucene/src/java/org/apache/lucene/search/Filter.java | 1 + lucene/src/java/org/apache/lucene/search/Weight.java | 8 ++++---- .../org/apache/lucene/search/function/ValueSource.java | 3 +-- .../java/org/apache/lucene/util/PerReaderTermState.java | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java index 50b4fd3ca5e..aa4119ab32f 100644 --- a/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java +++ b/lucene/src/java/org/apache/lucene/index/codecs/PrefixCodedTermState.java @@ -16,6 +16,7 @@ package org.apache.lucene.index.codecs; * limitations under the License. */ +import org.apache.lucene.index.DocsEnum; // javadocs import org.apache.lucene.index.OrdTermState; import org.apache.lucene.index.TermState; diff --git a/lucene/src/java/org/apache/lucene/search/FieldComparator.java b/lucene/src/java/org/apache/lucene/search/FieldComparator.java index 54bc20ba95a..1b2fc61c4ae 100644 --- a/lucene/src/java/org/apache/lucene/search/FieldComparator.java +++ b/lucene/src/java/org/apache/lucene/search/FieldComparator.java @@ -82,7 +82,7 @@ import org.apache.lucene.util.packed.PackedInts; * priority queue. The {@link FieldValueHitQueue} * calls this method when a new hit is competitive. * - *
  26. {@link #setNextReader(AtomicReaderContext)} Invoked + *
  27. {@link #setNextReader(IndexReader.AtomicReaderContext)} Invoked * when the search is switching to the next segment. * You may need to update internal state of the * comparator, for example retrieving new values from diff --git a/lucene/src/java/org/apache/lucene/search/Filter.java b/lucene/src/java/org/apache/lucene/search/Filter.java index f4404c71860..468a43b663c 100644 --- a/lucene/src/java/org/apache/lucene/search/Filter.java +++ b/lucene/src/java/org/apache/lucene/search/Filter.java @@ -19,6 +19,7 @@ package org.apache.lucene.search; import java.io.IOException; +import org.apache.lucene.index.IndexReader; // javadocs import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.util.DocIdBitSet; diff --git a/lucene/src/java/org/apache/lucene/search/Weight.java b/lucene/src/java/org/apache/lucene/search/Weight.java index 8c26047ab1d..65cc6ec61e2 100644 --- a/lucene/src/java/org/apache/lucene/search/Weight.java +++ b/lucene/src/java/org/apache/lucene/search/Weight.java @@ -34,7 +34,7 @@ import org.apache.lucene.index.IndexReader.ReaderContext; * {@link IndexReader} dependent state should reside in the {@link Scorer}. *

    * Since {@link Weight} creates {@link Scorer} instances for a given - * {@link AtomicReaderContext} ({@link #scorer(AtomicReaderContext, boolean, boolean)}) + * {@link AtomicReaderContext} ({@link #scorer(IndexReader.AtomicReaderContext, ScorerContext)}) * callers must maintain the relationship between the searcher's top-level * {@link ReaderContext} and the context used to create a {@link Scorer}. *

    @@ -49,7 +49,7 @@ import org.apache.lucene.index.IndexReader.ReaderContext; *

  28. The query normalization factor is passed to {@link #normalize(float)}. At * this point the weighting is complete. *
  29. A Scorer is constructed by - * {@link #scorer(AtomicReaderContext, ScorerContext)}. + * {@link #scorer(IndexReader.AtomicReaderContext, ScorerContext)}. * * * @since 2.9 @@ -89,7 +89,7 @@ public abstract class Weight implements Serializable { * * @param context * the {@link AtomicReaderContext} for which to return the {@link Scorer}. - * @param scorercontext the {@link ScorerContext} holding the scores context variables + * @param scorerContext the {@link ScorerContext} holding the scores context variables * @return a {@link Scorer} which scores documents in/out-of order. * @throws IOException */ @@ -102,7 +102,7 @@ public abstract class Weight implements Serializable { * Returns true iff this implementation scores docs only out of order. This * method is used in conjunction with {@link Collector}'s * {@link Collector#acceptsDocsOutOfOrder() acceptsDocsOutOfOrder} and - * {@link #scorer(AtomicReaderContext, boolean, boolean)} to + * {@link #scorer(IndexReader.AtomicReaderContext, ScorerContext)} to * create a matching {@link Scorer} instance for a given {@link Collector}, or * vice versa. *

    diff --git a/lucene/src/java/org/apache/lucene/search/function/ValueSource.java b/lucene/src/java/org/apache/lucene/search/function/ValueSource.java index b2c9603694a..debaa1615b5 100755 --- a/lucene/src/java/org/apache/lucene/search/function/ValueSource.java +++ b/lucene/src/java/org/apache/lucene/search/function/ValueSource.java @@ -19,7 +19,6 @@ package org.apache.lucene.search.function; import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.CompositeReaderContext; -import org.apache.lucene.index.IndexReader.AtomicReaderContext; import org.apache.lucene.index.IndexReader.ReaderContext; import org.apache.lucene.search.function.DocValues; @@ -52,7 +51,7 @@ public abstract class ValueSource implements Serializable { * Return the DocValues used by the function query. * @deprecated (4.0) This method is temporary, to ease the migration to segment-based * searching. Please change your code to not pass {@link CompositeReaderContext} to these - * APIs. Use {@link #getValues(AtomicReaderContext)} instead + * APIs. Use {@link #getValues(IndexReader.AtomicReaderContext)} instead */ @Deprecated public DocValues getValues(ReaderContext context) throws IOException { diff --git a/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java b/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java index bff514df035..81ad4ce2f3b 100644 --- a/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java +++ b/lucene/src/java/org/apache/lucene/util/PerReaderTermState.java @@ -138,9 +138,9 @@ public final class PerReaderTermState { /** * Returns the accumulated document frequency of all {@link TermState} - * instances passed to {@link #register(TermState, int)}. + * instances passed to {@link #register(TermState, int, int)}. * @return the accumulated document frequency of all {@link TermState} - * instances passed to {@link #register(TermState, int)}. + * instances passed to {@link #register(TermState, int, int)}. */ public int docFreq() { return docFreq; From e43fdc9654be8f6ca6b9b6b0146e3e6793f35943 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Tue, 18 Jan 2011 11:31:35 +0000 Subject: [PATCH 086/252] say how many msec flush took, in infoStream git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060324 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/java/org/apache/lucene/index/DocumentsWriter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java b/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java index e7e34e5d9a5..8b9d33e3135 100644 --- a/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java @@ -546,6 +546,8 @@ final class DocumentsWriter { // Lock order: IW -> DW synchronized SegmentInfo flush(IndexWriter writer, IndexFileDeleter deleter, MergePolicy mergePolicy, SegmentInfos segmentInfos) throws IOException { + final long startTime = System.currentTimeMillis(); + // We change writer's segmentInfos: assert Thread.holdsLock(writer); @@ -646,6 +648,10 @@ final class DocumentsWriter { // Lock order: IW -> DW -> BD pushDeletes(newSegment, segmentInfos); + if (infoStream != null) { + message("flush time " + (System.currentTimeMillis()-startTime) + " msec"); + } + return newSegment; } From 2a0484bd4042fda89e82ba915df77081f0c4297c Mon Sep 17 00:00:00 2001 From: Shai Erera Date: Tue, 18 Jan 2011 12:01:40 +0000 Subject: [PATCH 087/252] LUCENE-2295: remove maxFieldLength (trunk) git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1060340 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/lucene/demo/IndexHTML.java | 3 +- .../lucene/index/DocInverterPerField.java | 8 +--- .../apache/lucene/index/DocumentsWriter.java | 10 +---- .../index/DocumentsWriterThreadState.java | 1 - .../org/apache/lucene/index/IndexWriter.java | 30 ++------------- .../lucene/index/IndexWriterConfig.java | 38 +------------------ .../apache/lucene/index/TestIndexWriter.java | 27 +------------ .../lucene/index/TestIndexWriterConfig.java | 13 ------- .../TestLimitTokenCountAnalyzer.java | 30 +++++++++++++++ .../byTask/tasks/CreateIndexTask.java | 4 +- .../benchmark/byTask/tasks/OpenIndexTask.java | 2 - .../solr/spelling/FileBasedSpellChecker.java | 2 - .../apache/solr/update/SolrIndexConfig.java | 6 --- .../solr/core/TestArbitraryIndexDir.java | 3 +- .../test/org/apache/solr/search/TestSort.java | 3 +- .../spelling/IndexBasedSpellCheckerTest.java | 3 +- 16 files changed, 43 insertions(+), 140 deletions(-) diff --git a/lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexHTML.java b/lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexHTML.java index 07c18cbe3fd..75090df931a 100644 --- a/lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexHTML.java +++ b/lucene/contrib/demo/src/java/org/apache/lucene/demo/IndexHTML.java @@ -84,8 +84,7 @@ public class IndexHTML { } writer = new IndexWriter(FSDirectory.open(index), new IndexWriterConfig( Version.LUCENE_CURRENT, new StandardAnalyzer(Version.LUCENE_CURRENT)) - .setMaxFieldLength(1000000).setOpenMode( - create ? OpenMode.CREATE : OpenMode.CREATE_OR_APPEND)); + .setOpenMode(create ? OpenMode.CREATE : OpenMode.CREATE_OR_APPEND)); indexDocs(root, index, create); // add new docs System.out.println("Optimizing index..."); diff --git a/lucene/src/java/org/apache/lucene/index/DocInverterPerField.java b/lucene/src/java/org/apache/lucene/index/DocInverterPerField.java index 95d64c44136..d360fbfb230 100644 --- a/lucene/src/java/org/apache/lucene/index/DocInverterPerField.java +++ b/lucene/src/java/org/apache/lucene/index/DocInverterPerField.java @@ -63,8 +63,6 @@ final class DocInverterPerField extends DocFieldConsumerPerField { fieldState.reset(docState.doc.getBoost()); - final int maxFieldLength = docState.maxFieldLength; - final boolean doInvert = consumer.start(fields, count); for(int i=0;i= maxFieldLength) { - if (docState.infoStream != null) - docState.infoStream.println("maxFieldLength " +maxFieldLength+ " reached for field " + fieldInfo.name + ", ignoring following tokens"); - break; - } hasMoreTokens = stream.incrementToken(); } diff --git a/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java b/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java index 8b9d33e3135..0f8b401e107 100644 --- a/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java +++ b/lucene/src/java/org/apache/lucene/index/DocumentsWriter.java @@ -127,7 +127,6 @@ final class DocumentsWriter { private boolean aborting; // True if an abort is pending PrintStream infoStream; - int maxFieldLength = IndexWriterConfig.UNLIMITED_FIELD_LENGTH; Similarity similarity; // max # simultaneous threads; if there are more than @@ -140,7 +139,6 @@ final class DocumentsWriter { static class DocState { DocumentsWriter docWriter; Analyzer analyzer; - int maxFieldLength; PrintStream infoStream; Similarity similarity; int docID; @@ -191,6 +189,7 @@ final class DocumentsWriter { /** * Allocate bytes used from shared pool. */ + @Override protected byte[] newBuffer(int size) { assert size == PER_DOC_BLOCK_SIZE; return perDocAllocator.getByteBlock(); @@ -358,13 +357,6 @@ final class DocumentsWriter { } } - synchronized void setMaxFieldLength(int maxFieldLength) { - this.maxFieldLength = maxFieldLength; - for(int i=0;i - * NOTE: by default, {@link IndexWriterConfig#getMaxFieldLength()} - * returns {@link IndexWriterConfig#UNLIMITED_FIELD_LENGTH}. Pay attention to - * whether this setting fits your application. * * @param d * the index directory. The index is either created or appended @@ -689,7 +686,6 @@ public class IndexWriter implements Closeable { directory = d; analyzer = conf.getAnalyzer(); infoStream = defaultInfoStream; - maxFieldLength = conf.getMaxFieldLength(); termIndexInterval = conf.getTermIndexInterval(); mergePolicy = conf.getMergePolicy(); mergePolicy.setIndexWriter(this); @@ -768,7 +764,6 @@ public class IndexWriter implements Closeable { docWriter = new DocumentsWriter(directory, this, conf.getIndexingChain(), conf.getMaxThreadStates(), getCurrentFieldInfos(), bufferedDeletes); docWriter.setInfoStream(infoStream); - docWriter.setMaxFieldLength(maxFieldLength); // Default deleter (for backwards compatibility) is // KeepOnlyLastCommitDeleter: @@ -987,6 +982,7 @@ public class IndexWriter implements Closeable { * @throws CorruptIndexException if the index is corrupt * @throws IOException if there is a low-level IO error */ + @Override public void close() throws CorruptIndexException, IOException { close(true); } @@ -1177,25 +1173,7 @@ public class IndexWriter implements Closeable { } /** - * The maximum number of terms that will be indexed for a single field in a - * document. This limits the amount of memory required for indexing, so that - * collections with very large files will not crash the indexing process by - * running out of memory.

    - * Note that this effectively truncates large documents, excluding from the - * index terms that occur further in the document. If you know your source - * documents are large, be sure to set this value high enough to accommodate - * the expected size. If you set it to Integer.MAX_VALUE, then the only limit - * is your memory, but you should anticipate an OutOfMemoryError.

    - * By default, no more than 10,000 terms will be indexed for a field. - * - * @see MaxFieldLength - */ - private int maxFieldLength; - - /** - * Adds a document to this index. If the document contains more than - * {@link IndexWriterConfig#setMaxFieldLength(int)} terms for a given field, - * the remainder are discarded. + * Adds a document to this index. * *

    Note that if an Exception is hit (for example disk full) * then the index will be consistent, but this document @@ -1242,9 +1220,7 @@ public class IndexWriter implements Closeable { /** * Adds a document to this index, using the provided analyzer instead of the - * value of {@link #getAnalyzer()}. If the document contains more than - * {@link IndexWriterConfig#setMaxFieldLength(int)} terms for a given field, the remainder are - * discarded. + * value of {@link #getAnalyzer()}. * *

    See {@link #addDocument(Document)} for details on * index and IndexWriter state after an Exception, and diff --git a/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java b/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java index 34240ea5f2d..e8b6eb4a2c3 100644 --- a/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java +++ b/lucene/src/java/org/apache/lucene/index/IndexWriterConfig.java @@ -41,8 +41,6 @@ import org.apache.lucene.util.Version; */ public final class IndexWriterConfig implements Cloneable { - public static final int UNLIMITED_FIELD_LENGTH = Integer.MAX_VALUE; - /** * Specifies the open mode for {@link IndexWriter}: *