You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ar...@apache.org on 2008/06/25 04:51:26 UTC
svn commit: r671402 [2/5] - in
/incubator/lucene.net/trunk/C#/src/Lucene.Net/Search: ./ Function/ Payload/
Spans/
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FieldSortedHitQueue.cs?rev=671402&r1=671401&r2=671402&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FieldSortedHitQueue.cs Tue Jun 24 19:51:24 2008
@@ -33,9 +33,9 @@
/// </author>
/// <since> lucene 1.4
/// </since>
- /// <version> $Id: FieldSortedHitQueue.java 477084 2006-11-20 07:10:04Z otis $
+ /// <version> $Id: FieldSortedHitQueue.java 605225 2007-12-18 15:13:05Z gsingers $
/// </version>
- /// <seealso cref="Searcher#Search(Query,Filter,int,Sort)">
+ /// <seealso cref="Searcher.Search(Query,Filter,int,Sort)">
/// </seealso>
/// <seealso cref="FieldCache">
/// </seealso>
@@ -60,18 +60,26 @@
break;
case SortField.INT:
- comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorInt(reader, fieldname);
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorInt(reader, fieldname);
break;
case SortField.FLOAT:
- comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorFloat(reader, fieldname);
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorFloat(reader, fieldname);
+ break;
+
+ case SortField.LONG:
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorLong(reader, fieldname);
+ break;
+
+ case SortField.DOUBLE:
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorDouble(reader, fieldname);
break;
case SortField.STRING:
if (locale != null)
- comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorStringLocale(reader, fieldname, locale);
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorStringLocale(reader, fieldname, locale);
else
- comparator = Lucene.Net.Search.FieldSortedHitQueue.comparatorString(reader, fieldname);
+ comparator = Lucene.Net.Search.FieldSortedHitQueue.ComparatorString(reader, fieldname);
break;
case SortField.CUSTOM:
@@ -120,7 +128,40 @@
}
private class AnonymousClassScoreDocComparator1 : ScoreDocComparator
{
- public AnonymousClassScoreDocComparator1(float[] fieldOrder)
+ public AnonymousClassScoreDocComparator1(long[] fieldOrder)
+ {
+ InitBlock(fieldOrder);
+ }
+ private void InitBlock(long[] fieldOrder)
+ {
+ this.fieldOrder = fieldOrder;
+ }
+ private long[] fieldOrder;
+
+ public int Compare(ScoreDoc i, ScoreDoc j)
+ {
+ long li = fieldOrder[i.doc];
+ long lj = fieldOrder[j.doc];
+ if (li < lj)
+ return - 1;
+ if (li > lj)
+ return 1;
+ return 0;
+ }
+
+ public virtual System.IComparable SortValue(ScoreDoc i)
+ {
+ return (long) fieldOrder[i.doc];
+ }
+
+ public virtual int SortType()
+ {
+ return SortField.LONG;
+ }
+ }
+ private class AnonymousClassScoreDocComparator2 : ScoreDocComparator
+ {
+ public AnonymousClassScoreDocComparator2(float[] fieldOrder)
{
InitBlock(fieldOrder);
}
@@ -151,9 +192,42 @@
return SortField.FLOAT;
}
}
- private class AnonymousClassScoreDocComparator2 : ScoreDocComparator
+ private class AnonymousClassScoreDocComparator3 : ScoreDocComparator
+ {
+ public AnonymousClassScoreDocComparator3(double[] fieldOrder)
+ {
+ InitBlock(fieldOrder);
+ }
+ private void InitBlock(double[] fieldOrder)
+ {
+ this.fieldOrder = fieldOrder;
+ }
+ private double[] fieldOrder;
+
+ public int Compare(ScoreDoc i, ScoreDoc j)
+ {
+ double di = fieldOrder[i.doc];
+ double dj = fieldOrder[j.doc];
+ if (di < dj)
+ return - 1;
+ if (di > dj)
+ return 1;
+ return 0;
+ }
+
+ public virtual System.IComparable SortValue(ScoreDoc i)
+ {
+ return (double) fieldOrder[i.doc];
+ }
+
+ public virtual int SortType()
+ {
+ return SortField.DOUBLE;
+ }
+ }
+ private class AnonymousClassScoreDocComparator4 : ScoreDocComparator
{
- public AnonymousClassScoreDocComparator2(Lucene.Net.Search.StringIndex index)
+ public AnonymousClassScoreDocComparator4(Lucene.Net.Search.StringIndex index)
{
InitBlock(index);
}
@@ -184,9 +258,9 @@
return SortField.STRING;
}
}
- private class AnonymousClassScoreDocComparator3 : ScoreDocComparator
+ private class AnonymousClassScoreDocComparator5 : ScoreDocComparator
{
- public AnonymousClassScoreDocComparator3(System.String[] index, System.Globalization.CompareInfo collator)
+ public AnonymousClassScoreDocComparator5(System.String[] index, System.Globalization.CompareInfo collator)
{
InitBlock(index, collator);
}
@@ -277,12 +351,18 @@
return maxscore;
}
+ // Update maxscore.
+ private void UpdateMaxScore(FieldDoc fdoc)
+ {
+ maxscore = System.Math.Max(maxscore, fdoc.score);
+ }
+
// The signature of this method takes a FieldDoc in order to avoid
// the unneeded cast to retrieve the score.
// inherit javadoc
public virtual bool Insert(FieldDoc fdoc)
{
- maxscore = System.Math.Max(maxscore, fdoc.score);
+ UpdateMaxScore(fdoc);
return base.Insert(fdoc);
}
@@ -294,6 +374,15 @@
return Insert((FieldDoc) fdoc);
}
+ // This overrides PriorityQueue.insertWithOverflow() so that
+ // updateMaxScore(FieldDoc) that keeps track of the score isn't accidentally
+ // bypassed.
+ public override System.Object InsertWithOverflow(System.Object element)
+ {
+ UpdateMaxScore((FieldDoc) element);
+ return base.InsertWithOverflow(element);
+ }
+
/// <summary> Returns whether <code>a</code> is less relevant than <code>b</code>.</summary>
/// <param name="a">ScoreDoc
/// </param>
@@ -311,7 +400,7 @@
int c = 0;
for (int i = 0; i < n && c == 0; ++i)
{
- c = (fields[i].reverse)?comparators[i].Compare(docB, docA):comparators[i].Compare(docA, docB);
+ c = (fields[i].reverse) ? comparators[i].Compare(docB, docA) : comparators[i].Compare(docA, docB);
}
// avoid random sort order that could lead to duplicates (bug #31241):
if (c == 0)
@@ -330,7 +419,7 @@
/// </param>
/// <returns> The same FieldDoc passed in.
/// </returns>
- /// <seealso cref="Searchable#Search(Weight,Filter,int,Sort)">
+ /// <seealso cref="Searchable.Search(Weight,Filter,int,Sort)">
/// </seealso>
internal virtual FieldDoc FillFields(FieldDoc doc)
{
@@ -373,13 +462,29 @@
/// <returns> Comparator for sorting hits.
/// </returns>
/// <throws> IOException If an error occurs reading the index. </throws>
- internal static ScoreDocComparator comparatorInt(IndexReader reader, System.String fieldname)
+ internal static ScoreDocComparator ComparatorInt(IndexReader reader, System.String fieldname)
{
System.String field = String.Intern(fieldname);
int[] fieldOrder = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(reader, field);
return new AnonymousClassScoreDocComparator(fieldOrder);
}
+ /// <summary> Returns a comparator for sorting hits according to a field containing integers.</summary>
+ /// <param name="reader"> Index to use.
+ /// </param>
+ /// <param name="fieldname"> Fieldable containg integer values.
+ /// </param>
+ /// <returns> Comparator for sorting hits.
+ /// </returns>
+ /// <throws> IOException If an error occurs reading the index. </throws>
+ internal static ScoreDocComparator ComparatorLong(IndexReader reader, System.String fieldname)
+ {
+ System.String field = String.Intern(fieldname);
+ long[] fieldOrder = Lucene.Net.Search.ExtendedFieldCache_Fields.EXT_DEFAULT.GetLongs(reader, field);
+ return new AnonymousClassScoreDocComparator1(fieldOrder);
+ }
+
+
/// <summary> Returns a comparator for sorting hits according to a field containing floats.</summary>
/// <param name="reader"> Index to use.
/// </param>
@@ -388,11 +493,26 @@
/// <returns> Comparator for sorting hits.
/// </returns>
/// <throws> IOException If an error occurs reading the index. </throws>
- internal static ScoreDocComparator comparatorFloat(IndexReader reader, System.String fieldname)
+ internal static ScoreDocComparator ComparatorFloat(IndexReader reader, System.String fieldname)
{
System.String field = String.Intern(fieldname);
float[] fieldOrder = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetFloats(reader, field);
- return new AnonymousClassScoreDocComparator1(fieldOrder);
+ return new AnonymousClassScoreDocComparator2(fieldOrder);
+ }
+
+ /// <summary> Returns a comparator for sorting hits according to a field containing doubles.</summary>
+ /// <param name="reader"> Index to use.
+ /// </param>
+ /// <param name="fieldname"> Fieldable containg float values.
+ /// </param>
+ /// <returns> Comparator for sorting hits.
+ /// </returns>
+ /// <throws> IOException If an error occurs reading the index. </throws>
+ internal static ScoreDocComparator ComparatorDouble(IndexReader reader, System.String fieldname)
+ {
+ System.String field = String.Intern(fieldname);
+ double[] fieldOrder = Lucene.Net.Search.ExtendedFieldCache_Fields.EXT_DEFAULT.GetDoubles(reader, field);
+ return new AnonymousClassScoreDocComparator3(fieldOrder);
}
/// <summary> Returns a comparator for sorting hits according to a field containing strings.</summary>
@@ -403,11 +523,11 @@
/// <returns> Comparator for sorting hits.
/// </returns>
/// <throws> IOException If an error occurs reading the index. </throws>
- internal static ScoreDocComparator comparatorString(IndexReader reader, System.String fieldname)
+ internal static ScoreDocComparator ComparatorString(IndexReader reader, System.String fieldname)
{
System.String field = String.Intern(fieldname);
Lucene.Net.Search.StringIndex index = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetStringIndex(reader, field);
- return new AnonymousClassScoreDocComparator2(index);
+ return new AnonymousClassScoreDocComparator4(index);
}
/// <summary> Returns a comparator for sorting hits according to a field containing strings.</summary>
@@ -418,12 +538,12 @@
/// <returns> Comparator for sorting hits.
/// </returns>
/// <throws> IOException If an error occurs reading the index. </throws>
- internal static ScoreDocComparator comparatorStringLocale(IndexReader reader, System.String fieldname, System.Globalization.CultureInfo locale)
+ internal static ScoreDocComparator ComparatorStringLocale(IndexReader reader, System.String fieldname, System.Globalization.CultureInfo locale)
{
System.Globalization.CompareInfo collator = locale.CompareInfo;
System.String field = String.Intern(fieldname);
System.String[] index = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetStrings(reader, field);
- return new AnonymousClassScoreDocComparator3(index, collator);
+ return new AnonymousClassScoreDocComparator5(index, collator);
}
/// <summary> Returns a comparator for sorting hits according to values in the given field.
@@ -441,22 +561,26 @@
internal static ScoreDocComparator ComparatorAuto(IndexReader reader, System.String fieldname)
{
System.String field = String.Intern(fieldname);
- System.Object lookupArray = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetAuto(reader, field);
+ System.Object lookupArray = Lucene.Net.Search.ExtendedFieldCache_Fields.EXT_DEFAULT.GetAuto(reader, field);
if (lookupArray is Lucene.Net.Search.StringIndex)
{
- return comparatorString(reader, field);
+ return ComparatorString(reader, field);
}
else if (lookupArray is int[])
{
- return comparatorInt(reader, field);
+ return ComparatorInt(reader, field);
+ }
+ else if (lookupArray is long[])
+ {
+ return ComparatorLong(reader, field);
}
else if (lookupArray is float[])
{
- return comparatorFloat(reader, field);
+ return ComparatorFloat(reader, field);
}
else if (lookupArray is System.String[])
{
- return comparatorString(reader, field);
+ return ComparatorString(reader, field);
}
else
{
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilterManager.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FilterManager.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilterManager.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilterManager.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace Lucene.Net.Search
+{
+
+ /// <summary> Filter caching singleton. It can be used by {@link Lucene.Net.Search.RemoteCachingWrapperFilter}
+ /// or just to save filters locally for reuse.
+ /// This class makes it possble to cache Filters even when using RMI, as it
+ /// keeps the cache on the seaercher side of the RMI connection.
+ ///
+ /// Also could be used as a persistent storage for any filter as long as the
+ /// filter provides a proper hashCode(), as that is used as the key in the cache.
+ ///
+ /// The cache is periodically cleaned up from a separate thread to ensure the
+ /// cache doesn't exceed the maximum size.
+ /// </summary>
+ /// <author> Matt Ericson
+ /// </author>
+ public class FilterManager
+ {
+
+ protected internal static FilterManager manager;
+
+ /// <summary>The default maximum number of Filters in the cache </summary>
+ protected internal const int DEFAULT_CACHE_CLEAN_SIZE = 100;
+ /// <summary>The default frequency of cache clenup </summary>
+ protected internal const long DEFAULT_CACHE_SLEEP_TIME = 1000 * 60 * 10;
+
+ /// <summary>The cache itself </summary>
+ protected internal System.Collections.IDictionary cache;
+ /// <summary>Maximum allowed cache size </summary>
+ protected internal int cacheCleanSize;
+ /// <summary>Cache cleaning frequency </summary>
+ protected internal long cleanSleepTime;
+ /// <summary>Cache cleaner that runs in a separate thread </summary>
+ protected internal FilterCleaner filterCleaner;
+
+ public static FilterManager GetInstance()
+ {
+ lock (typeof(Lucene.Net.Search.FilterManager))
+ {
+ if (manager == null)
+ {
+ manager = new FilterManager();
+ }
+ return manager;
+ }
+ }
+
+ /// <summary> Sets up the FilterManager singleton.</summary>
+ protected internal FilterManager()
+ {
+ cache = new System.Collections.Hashtable();
+ cacheCleanSize = DEFAULT_CACHE_CLEAN_SIZE; // Let the cache get to 100 items
+ cleanSleepTime = DEFAULT_CACHE_SLEEP_TIME; // 10 minutes between cleanings
+
+ filterCleaner = new FilterCleaner(this);
+ SupportClass.ThreadClass fcThread = new SupportClass.ThreadClass(new System.Threading.ThreadStart(filterCleaner.Run));
+ // setto be a Daemon so it doesn't have to be stopped
+ fcThread.IsBackground = true;
+ fcThread.Start();
+ }
+
+ /// <summary> Sets the max size that cache should reach before it is cleaned up</summary>
+ /// <param name="cacheCleanSize">maximum allowed cache size
+ /// </param>
+ public virtual void SetCacheSize(int cacheCleanSize)
+ {
+ this.cacheCleanSize = cacheCleanSize;
+ }
+
+ /// <summary> Sets the cache cleaning frequency in milliseconds.</summary>
+ /// <param name="cleanSleepTime">cleaning frequency in millioseconds
+ /// </param>
+ public virtual void SetCleanThreadSleepTime(long cleanSleepTime)
+ {
+ this.cleanSleepTime = cleanSleepTime;
+ }
+
+ /// <summary> Returns the cached version of the filter. Allows the caller to pass up
+ /// a small filter but this will keep a persistent version around and allow
+ /// the caching filter to do its job.
+ ///
+ /// </summary>
+ /// <param name="filter">The input filter
+ /// </param>
+ /// <returns> The cached version of the filter
+ /// </returns>
+ public virtual Filter GetFilter(Filter filter)
+ {
+ lock (cache.SyncRoot)
+ {
+ FilterItem fi = null;
+ fi = (FilterItem) cache[(System.Int32) filter.GetHashCode()];
+ if (fi != null)
+ {
+ fi.timestamp = System.DateTime.Now.Millisecond; // {{Aroush-2.3.1}} do we want Millisecond or Ticks here?
+ return fi.filter;
+ }
+ cache[(System.Int32) filter.GetHashCode()] = new FilterItem(this, filter);
+ return filter;
+ }
+ }
+
+ /// <summary> Holds the filter and the last time the filter was used, to make LRU-based
+ /// cache cleaning possible.
+ /// TODO: Clean this up when we switch to Java 1.5
+ /// </summary>
+ protected internal class FilterItem
+ {
+ private void InitBlock(FilterManager enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private FilterManager enclosingInstance;
+ public FilterManager Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ public Filter filter;
+ public long timestamp;
+
+ public FilterItem(FilterManager enclosingInstance, Filter filter)
+ {
+ InitBlock(enclosingInstance);
+ this.filter = filter;
+ this.timestamp = System.DateTime.Now.Millisecond; // {{Aroush-2.3.1}} do we want Millisecond or Ticks here?
+ }
+ }
+
+
+ /// <summary> Keeps the cache from getting too big.
+ /// If we were using Java 1.5, we could use LinkedHashMap and we would not need this thread
+ /// to clean out the cache.
+ ///
+ /// The SortedSet sortedFilterItems is used only to sort the items from the cache,
+ /// so when it's time to clean up we have the TreeSet sort the FilterItems by
+ /// timestamp.
+ ///
+ /// Removes 1.5 * the numbers of items to make the cache smaller.
+ /// For example:
+ /// If cache clean size is 10, and the cache is at 15, we would remove (15 - 10) * 1.5 = 7.5 round up to 8.
+ /// This way we clean the cache a bit more, and avoid having the cache cleaner having to do it frequently.
+ /// </summary>
+ protected internal class FilterCleaner : IThreadRunnable
+ {
+ private class AnonymousClassComparator : System.Collections.Generic.IComparer<Object>
+ {
+ public AnonymousClassComparator(FilterCleaner enclosingInstance)
+ {
+ InitBlock(enclosingInstance);
+ }
+ private void InitBlock(FilterCleaner enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private FilterCleaner enclosingInstance;
+ public FilterCleaner Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ public virtual int Compare(System.Object a, System.Object b)
+ {
+ if (a is System.Collections.DictionaryEntry && b is System.Collections.DictionaryEntry)
+ {
+ FilterItem fia = (FilterItem) ((System.Collections.DictionaryEntry) a).Value;
+ FilterItem fib = (FilterItem) ((System.Collections.DictionaryEntry) b).Value;
+ if (fia.timestamp == fib.timestamp)
+ {
+ return 0;
+ }
+ // smaller timestamp first
+ if (fia.timestamp < fib.timestamp)
+ {
+ return - 1;
+ }
+ // larger timestamp last
+ return 1;
+ }
+ else
+ {
+ throw new System.InvalidCastException("Objects are not Map.Entry");
+ }
+ }
+ }
+ private void InitBlock(FilterManager enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private FilterManager enclosingInstance;
+ public FilterManager Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+
+ private bool running = true;
+ System.Collections.Generic.SortedDictionary<Object, Object> sortedFilterItems;
+
+ public FilterCleaner(FilterManager enclosingInstance)
+ {
+ InitBlock(enclosingInstance);
+ sortedFilterItems = new System.Collections.Generic.SortedDictionary<Object, Object>(new AnonymousClassComparator(this));
+ }
+
+ public virtual void Run()
+ {
+ while (running)
+ {
+
+ // sort items from oldest to newest
+ // we delete the oldest filters
+ if (Enclosing_Instance.cache.Count > Enclosing_Instance.cacheCleanSize)
+ {
+ // empty the temporary set
+ sortedFilterItems.Clear();
+ lock (Enclosing_Instance.cache.SyncRoot)
+ {
+ System.Collections.IDictionaryEnumerator entries = Enclosing_Instance.cache.GetEnumerator();
+ while (entries.MoveNext())
+ {
+ sortedFilterItems.Add(entries.Entry.Key, entries.Entry.Value);
+ }
+ System.Collections.IEnumerator it = sortedFilterItems.GetEnumerator();
+ int numToDelete = (int) ((Enclosing_Instance.cache.Count - Enclosing_Instance.cacheCleanSize) * 1.5);
+ int counter = 0;
+ // loop over the set and delete all of the cache entries not used in a while
+ while (it.MoveNext() && counter++ < numToDelete)
+ {
+ System.Collections.DictionaryEntry entry = (System.Collections.DictionaryEntry) it.Current;
+ Enclosing_Instance.cache.Remove(entry.Key);
+ }
+ }
+ // empty the set so we don't tie up the memory
+ sortedFilterItems.Clear();
+ }
+ // take a nap
+ try
+ {
+ System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * Enclosing_Instance.cleanSleepTime));
+ }
+ catch (System.Threading.ThreadInterruptedException e)
+ {
+ // just keep going
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/FilteredQuery.cs?rev=671402&r1=671401&r2=671402&view=diff
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs (original)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/FilteredQuery.cs Tue Jun 24 19:51:24 2008
@@ -37,8 +37,8 @@
/// </author>
/// <since> 1.4
/// </since>
- /// <version> $Id: FilteredQuery.java 472959 2006-11-09 16:21:50Z yonik $
- /// </version>
+ /// <version> $Id: FilteredQuery.java 544254 2007-06-04 20:41:06Z doronc $
+ /// </version>
/// <seealso cref="CachingWrapperFilter">
/// </seealso>
[Serializable]
@@ -119,13 +119,15 @@
public override float Score()
{
- return scorer.Score();
+ return Enclosing_Instance.Enclosing_Instance.GetBoost() * scorer.Score();
}
// add an explanation about whether the document was filtered
public override Explanation Explain(int i)
{
Explanation exp = scorer.Explain(i);
+ exp.SetValue(Enclosing_Instance.Enclosing_Instance.GetBoost() * exp.GetValue());
+
if (bitset.Get(i))
exp.SetDescription("allowed by filter: " + exp.GetDescription());
else
@@ -150,23 +152,32 @@
}
}
+ private float value_Renamed;
// pass these methods through to enclosed query's weight
public virtual float GetValue()
{
- return weight.GetValue();
- }
+ return value_Renamed;
+ }
public virtual float SumOfSquaredWeights()
{
- return weight.SumOfSquaredWeights();
+ return weight.SumOfSquaredWeights() * Enclosing_Instance.GetBoost() * Enclosing_Instance.GetBoost();
}
public virtual void Normalize(float v)
{
weight.Normalize(v);
+ value_Renamed = weight.GetValue() * Enclosing_Instance.GetBoost();
}
public virtual Explanation Explain(IndexReader ir, int i)
{
Explanation inner = weight.Explain(ir, i);
+ if (Enclosing_Instance.GetBoost() != 1)
+ {
+ Explanation preBoost = inner;
+ inner = new Explanation(inner.GetValue() * Enclosing_Instance.GetBoost(), "product of:");
+ inner.AddDetail(new Explanation(Enclosing_Instance.GetBoost(), "boost"));
+ inner.AddDetail(preBoost);
+ }
Filter f = Enclosing_Instance.filter;
System.Collections.BitArray matches = f.Bits(ir);
if (matches.Get(i))
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/ByteFieldSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/ByteFieldSource.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/ByteFieldSource.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/ByteFieldSource.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using FieldCache = Lucene.Net.Search.FieldCache;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: obtains single byte field values from the
+ /// {@link Lucene.Net.Search.FieldCache FieldCache}
+ /// using <code>getBytes()</code> and makes those values
+ /// available as other numeric types, casting as needed.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ /// </summary>
+ /// <seealso cref="Lucene.Net.Search.Function.FieldCacheSource for requirements">
+ /// on the field.
+ /// </seealso>
+ [Serializable]
+ public class ByteFieldSource : FieldCacheSource
+ {
+ private class AnonymousClassDocValues : DocValues
+ {
+ public AnonymousClassDocValues(byte[] arr, ByteFieldSource enclosingInstance)
+ {
+ InitBlock(arr, enclosingInstance);
+ }
+ private void InitBlock(byte[] arr, ByteFieldSource enclosingInstance)
+ {
+ this.arr = arr;
+ this.enclosingInstance = enclosingInstance;
+ }
+ private byte[] arr;
+ private ByteFieldSource enclosingInstance;
+ public ByteFieldSource Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#floatVal(int) */
+ public override float FloatVal(int doc)
+ {
+ return (float) arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#intVal(int) */
+ public override int IntVal(int doc)
+ {
+ return arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#toString(int) */
+ public override System.String ToString(int doc)
+ {
+ return Enclosing_Instance.Description() + '=' + IntVal(doc);
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#getInnerArray() */
+ internal override System.Object GetInnerArray()
+ {
+ return arr;
+ }
+ }
+ private Lucene.Net.Search.ByteParser parser;
+
+ /// <summary> Create a cached byte field source with default string-to-byte parser. </summary>
+ public ByteFieldSource(System.String field):this(field, null)
+ {
+ }
+
+ /// <summary> Create a cached byte field source with a specific string-to-byte parser. </summary>
+ public ByteFieldSource(System.String field, Lucene.Net.Search.ByteParser parser):base(field)
+ {
+ this.parser = parser;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#description() */
+ public override System.String Description()
+ {
+ return "byte(" + base.Description() + ')';
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#getCachedValues(Lucene.Net.Search.FieldCache, java.lang.String, Lucene.Net.Index.IndexReader) */
+ public override DocValues GetCachedFieldValues(FieldCache cache, System.String field, IndexReader reader)
+ {
+ byte[] arr = (parser == null) ? cache.GetBytes(reader, field) : cache.GetBytes(reader, field, parser);
+ return new AnonymousClassDocValues(arr, this);
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceEquals(Lucene.Net.Search.Function.FieldCacheSource) */
+ public override bool CachedFieldSourceEquals(FieldCacheSource o)
+ {
+ if (o.GetType() != typeof(ByteFieldSource))
+ {
+ return false;
+ }
+ ByteFieldSource other = (ByteFieldSource) o;
+ return this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType();
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceHashCode() */
+ public override int CachedFieldSourceHashCode()
+ {
+ return parser == null ? typeof(System.SByte).GetHashCode() : parser.GetType().GetHashCode();
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/CustomScoreQuery.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/CustomScoreQuery.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,555 @@
+/*
+ * 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.
+ */
+
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using ToStringUtils = Lucene.Net.Util.ToStringUtils;
+using ComplexExplanation = Lucene.Net.Search.ComplexExplanation;
+using Explanation = Lucene.Net.Search.Explanation;
+using Query = Lucene.Net.Search.Query;
+using Scorer = Lucene.Net.Search.Scorer;
+using Searcher = Lucene.Net.Search.Searcher;
+using Similarity = Lucene.Net.Search.Similarity;
+using Weight = Lucene.Net.Search.Weight;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Query that sets document score as a programmatic function of several (sub) scores.
+ /// <ol>
+ /// <li>the score of its subQuery (any query)</li>
+ /// <li>(optional) the score of its ValueSourtceQuery (or queries),
+ /// for most simple/convineient use case this query would be a
+ /// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQuery}</li>
+ /// </ol>
+ /// Subclasses can modify the computation by overriding {@link #CustomScore(int, float, float)}.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ /// </summary>
+ [Serializable]
+ public class CustomScoreQuery : Query, System.ICloneable
+ {
+
+ private Query subQuery;
+ private ValueSourceQuery[] valSrcQueries; // never null (empty array if there are no valSrcQueries).
+ private bool strict = false; // if true, valueSource part of query does not take part in weights normalization.
+
+ /// <summary> Create a CustomScoreQuery over input subQuery.</summary>
+ /// <param name="subQuery">the sub query whose scored is being customed. Must not be null.
+ /// </param>
+ public CustomScoreQuery(Query subQuery) : this(subQuery, new ValueSourceQuery[0])
+ {
+ }
+
+ /// <summary> Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}.</summary>
+ /// <param name="subQuery">the sub query whose score is being customed. Must not be null.
+ /// </param>
+ /// <param name="valSrcQuery">a value source query whose scores are used in the custom score
+ /// computation. For most simple/convineient use case this would be a
+ /// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQuery}.
+ /// This parameter is optional - it can be null.
+ /// </param>
+ public CustomScoreQuery(Query subQuery, ValueSourceQuery valSrcQuery) : this(subQuery, valSrcQuery != null ? new ValueSourceQuery[]{valSrcQuery} : new ValueSourceQuery[0])
+ {
+ }
+
+ /// <summary> Create a CustomScoreQuery over input subQuery and a {@link ValueSourceQuery}.</summary>
+ /// <param name="subQuery">the sub query whose score is being customed. Must not be null.
+ /// </param>
+ /// <param name="valSrcQueries">value source queries whose scores are used in the custom score
+ /// computation. For most simple/convineient use case these would be
+ /// {@link Lucene.Net.Search.Function.FieldScoreQuery FieldScoreQueries}.
+ /// This parameter is optional - it can be null or even an empty array.
+ /// </param>
+ public CustomScoreQuery(Query subQuery, ValueSourceQuery[] valSrcQueries) : base()
+ {
+ this.subQuery = subQuery;
+ this.valSrcQueries = valSrcQueries != null ? valSrcQueries : new ValueSourceQuery[0];
+ if (subQuery == null)
+ throw new System.ArgumentException("<subquery> must not be null!");
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Query#rewrite(Lucene.Net.Index.IndexReader) */
+ public override Query Rewrite(IndexReader reader)
+ {
+ subQuery = subQuery.Rewrite(reader);
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ valSrcQueries[i] = (ValueSourceQuery) valSrcQueries[i].Rewrite(reader);
+ }
+ return this;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Query#extractTerms(java.util.Set) */
+ public override void ExtractTerms(System.Collections.Hashtable terms)
+ {
+ subQuery.ExtractTerms(terms);
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ valSrcQueries[i].ExtractTerms(terms);
+ }
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Query#clone() */
+ public override System.Object Clone()
+ {
+ CustomScoreQuery clone = (CustomScoreQuery) base.Clone();
+ clone.subQuery = (Query) subQuery.Clone();
+ clone.valSrcQueries = new ValueSourceQuery[valSrcQueries.Length];
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ clone.valSrcQueries[i] = (ValueSourceQuery) valSrcQueries[i].Clone();
+ }
+ return clone;
+ }
+
+ /* (non-Javadoc) @see Lucene.Net.Search.Query#toString(java.lang.String) */
+ public override System.String ToString(System.String field)
+ {
+ System.Text.StringBuilder sb = new System.Text.StringBuilder(Name()).Append("(");
+ sb.Append(subQuery.ToString(field));
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ sb.Append(", ").Append(valSrcQueries[i].ToString(field));
+ }
+ sb.Append(")");
+ sb.Append(strict ? " STRICT" : "");
+ return sb.ToString() + ToStringUtils.Boost(GetBoost());
+ }
+
+ /// <summary>Returns true if <code>o</code> is equal to this. </summary>
+ public override bool Equals(System.Object o)
+ {
+ if (GetType() != o.GetType())
+ {
+ return false;
+ }
+ CustomScoreQuery other = (CustomScoreQuery) o;
+ if (this.GetBoost() != other.GetBoost() || !this.subQuery.Equals(other.subQuery) || this.valSrcQueries.Length != other.valSrcQueries.Length)
+ {
+ return false;
+ }
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ //TODO simplify with Arrays.deepEquals() once moving to Java 1.5
+ if (!valSrcQueries[i].Equals(other.valSrcQueries[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// <summary>Returns a hash code value for this object. </summary>
+ public override int GetHashCode()
+ {
+ int valSrcHash = 0;
+ for (int i = 0; i < valSrcQueries.Length; i++)
+ {
+ //TODO simplify with Arrays.deepHashcode() once moving to Java 1.5
+ valSrcHash += valSrcQueries[i].GetHashCode();
+ }
+ return (GetType().GetHashCode() + subQuery.GetHashCode() + valSrcHash) ^ BitConverter.ToInt32(BitConverter.GetBytes(GetBoost()), 0);
+ }
+
+ /// <summary> Compute a custom score by the subQuery score and a number of
+ /// ValueSourceQuery scores.
+ /// <p>
+ /// Subclasses can override this method to modify the custom score.
+ /// <p>
+ /// If your custom scoring is different than the default herein you
+ /// should override at least one of the two customScore() methods.
+ /// If the number of ValueSourceQueries is always < 2 it is
+ /// sufficient to override the other
+ /// {@link #CustomScore(int, float, float) costomScore()}
+ /// method, which is simpler.
+ /// <p>
+ /// The default computation herein is:
+ /// <pre>
+ /// ModifiedScore = valSrcScore * subQueryScore[0] * subQueryScore[1] * ...
+ /// </pre>
+ ///
+ /// </summary>
+ /// <param name="doc">id of scored doc.
+ /// </param>
+ /// <param name="subQueryScore">score of that doc by the subQuery.
+ /// </param>
+ /// <param name="valSrcScores">score of that doc by the ValueSourceQuery.
+ /// </param>
+ /// <returns> custom score.
+ /// </returns>
+ public virtual float CustomScore(int doc, float subQueryScore, float[] valSrcScores)
+ {
+ if (valSrcScores.Length == 1)
+ {
+ return CustomScore(doc, subQueryScore, valSrcScores[0]);
+ }
+ if (valSrcScores.Length == 0)
+ {
+ return CustomScore(doc, subQueryScore, 1);
+ }
+ float score = subQueryScore;
+ for (int i = 0; i < valSrcScores.Length; i++)
+ {
+ score *= valSrcScores[i];
+ }
+ return score;
+ }
+
+ /// <summary> Compute a custom score by the subQuery score and the ValueSourceQuery score.
+ /// <p>
+ /// Subclasses can override this method to modify the custom score.
+ /// <p>
+ /// If your custom scoring is different than the default herein you
+ /// should override at least one of the two customScore() methods.
+ /// If the number of ValueSourceQueries is always < 2 it is
+ /// sufficient to override this costomScore() method, which is simpler.
+ /// <p>
+ /// The default computation herein is:
+ /// <pre>
+ /// ModifiedScore = valSrcScore * subQueryScore
+ /// </pre>
+ ///
+ /// </summary>
+ /// <param name="doc">id of scored doc.
+ /// </param>
+ /// <param name="subQueryScore">score of that doc by the subQuery.
+ /// </param>
+ /// <param name="valSrcScore">score of that doc by the ValueSourceQuery.
+ /// </param>
+ /// <returns> custom score.
+ /// </returns>
+ public virtual float CustomScore(int doc, float subQueryScore, float valSrcScore)
+ {
+ return subQueryScore * valSrcScore;
+ }
+
+ /// <summary> Explain the custom score.
+ /// Whenever overriding {@link #CustomScore(int, float, float[])},
+ /// this method should also be overridden to provide the correct explanation
+ /// for the part of the custom scoring.
+ ///
+ /// </summary>
+ /// <param name="doc">doc being explained.
+ /// </param>
+ /// <param name="subQueryExpl">explanation for the sub-query part.
+ /// </param>
+ /// <param name="valSrcExpls">explanation for the value source part.
+ /// </param>
+ /// <returns> an explanation for the custom score
+ /// </returns>
+ public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[] valSrcExpls)
+ {
+ if (valSrcExpls.Length == 1)
+ {
+ return CustomExplain(doc, subQueryExpl, valSrcExpls[0]);
+ }
+ if (valSrcExpls.Length == 0)
+ {
+ return subQueryExpl;
+ }
+ float valSrcScore = 1;
+ for (int i = 0; i < valSrcExpls.Length; i++)
+ {
+ valSrcScore *= valSrcExpls[i].GetValue();
+ }
+ Explanation exp = new Explanation(valSrcScore * subQueryExpl.GetValue(), "custom score: product of:");
+ exp.AddDetail(subQueryExpl);
+ for (int i = 0; i < valSrcExpls.Length; i++)
+ {
+ exp.AddDetail(valSrcExpls[i]);
+ }
+ return exp;
+ }
+
+ /// <summary> Explain the custom score.
+ /// Whenever overriding {@link #CustomScore(int, float, float)},
+ /// this method should also be overridden to provide the correct explanation
+ /// for the part of the custom scoring.
+ ///
+ /// </summary>
+ /// <param name="doc">doc being explained.
+ /// </param>
+ /// <param name="subQueryExpl">explanation for the sub-query part.
+ /// </param>
+ /// <param name="valSrcExpl">explanation for the value source part.
+ /// </param>
+ /// <returns> an explanation for the custom score
+ /// </returns>
+ public virtual Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl)
+ {
+ float valSrcScore = 1;
+ if (valSrcExpl != null)
+ {
+ valSrcScore *= valSrcExpl.GetValue();
+ }
+ Explanation exp = new Explanation(valSrcScore * subQueryExpl.GetValue(), "custom score: product of:");
+ exp.AddDetail(subQueryExpl);
+ exp.AddDetail(valSrcExpl);
+ return exp;
+ }
+
+ //=========================== W E I G H T ============================
+
+ [Serializable]
+ private class CustomWeight : Weight
+ {
+ private void InitBlock(CustomScoreQuery enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private CustomScoreQuery enclosingInstance;
+ public CustomScoreQuery Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ internal Similarity similarity;
+ internal Weight subQueryWeight;
+ internal Weight[] valSrcWeights;
+ internal bool qStrict;
+
+ public CustomWeight(CustomScoreQuery enclosingInstance, Searcher searcher)
+ {
+ InitBlock(enclosingInstance);
+ this.similarity = Enclosing_Instance.GetSimilarity(searcher);
+ this.subQueryWeight = Enclosing_Instance.subQuery.Weight(searcher);
+ this.subQueryWeight = Enclosing_Instance.subQuery.Weight(searcher);
+ this.valSrcWeights = new Weight[Enclosing_Instance.valSrcQueries.Length];
+ for (int i = 0; i < Enclosing_Instance.valSrcQueries.Length; i++)
+ {
+ this.valSrcWeights[i] = Enclosing_Instance.valSrcQueries[i].CreateWeight(searcher);
+ }
+ this.qStrict = Enclosing_Instance.strict;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#getQuery() */
+ public virtual Query GetQuery()
+ {
+ return Enclosing_Instance;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#getValue() */
+ public virtual float GetValue()
+ {
+ return Enclosing_Instance.GetBoost();
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#sumOfSquaredWeights() */
+ public virtual float SumOfSquaredWeights()
+ {
+ float sum = subQueryWeight.SumOfSquaredWeights();
+ for (int i = 0; i < valSrcWeights.Length; i++)
+ {
+ if (qStrict)
+ {
+ valSrcWeights[i].SumOfSquaredWeights(); // do not include ValueSource part in the query normalization
+ }
+ else
+ {
+ sum += valSrcWeights[i].SumOfSquaredWeights();
+ }
+ }
+ sum *= Enclosing_Instance.GetBoost() * Enclosing_Instance.GetBoost(); // boost each sub-weight
+ return sum;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#normalize(float) */
+ public virtual void Normalize(float norm)
+ {
+ norm *= Enclosing_Instance.GetBoost(); // incorporate boost
+ subQueryWeight.Normalize(norm);
+ for (int i = 0; i < valSrcWeights.Length; i++)
+ {
+ if (qStrict)
+ {
+ valSrcWeights[i].Normalize(1); // do not normalize the ValueSource part
+ }
+ else
+ {
+ valSrcWeights[i].Normalize(norm);
+ }
+ }
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#scorer(Lucene.Net.Index.IndexReader) */
+ public virtual Scorer Scorer(IndexReader reader)
+ {
+ Scorer subQueryScorer = subQueryWeight.Scorer(reader);
+ Scorer[] valSrcScorers = new Scorer[valSrcWeights.Length];
+ for (int i = 0; i < valSrcScorers.Length; i++)
+ {
+ valSrcScorers[i] = valSrcWeights[i].Scorer(reader);
+ }
+ return new CustomScorer(enclosingInstance, similarity, reader, this, subQueryScorer, valSrcScorers);
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Weight#explain(Lucene.Net.Index.IndexReader, int) */
+ public virtual Explanation Explain(IndexReader reader, int doc)
+ {
+ return Scorer(reader).Explain(doc);
+ }
+ }
+
+
+ //=========================== S C O R E R ============================
+
+ /// <summary> A scorer that applies a (callback) function on scores of the subQuery.</summary>
+ private class CustomScorer : Scorer
+ {
+ private void InitBlock(CustomScoreQuery enclosingInstance)
+ {
+ this.enclosingInstance = enclosingInstance;
+ }
+ private CustomScoreQuery enclosingInstance;
+ public CustomScoreQuery Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ private CustomWeight weight;
+ private float qWeight;
+ private Scorer subQueryScorer;
+ private Scorer[] valSrcScorers;
+ private IndexReader reader;
+ private float[] vScores; // reused in score() to avoid allocating this array for each doc
+
+ // constructor
+ internal CustomScorer(CustomScoreQuery enclosingInstance, Similarity similarity, IndexReader reader, CustomWeight w, Scorer subQueryScorer, Scorer[] valSrcScorers) : base(similarity)
+ {
+ InitBlock(enclosingInstance);
+ this.weight = w;
+ this.qWeight = w.GetValue();
+ this.subQueryScorer = subQueryScorer;
+ this.valSrcScorers = valSrcScorers;
+ this.reader = reader;
+ this.vScores = new float[valSrcScorers.Length];
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Scorer#next() */
+ public override bool Next()
+ {
+ bool hasNext = subQueryScorer.Next();
+ if (hasNext)
+ {
+ for (int i = 0; i < valSrcScorers.Length; i++)
+ {
+ valSrcScorers[i].SkipTo(subQueryScorer.Doc());
+ }
+ }
+ return hasNext;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Scorer#doc() */
+ public override int Doc()
+ {
+ return subQueryScorer.Doc();
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Scorer#score() */
+ public override float Score()
+ {
+ for (int i = 0; i < valSrcScorers.Length; i++)
+ {
+ vScores[i] = valSrcScorers[i].Score();
+ }
+ return qWeight * Enclosing_Instance.CustomScore(subQueryScorer.Doc(), subQueryScorer.Score(), vScores);
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Scorer#skipTo(int) */
+ public override bool SkipTo(int target)
+ {
+ bool hasNext = subQueryScorer.SkipTo(target);
+ if (hasNext)
+ {
+ for (int i = 0; i < valSrcScorers.Length; i++)
+ {
+ valSrcScorers[i].SkipTo(subQueryScorer.Doc());
+ }
+ }
+ return hasNext;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Scorer#explain(int) */
+ public override Explanation Explain(int doc)
+ {
+ Explanation subQueryExpl = weight.subQueryWeight.Explain(reader, doc);
+ if (!subQueryExpl.IsMatch())
+ {
+ return subQueryExpl;
+ }
+ // match
+ Explanation[] valSrcExpls = new Explanation[valSrcScorers.Length];
+ for (int i = 0; i < valSrcScorers.Length; i++)
+ {
+ valSrcExpls[i] = valSrcScorers[i].Explain(doc);
+ }
+ Explanation customExp = Enclosing_Instance.CustomExplain(doc, subQueryExpl, valSrcExpls);
+ float sc = qWeight * customExp.GetValue();
+ Explanation res = new ComplexExplanation(true, sc, Enclosing_Instance.ToString() + ", product of:");
+ res.AddDetail(customExp);
+ res.AddDetail(new Explanation(qWeight, "queryBoost")); // actually using the q boost as q weight (== weight value)
+ return res;
+ }
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Query#createWeight(Lucene.Net.Search.Searcher) */
+ protected internal override Weight CreateWeight(Searcher searcher)
+ {
+ return new CustomWeight(this, searcher);
+ }
+
+ /// <summary> Checks if this is strict custom scoring.
+ /// In strict custom scoring, the ValueSource part of does not participate in weight normalization.
+ /// This may be useful when one wants full control over how scores are modified, and does
+ /// not care about normalizing by the ValueSource part.
+ /// One particular case where this is useful if for testing this query.
+ /// <P>
+ /// Note: only has effect when the ValueSource part is not null.
+ /// </summary>
+ public virtual bool IsStrict()
+ {
+ return strict;
+ }
+
+ /// <summary> Set the strict mode of this query. </summary>
+ /// <param name="strict">The strict mode to set.
+ /// </param>
+ /// <seealso cref="IsStrict()">
+ /// </seealso>
+ public virtual void SetStrict(bool strict)
+ {
+ this.strict = strict;
+ }
+
+ /// <summary> A short name of this query, used in {@link #ToString(String)}.</summary>
+ public virtual System.String Name()
+ {
+ return "custom";
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/DocValues.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/DocValues.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/DocValues.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/DocValues.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+using System;
+
+using Explanation = Lucene.Net.Search.Explanation;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: represents field values as different types.
+ /// Normally created via a
+ /// {@link Lucene.Net.Search.Function.ValueSource ValueSuorce}
+ /// for a particular field and reader.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ ///
+ /// </summary>
+ public abstract class DocValues
+ {
+ /*
+ * DocValues is distinct from ValueSource because
+ * there needs to be an object created at query evaluation time that
+ * is not referenced by the query itself because:
+ * - Query objects should be MT safe
+ * - For caching, Query objects are often used as keys... you don't
+ * want the Query carrying around big objects
+ */
+
+ /// <summary> Return doc value as a float.
+ /// <P>Mandatory: every DocValues implementation must implement at least this method.
+ /// </summary>
+ /// <param name="doc">document whose float value is requested.
+ /// </param>
+ public abstract float FloatVal(int doc);
+
+ /// <summary> Return doc value as an int.
+ /// <P>Optional: DocValues implementation can (but don't have to) override this method.
+ /// </summary>
+ /// <param name="doc">document whose int value is requested.
+ /// </param>
+ public virtual int IntVal(int doc)
+ {
+ return (int) FloatVal(doc);
+ }
+
+ /// <summary> Return doc value as a long.
+ /// <P>Optional: DocValues implementation can (but don't have to) override this method.
+ /// </summary>
+ /// <param name="doc">document whose long value is requested.
+ /// </param>
+ public virtual long LongVal(int doc)
+ {
+ return (long) FloatVal(doc);
+ }
+
+ /// <summary> Return doc value as a double.
+ /// <P>Optional: DocValues implementation can (but don't have to) override this method.
+ /// </summary>
+ /// <param name="doc">document whose double value is requested.
+ /// </param>
+ public virtual double DoubleVal(int doc)
+ {
+ return (double) FloatVal(doc);
+ }
+
+ /// <summary> Return doc value as a string.
+ /// <P>Optional: DocValues implementation can (but don't have to) override this method.
+ /// </summary>
+ /// <param name="doc">document whose string value is requested.
+ /// </param>
+ public virtual System.String StrVal(int doc)
+ {
+ return FloatVal(doc).ToString();
+ }
+
+ /// <summary> Return a string representation of a doc value, as reuired for Explanations.</summary>
+ public abstract System.String ToString(int doc);
+
+ /// <summary> Explain the scoring value for the input doc.</summary>
+ public virtual Explanation Explain(int doc)
+ {
+ return new Explanation(FloatVal(doc), ToString(doc));
+ }
+
+ /// <summary> Expert: for test purposes only, return the inner array of values, or null if not applicable.
+ /// <p>
+ /// Allows tests to verify that loaded values are:
+ /// <ol>
+ /// <li>indeed cached/reused.</li>
+ /// <li>stored in the expected size/type (byte/short/int/float).</li>
+ /// </ol>
+ /// Note: implementations of DocValues must override this method for
+ /// these test elements to be tested, Otherwise the test would not fail, just
+ /// print a warning.
+ /// </summary>
+ internal virtual System.Object GetInnerArray()
+ {
+ throw new System.NotSupportedException("this optional method is for test purposes only");
+ }
+
+ // --- some simple statistics on values
+ private float minVal;
+ private float maxVal;
+ private float avgVal;
+ private bool computed = false;
+ // compute optional values
+ private void Compute()
+ {
+ if (computed)
+ {
+ return ;
+ }
+ minVal = System.Single.MaxValue;
+ maxVal = 0;
+ float sum = 0;
+ int n = 0;
+ while (true)
+ {
+ float val;
+ try
+ {
+ val = FloatVal(n);
+ }
+ catch (System.IndexOutOfRangeException e)
+ {
+ break;
+ }
+ sum += val;
+ minVal = System.Math.Min(minVal, val);
+ maxVal = System.Math.Max(maxVal, val);
+ }
+ avgVal = sum / n;
+ computed = true;
+ }
+ /// <summary> Optional op.
+ /// Returns the minimum of all values.
+ /// </summary>
+ public virtual float GetMinValue()
+ {
+ Compute();
+ return minVal;
+ }
+
+ /// <summary> Optional op.
+ /// Returns the maximum of all values.
+ /// </summary>
+ public virtual float GetMaxValue()
+ {
+ Compute();
+ return maxVal;
+ }
+
+ /// <summary> Returns the average of all values. </summary>
+ public virtual float GetAverageValue()
+ {
+ Compute();
+ return avgVal;
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldCacheSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/FieldCacheSource.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldCacheSource.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldCacheSource.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using FieldCache = Lucene.Net.Search.FieldCache;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: A base class for ValueSource implementations that retrieve values for
+ /// a single field from the {@link Lucene.Net.Search.FieldCache FieldCache}.
+ /// <p>
+ /// Fields used herein nust be indexed (doesn't matter if these fields are stored or not).
+ /// <p>
+ /// It is assumed that each such indexed field is untokenized, or at least has a single token in a document.
+ /// For documents with multiple tokens of the same field, behavior is undefined (It is likely that current
+ /// code would use the value of one of these tokens, but this is not guaranteed).
+ /// <p>
+ /// Document with no tokens in this field are assigned the <code>Zero</code> value.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ /// </summary>
+ /// <author> yonik
+ /// </author>
+ [Serializable]
+ public abstract class FieldCacheSource : ValueSource
+ {
+ private System.String field;
+
+ /// <summary> Create a cached field source for the input field. </summary>
+ public FieldCacheSource(System.String field)
+ {
+ this.field = field;
+ }
+
+ /* (non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#getValues(Lucene.Net.Index.IndexReader) */
+ public override DocValues GetValues(IndexReader reader)
+ {
+ return GetCachedFieldValues(Lucene.Net.Search.FieldCache_Fields.DEFAULT, field, reader);
+ }
+
+ /* (non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#description() */
+ public override System.String Description()
+ {
+ return field;
+ }
+
+ /// <summary> Return cached DocValues for input field and reader.</summary>
+ /// <param name="cache">FieldCache so that values of a field are loaded once per reader (RAM allowing)
+ /// </param>
+ /// <param name="field">Field for which values are required.
+ /// </param>
+ /// <seealso cref="ValueSource">
+ /// </seealso>
+ public abstract DocValues GetCachedFieldValues(FieldCache cache, System.String field, IndexReader reader);
+
+ /*(non-Javadoc) @see java.lang.Object#equals(java.lang.Object) */
+ public override bool Equals(System.Object o)
+ {
+ if (!(o is FieldCacheSource))
+ {
+ return false;
+ }
+ FieldCacheSource other = (FieldCacheSource) o;
+ return this.field.Equals(other.field) && CachedFieldSourceEquals(other);
+ }
+
+ /*(non-Javadoc) @see java.lang.Object#hashCode() */
+ public override int GetHashCode()
+ {
+ return field.GetHashCode() + CachedFieldSourceHashCode();
+ }
+
+ /// <summary> Check if equals to another {@link FieldCacheSource}, already knowing that cache and field are equal. </summary>
+ /// <seealso cref="Object.equals(java.lang.Object)">
+ /// </seealso>
+ public abstract bool CachedFieldSourceEquals(FieldCacheSource other);
+
+ /// <summary> Return a hash code of a {@link FieldCacheSource}, without the hash-codes of the field
+ /// and the cache (those are taken care of elsewhere).
+ /// </summary>
+ /// <seealso cref="Object.hashCode()">
+ /// </seealso>
+ public abstract int CachedFieldSourceHashCode();
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldScoreQuery.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/FieldScoreQuery.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldScoreQuery.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FieldScoreQuery.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+using System;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> A query that scores each document as the value of the numeric input field.
+ /// <p>
+ /// The query matches all documents, and scores each document according to the numeric
+ /// value of that field.
+ /// <p>
+ /// It is assumed, and expected, that:
+ /// <ul>
+ /// <li>The field used here is indexed, and has exactly
+ /// one token in every scored document.</li>
+ /// <li>Best if this field is un_tokenized.</li>
+ /// <li>That token is parsable to the selected type.</li>
+ /// </ul>
+ /// <p>
+ /// Combining this query in a FunctionQuery allows much freedom in affecting document scores.
+ /// Note, that with this freedom comes responsibility: it is more than likely that the
+ /// default Lucene scoring is superior in quality to scoring modified as explained here.
+ /// However, in some cases, and certainly for research experiments, this capability may turn useful.
+ /// <p>
+ /// When contructing this query, select the appropriate type. That type should match the data stored in the
+ /// field. So in fact the "right" type should be selected before indexing. Type selection
+ /// has effect on the RAM usage:
+ /// <ul>
+ /// <li>{@link Type#BYTE} consumes 1 * maxDocs bytes.</li>
+ /// <li>{@link Type#SHORT} consumes 2 * maxDocs bytes.</li>
+ /// <li>{@link Type#INT} consumes 4 * maxDocs bytes.</li>
+ /// <li>{@link Type#FLOAT} consumes 8 * maxDocs bytes.</li>
+ /// </ul>
+ /// <p>
+ /// <b>Caching:</b>
+ /// Values for the numeric field are loaded once and cached in memory for further use with the same IndexReader.
+ /// To take advantage of this, it is extremely important to reuse index-readers or index-searchers,
+ /// otherwise, for instance if for each query a new index reader is opened, large penalties would be
+ /// payd for loading the field values into memory over and over again!
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ /// </summary>
+ [Serializable]
+ public class FieldScoreQuery : ValueSourceQuery
+ {
+
+ /// <summary> Type of score field, indicating how field values are interpreted/parsed.
+ /// <p>
+ /// The type selected at search search time should match the data stored in the field.
+ /// Different types have different RAM requirements:
+ /// <ul>
+ /// <li>{@link #BYTE} consumes 1 * maxDocs bytes.</li>
+ /// <li>{@link #SHORT} consumes 2 * maxDocs bytes.</li>
+ /// <li>{@link #INT} consumes 4 * maxDocs bytes.</li>
+ /// <li>{@link #FLOAT} consumes 8 * maxDocs bytes.</li>
+ /// </ul>
+ /// </summary>
+ public class Type
+ {
+
+ /// <summary>field values are interpreted as numeric byte values. </summary>
+ public static readonly Type BYTE = new Type("byte");
+
+ /// <summary>field values are interpreted as numeric short values. </summary>
+ public static readonly Type SHORT = new Type("short");
+
+ /// <summary>field values are interpreted as numeric int values. </summary>
+ public static readonly Type INT = new Type("int");
+
+ /// <summary>field values are interpreted as numeric float values. </summary>
+ public static readonly Type FLOAT = new Type("float");
+
+ private System.String typeName;
+ internal Type(System.String name)
+ {
+ this.typeName = name;
+ }
+ /*(non-Javadoc) @see java.lang.Object#toString() */
+ public override System.String ToString()
+ {
+ return GetType().FullName + "::" + typeName;
+ }
+ }
+
+ /// <summary> Create a FieldScoreQuery - a query that scores each document as the value of the numeric input field.
+ /// <p>
+ /// The <code>type</code> param tells how to parse the field string values into a numeric score value.
+ /// </summary>
+ /// <param name="field">the numeric field to be used.
+ /// </param>
+ /// <param name="type">the type of the field: either
+ /// {@link Type#BYTE}, {@link Type#SHORT}, {@link Type#INT}, or {@link Type#FLOAT}.
+ /// </param>
+ public FieldScoreQuery(System.String field, Type type) : base(GetValueSource(field, type))
+ {
+ }
+
+ // create the appropriate (cached) field value source.
+ private static ValueSource GetValueSource(System.String field, Type type)
+ {
+ if (type == Type.BYTE)
+ {
+ return new ByteFieldSource(field);
+ }
+ if (type == Type.SHORT)
+ {
+ return new ShortFieldSource(field);
+ }
+ if (type == Type.INT)
+ {
+ return new IntFieldSource(field);
+ }
+ if (type == Type.FLOAT)
+ {
+ return new FloatFieldSource(field);
+ }
+ throw new System.ArgumentException(type + " is not a known Field Score Query Type!");
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FloatFieldSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/FloatFieldSource.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FloatFieldSource.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/FloatFieldSource.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using FieldCache = Lucene.Net.Search.FieldCache;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: obtains float field values from the
+ /// {@link Lucene.Net.Search.FieldCache FieldCache}
+ /// using <code>getFloats()</code> and makes those values
+ /// available as other numeric types, casting as needed.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ /// </summary>
+ /// <seealso cref="Lucene.Net.Search.Function.FieldCacheSource for requirements">
+ /// on the field.
+ ///
+ /// </seealso>
+ /// <author> yonik
+ /// </author>
+ [Serializable]
+ public class FloatFieldSource : FieldCacheSource
+ {
+ private class AnonymousClassDocValues : DocValues
+ {
+ public AnonymousClassDocValues(float[] arr, FloatFieldSource enclosingInstance)
+ {
+ InitBlock(arr, enclosingInstance);
+ }
+ private void InitBlock(float[] arr, FloatFieldSource enclosingInstance)
+ {
+ this.arr = arr;
+ this.enclosingInstance = enclosingInstance;
+ }
+ private float[] arr;
+ private FloatFieldSource enclosingInstance;
+ public FloatFieldSource Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#floatVal(int) */
+ public override float FloatVal(int doc)
+ {
+ return arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#toString(int) */
+ public override System.String ToString(int doc)
+ {
+ return Enclosing_Instance.Description() + '=' + arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#getInnerArray() */
+ internal override System.Object GetInnerArray()
+ {
+ return arr;
+ }
+ }
+ private Lucene.Net.Search.FloatParser parser;
+
+ /// <summary> Create a cached float field source with default string-to-float parser. </summary>
+ public FloatFieldSource(System.String field) : this(field, null)
+ {
+ }
+
+ /// <summary> Create a cached float field source with a specific string-to-float parser. </summary>
+ public FloatFieldSource(System.String field, Lucene.Net.Search.FloatParser parser) : base(field)
+ {
+ this.parser = parser;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#description() */
+ public override System.String Description()
+ {
+ return "float(" + base.Description() + ')';
+ }
+
+ public override DocValues GetCachedFieldValues(FieldCache cache, System.String field, IndexReader reader)
+ {
+ float[] arr = (parser == null) ? cache.GetFloats(reader, field) : cache.GetFloats(reader, field, parser);
+ return new AnonymousClassDocValues(arr, this);
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceEquals(Lucene.Net.Search.Function.FieldCacheSource) */
+ public override bool CachedFieldSourceEquals(FieldCacheSource o)
+ {
+ if (o.GetType() != typeof(FloatFieldSource))
+ {
+ return false;
+ }
+ FloatFieldSource other = (FloatFieldSource) o;
+ return this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType();
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceHashCode() */
+ public override int CachedFieldSourceHashCode()
+ {
+ return parser == null ? typeof(System.Single).GetHashCode() : parser.GetType().GetHashCode();
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/IntFieldSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/IntFieldSource.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/IntFieldSource.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/IntFieldSource.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,130 @@
+/*
+ * 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.
+ */
+
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using FieldCache = Lucene.Net.Search.FieldCache;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: obtains int field values from the
+ /// {@link Lucene.Net.Search.FieldCache FieldCache}
+ /// using <code>getInts()</code> and makes those values
+ /// available as other numeric types, casting as needed.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ /// </summary>
+ /// <seealso cref="Lucene.Net.Search.Function.FieldCacheSource for requirements">
+ /// on the field.
+ ///
+ ///
+ /// </seealso>
+ [Serializable]
+ public class IntFieldSource : FieldCacheSource
+ {
+ private class AnonymousClassDocValues : DocValues
+ {
+ public AnonymousClassDocValues(int[] arr, IntFieldSource enclosingInstance)
+ {
+ InitBlock(arr, enclosingInstance);
+ }
+ private void InitBlock(int[] arr, IntFieldSource enclosingInstance)
+ {
+ this.arr = arr;
+ this.enclosingInstance = enclosingInstance;
+ }
+ private int[] arr;
+ private IntFieldSource enclosingInstance;
+ public IntFieldSource Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#floatVal(int) */
+ public override float FloatVal(int doc)
+ {
+ return (float) arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#intVal(int) */
+ public override int IntVal(int doc)
+ {
+ return arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#toString(int) */
+ public override System.String ToString(int doc)
+ {
+ return Enclosing_Instance.Description() + '=' + IntVal(doc);
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#getInnerArray() */
+ internal override System.Object GetInnerArray()
+ {
+ return arr;
+ }
+ }
+ private Lucene.Net.Search.IntParser parser;
+
+ /// <summary> Create a cached int field source with default string-to-int parser. </summary>
+ public IntFieldSource(System.String field) : this(field, null)
+ {
+ }
+
+ /// <summary> Create a cached int field source with a specific string-to-int parser. </summary>
+ public IntFieldSource(System.String field, Lucene.Net.Search.IntParser parser) : base(field)
+ {
+ this.parser = parser;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#description() */
+ public override System.String Description()
+ {
+ return "int(" + base.Description() + ')';
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#getCachedValues(Lucene.Net.Search.FieldCache, java.lang.String, Lucene.Net.Index.IndexReader) */
+ public override DocValues GetCachedFieldValues(FieldCache cache, System.String field, IndexReader reader)
+ {
+ int[] arr = (parser == null) ? cache.GetInts(reader, field) : cache.GetInts(reader, field, parser);
+ return new AnonymousClassDocValues(arr, this);
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceEquals(Lucene.Net.Search.Function.FieldCacheSource) */
+ public override bool CachedFieldSourceEquals(FieldCacheSource o)
+ {
+ if (o.GetType() != typeof(IntFieldSource))
+ {
+ return false;
+ }
+ IntFieldSource other = (IntFieldSource) o;
+ return this.parser == null ? other.parser == null : this.parser.GetType() == other.parser.GetType();
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.FieldCacheSource#cachedFieldSourceHashCode() */
+ public override int CachedFieldSourceHashCode()
+ {
+ return parser == null ? typeof(System.Int32).GetHashCode() : parser.GetType().GetHashCode();
+ }
+ }
+}
\ No newline at end of file
Added: incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/OrdFieldSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/src/Lucene.Net/Search/Function/OrdFieldSource.cs?rev=671402&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/OrdFieldSource.cs (added)
+++ incubator/lucene.net/trunk/C#/src/Lucene.Net/Search/Function/OrdFieldSource.cs Tue Jun 24 19:51:24 2008
@@ -0,0 +1,140 @@
+/*
+ * 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.
+ */
+using System;
+
+using IndexReader = Lucene.Net.Index.IndexReader;
+using FieldCache = Lucene.Net.Search.FieldCache;
+
+namespace Lucene.Net.Search.Function
+{
+
+ /// <summary> Expert: obtains the ordinal of the field value from the default Lucene
+ /// {@link Lucene.Net.Search.FieldCache Fieldcache} using getStringIndex().
+ /// <p>
+ /// The native lucene index order is used to assign an ordinal value for each field value.
+ /// <p
+ /// Field values (terms) are lexicographically ordered by unicode value, and numbered starting at 1.
+ /// <p>
+ /// Example:
+ /// <br>If there were only three field values: "apple","banana","pear"
+ /// <br>then ord("apple")=1, ord("banana")=2, ord("pear")=3
+ /// <p>
+ /// WARNING:
+ /// ord() depends on the position in an index and can thus change
+ /// when other documents are inserted or deleted,
+ /// or if a MultiSearcher is used.
+ ///
+ /// <p><font color="#FF0000">
+ /// WARNING: The status of the <b>search.function</b> package is experimental.
+ /// The APIs introduced here might change in the future and will not be
+ /// supported anymore in such a case.</font>
+ ///
+ /// </summary>
+ /// <author> yonik
+ /// </author>
+
+ [Serializable]
+ public class OrdFieldSource : ValueSource
+ {
+ private class AnonymousClassDocValues : DocValues
+ {
+ public AnonymousClassDocValues(int[] arr, OrdFieldSource enclosingInstance)
+ {
+ InitBlock(arr, enclosingInstance);
+ }
+ private void InitBlock(int[] arr, OrdFieldSource enclosingInstance)
+ {
+ this.arr = arr;
+ this.enclosingInstance = enclosingInstance;
+ }
+ private int[] arr;
+ private OrdFieldSource enclosingInstance;
+ public OrdFieldSource Enclosing_Instance
+ {
+ get
+ {
+ return enclosingInstance;
+ }
+
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#floatVal(int) */
+ public override float FloatVal(int doc)
+ {
+ return (float) arr[doc];
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#strVal(int) */
+ public override System.String StrVal(int doc)
+ {
+ // the string value of the ordinal, not the string itself
+ return System.Convert.ToString(arr[doc]);
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#toString(int) */
+ public override System.String ToString(int doc)
+ {
+ return Enclosing_Instance.Description() + '=' + IntVal(doc);
+ }
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.DocValues#getInnerArray() */
+ internal override System.Object GetInnerArray()
+ {
+ return arr;
+ }
+ }
+ protected internal System.String field;
+
+ /// <summary> Contructor for a certain field.</summary>
+ /// <param name="field">field whose values order is used.
+ /// </param>
+ public OrdFieldSource(System.String field)
+ {
+ this.field = field;
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#description() */
+ public override System.String Description()
+ {
+ return "ord(" + field + ')';
+ }
+
+ /*(non-Javadoc) @see Lucene.Net.Search.Function.ValueSource#getValues(Lucene.Net.Index.IndexReader) */
+ public override DocValues GetValues(IndexReader reader)
+ {
+ int[] arr = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetStringIndex(reader, field).order;
+ return new AnonymousClassDocValues(arr, this);
+ }
+
+ /*(non-Javadoc) @see java.lang.Object#equals(java.lang.Object) */
+ public override bool Equals(System.Object o)
+ {
+ if (o.GetType() != typeof(OrdFieldSource))
+ return false;
+ OrdFieldSource other = (OrdFieldSource) o;
+ return this.field.Equals(other.field);
+ }
+
+ private static readonly int hcode;
+
+ /*(non-Javadoc) @see java.lang.Object#hashCode() */
+ public override int GetHashCode()
+ {
+ return hcode + field.GetHashCode();
+ }
+ static OrdFieldSource()
+ {
+ hcode = typeof(OrdFieldSource).GetHashCode();
+ }
+ }
+}
\ No newline at end of file