blob: f9222443359fcd7c465b12e91b510dd1bf3d12bc [file]
using System;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
namespace Lucene.Net.Search
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using AtomicReader = Lucene.Net.Index.AtomicReader;
using BinaryDocValues = Lucene.Net.Index.BinaryDocValues;
using IBits = Lucene.Net.Util.IBits;
using BytesRef = Lucene.Net.Util.BytesRef;
using NumericUtils = Lucene.Net.Util.NumericUtils;
using RamUsageEstimator = Lucene.Net.Util.RamUsageEstimator;
using SortedDocValues = Lucene.Net.Index.SortedDocValues;
using SortedSetDocValues = Lucene.Net.Index.SortedSetDocValues;
using Terms = Lucene.Net.Index.Terms;
using TermsEnum = Lucene.Net.Index.TermsEnum;
/// <summary>
/// Expert: Maintains caches of term values.
///
/// <p>Created: May 19, 2004 11:13:14 AM
///
/// @since lucene 1.4 </summary>
/// <seealso cref=Lucene.Net.Util.FieldCacheSanityChecker</seealso>
public interface IFieldCache
{
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is found,
/// reads the terms in <code>field</code> and returns a bit set at the size of
/// <code>reader.maxDoc()</code>, with turned on bits for each docid that
/// does have a value for this field.
/// </summary>
IBits GetDocsWithField(AtomicReader reader, string field);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is
/// found, reads the terms in <code>field</code> as a single byte and returns an array
/// of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field. </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the single byte values. </param>
/// <param name="setDocsWithField"> If true then <seealso cref="#getDocsWithField"/> will
/// also be computed and stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
/// @deprecated (4.4) Index as a numeric field using <seealso cref="IntField"/> and then use <seealso cref="#getInts(AtomicReader, String, boolean)"/> instead.
[Obsolete("(4.4) Index as a numeric field using IntField and then use GetInt32s(AtomicReader, string, bool) instead.")]
FieldCache.Bytes GetBytes(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is found,
/// reads the terms in <code>field</code> as bytes and returns an array of
/// size <code>reader.maxDoc()</code> of the value each document has in the
/// given field. </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the bytes. </param>
/// <param name="parser"> Computes byte for string values. </param>
/// <param name="setDocsWithField"> If true then <seealso cref="#getDocsWithField"/> will
/// also be computed and stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
/// @deprecated (4.4) Index as a numeric field using <seealso cref="IntField"/> and then use <seealso cref="#getInts(AtomicReader, String, boolean)"/> instead.
[Obsolete("(4.4) Index as a numeric field using IntField and then use GetInt32s(AtomicReader, string, bool) instead.")]
FieldCache.Bytes GetBytes(AtomicReader reader, string field, FieldCache.IByteParser parser, bool setDocsWithField);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is
/// found, reads the terms in <code>field</code> as shorts and returns an array
/// of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field.
/// <para/>
/// NOTE: this was getShorts() in Lucene
/// </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the shorts. </param>
/// <param name="setDocsWithField"> If true then <seealso cref="#getDocsWithField"/> will
/// also be computed and stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
/// @deprecated (4.4) Index as a numeric field using <seealso cref="IntField"/> and then use <seealso cref="#getInts(AtomicReader, String, boolean)"/> instead.
[Obsolete("(4.4) Index as a numeric field using Int32Field and then use GetInt32s(AtomicReader, string, bool) instead.")]
FieldCache.Int16s GetInt16s(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is found,
/// reads the terms in <code>field</code> as shorts and returns an array of
/// size <code>reader.maxDoc()</code> of the value each document has in the
/// given field.
/// <para/>
/// NOTE: this was getShorts() in Lucene
/// </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the shorts. </param>
/// <param name="parser"> Computes short for string values. </param>
/// <param name="setDocsWithField"> If true then <seealso cref="#getDocsWithField"/> will
/// also be computed and stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
/// @deprecated (4.4) Index as a numeric field using <seealso cref="IntField"/> and then use <seealso cref="#getInts(AtomicReader, String, boolean)"/> instead.
[Obsolete("(4.4) Index as a numeric field using Int32Field and then use GetInt32s(AtomicReader, string, bool) instead.")]
FieldCache.Int16s GetInt16s(AtomicReader reader, string field, FieldCache.IInt16Parser parser, bool setDocsWithField);
/// <summary>
/// Returns an <seealso cref="FieldCache.Int32s"/> over the values found in documents in the given
/// field.
/// <para/>
/// NOTE: this was getInts() in Lucene
/// </summary>
/// <seealso cref= #getInts(AtomicReader, String, IntParser, boolean) </seealso>
FieldCache.Int32s GetInt32s(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Returns an <seealso cref="FieldCache.Int32s"/> over the values found in documents in the given
/// field. If the field was indexed as <seealso cref="NumericDocValuesField"/>, it simply
/// uses <seealso cref="AtomicReader#getNumericDocValues(String)"/> to read the values.
/// Otherwise, it checks the internal cache for an appropriate entry, and if
/// none is found, reads the terms in <code>field</code> as ints and returns
/// an array of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field.
/// <para/>
/// NOTE: this was getInts() in Lucene
/// </summary>
/// <param name="reader">
/// Used to get field values. </param>
/// <param name="field">
/// Which field contains the longs. </param>
/// <param name="parser">
/// Computes int for string values. May be {@code null} if the
/// requested field was indexed as <seealso cref="NumericDocValuesField"/> or
/// <seealso cref="IntField"/>. </param>
/// <param name="setDocsWithField">
/// If true then <seealso cref="#getDocsWithField"/> will also be computed and
/// stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException">
/// If any error occurs. </exception>
FieldCache.Int32s GetInt32s(AtomicReader reader, string field, FieldCache.IInt32Parser parser, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Floats"/> over the values found in documents in the given
/// field.
/// <para/>
/// NOTE: this was getFloats() in Lucene
/// </summary>
/// <seealso cref= #getFloats(AtomicReader, String, FloatParser, boolean) </seealso>
FieldCache.Singles GetSingles(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Floats"/> over the values found in documents in the given
/// field. If the field was indexed as <seealso cref="NumericDocValuesField"/>, it simply
/// uses <seealso cref="AtomicReader#getNumericDocValues(String)"/> to read the values.
/// Otherwise, it checks the internal cache for an appropriate entry, and if
/// none is found, reads the terms in <code>field</code> as floats and returns
/// an array of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field.
/// <para/>
/// NOTE: this was getFloats() in Lucene
/// </summary>
/// <param name="reader">
/// Used to get field values. </param>
/// <param name="field">
/// Which field contains the floats. </param>
/// <param name="parser">
/// Computes float for string values. May be {@code null} if the
/// requested field was indexed as <seealso cref="NumericDocValuesField"/> or
/// <seealso cref="FloatField"/>. </param>
/// <param name="setDocsWithField">
/// If true then <seealso cref="#getDocsWithField"/> will also be computed and
/// stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException">
/// If any error occurs. </exception>
FieldCache.Singles GetSingles(AtomicReader reader, string field, FieldCache.ISingleParser parser, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Longs"/> over the values found in documents in the given
/// field.
/// <para/>
/// NOTE: this was getLongs() in Lucene
/// </summary>
/// <seealso cref= #getLongs(AtomicReader, String, LongParser, boolean) </seealso>
FieldCache.Int64s GetInt64s(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Longs"/> over the values found in documents in the given
/// field. If the field was indexed as <seealso cref="NumericDocValuesField"/>, it simply
/// uses <seealso cref="AtomicReader#getNumericDocValues(String)"/> to read the values.
/// Otherwise, it checks the internal cache for an appropriate entry, and if
/// none is found, reads the terms in <code>field</code> as longs and returns
/// an array of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field.
/// <para/>
/// NOTE: this was getLongs() in Lucene
/// </summary>
/// <param name="reader">
/// Used to get field values. </param>
/// <param name="field">
/// Which field contains the longs. </param>
/// <param name="parser">
/// Computes long for string values. May be {@code null} if the
/// requested field was indexed as <seealso cref="NumericDocValuesField"/> or
/// <seealso cref="LongField"/>. </param>
/// <param name="setDocsWithField">
/// If true then <seealso cref="#getDocsWithField"/> will also be computed and
/// stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException">
/// If any error occurs. </exception>
FieldCache.Int64s GetInt64s(AtomicReader reader, string field, FieldCache.IInt64Parser parser, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Doubles"/> over the values found in documents in the given
/// field.
/// </summary>
/// <seealso cref= #getDoubles(AtomicReader, String, DoubleParser, boolean) </seealso>
FieldCache.Doubles GetDoubles(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Returns a <seealso cref="Doubles"/> over the values found in documents in the given
/// field. If the field was indexed as <seealso cref="NumericDocValuesField"/>, it simply
/// uses <seealso cref="AtomicReader#getNumericDocValues(String)"/> to read the values.
/// Otherwise, it checks the internal cache for an appropriate entry, and if
/// none is found, reads the terms in <code>field</code> as doubles and returns
/// an array of size <code>reader.maxDoc()</code> of the value each document
/// has in the given field.
/// </summary>
/// <param name="reader">
/// Used to get field values. </param>
/// <param name="field">
/// Which field contains the longs. </param>
/// <param name="parser">
/// Computes double for string values. May be {@code null} if the
/// requested field was indexed as <seealso cref="NumericDocValuesField"/> or
/// <seealso cref="DoubleField"/>. </param>
/// <param name="setDocsWithField">
/// If true then <seealso cref="#getDocsWithField"/> will also be computed and
/// stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException">
/// If any error occurs. </exception>
FieldCache.Doubles GetDoubles(AtomicReader reader, string field, FieldCache.IDoubleParser parser, bool setDocsWithField);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none
/// is found, reads the term values in <code>field</code>
/// and returns a <seealso cref="BinaryDocValues"/> instance, providing a
/// method to retrieve the term (as a BytesRef) per document. </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the strings. </param>
/// <param name="setDocsWithField"> If true then <seealso cref="#getDocsWithField"/> will
/// also be computed and stored in the FieldCache. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
BinaryDocValues GetTerms(AtomicReader reader, string field, bool setDocsWithField);
/// <summary>
/// Expert: just like <seealso cref="#getTerms(AtomicReader,String,boolean)"/>,
/// but you can specify whether more RAM should be consumed in exchange for
/// faster lookups (default is "true"). Note that the
/// first call for a given reader and field "wins",
/// subsequent calls will share the same cache entry.
/// </summary>
BinaryDocValues GetTerms(AtomicReader reader, string field, bool setDocsWithField, float acceptableOverheadRatio);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none
/// is found, reads the term values in <code>field</code>
/// and returns a <seealso cref="SortedDocValues"/> instance,
/// providing methods to retrieve sort ordinals and terms
/// (as a ByteRef) per document. </summary>
/// <param name="reader"> Used to get field values. </param>
/// <param name="field"> Which field contains the strings. </param>
/// <returns> The values in the given field for each document. </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
SortedDocValues GetTermsIndex(AtomicReader reader, string field);
/// <summary>
/// Expert: just like {@link
/// #getTermsIndex(AtomicReader,String)}, but you can specify
/// whether more RAM should be consumed in exchange for
/// faster lookups (default is "true"). Note that the
/// first call for a given reader and field "wins",
/// subsequent calls will share the same cache entry.
/// </summary>
SortedDocValues GetTermsIndex(AtomicReader reader, string field, float acceptableOverheadRatio);
/// <summary>
/// Checks the internal cache for an appropriate entry, and if none is found, reads the term values
/// in <code>field</code> and returns a <seealso cref="DocTermOrds"/> instance, providing a method to retrieve
/// the terms (as ords) per document.
/// </summary>
/// <param name="reader"> Used to build a <seealso cref="DocTermOrds"/> instance </param>
/// <param name="field"> Which field contains the strings. </param>
/// <returns> a <seealso cref="DocTermOrds"/> instance </returns>
/// <exception cref="IOException"> If any error occurs. </exception>
SortedSetDocValues GetDocTermOrds(AtomicReader reader, string field);
/// <summary>
/// EXPERT: A unique Identifier/Description for each item in the FieldCache.
/// Can be useful for logging/debugging.
/// @lucene.experimental
/// </summary>
/// <summary>
/// EXPERT: Generates an array of CacheEntry objects representing all items
/// currently in the FieldCache.
/// <p>
/// NOTE: These CacheEntry objects maintain a strong reference to the
/// Cached Values. Maintaining references to a CacheEntry the AtomicIndexReader
/// associated with it has garbage collected will prevent the Value itself
/// from being garbage collected when the Cache drops the WeakReference.
/// </p>
/// @lucene.experimental
/// </summary>
FieldCache.CacheEntry[] GetCacheEntries();
/// <summary>
/// <p>
/// EXPERT: Instructs the FieldCache to forcibly expunge all entries
/// from the underlying caches. this is intended only to be used for
/// test methods as a way to ensure a known base state of the Cache
/// (with out needing to rely on GC to free WeakReferences).
/// It should not be relied on for "Cache maintenance" in general
/// application code.
/// </p>
/// @lucene.experimental
/// </summary>
void PurgeAllCaches();
/// <summary>
/// Expert: drops all cache entries associated with this
/// reader <seealso cref="IndexReader#getCoreCacheKey"/>. NOTE: this cache key must
/// precisely match the reader that the cache entry is
/// keyed on. If you pass a top-level reader, it usually
/// will have no effect as Lucene now caches at the segment
/// reader level.
/// </summary>
void PurgeByCacheKey(object coreCacheKey);
/// <summary>
/// If non-null, FieldCacheImpl will warn whenever
/// entries are created that are not sane according to
/// <seealso cref="Lucene.Net.Util.FieldCacheSanityChecker"/>.
/// </summary>
TextWriter InfoStream { set; get; }
}
// LUCENENET TODO: Copy documentation from Lucene
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public static class FieldCache
{
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Bytes
{
public abstract byte Get(int docID);
public static readonly Bytes EMPTY = new EmptyBytes();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptyBytes : Bytes
{
public override byte Get(int docID)
{
return 0;
}
}
}
/// <summary>
/// NOTE: This was Shorts in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Int16s
{
public abstract short Get(int docID);
public static readonly Int16s EMPTY = new EmptyInt16s();
/// <summary>
/// NOTE: This was EmptyShorts in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptyInt16s : Int16s
{
public override short Get(int docID)
{
return 0;
}
}
}
/// <summary>
/// NOTE: This was Ints in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Int32s
{
public abstract int Get(int docID);
public static readonly Int32s EMPTY = new EmptyInt32s();
/// <summary>
/// NOTE: This was EmptyInts in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptyInt32s : Int32s
{
public override int Get(int docID)
{
return 0;
}
}
}
/// <summary>
/// NOTE: This was Longs in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Int64s
{
public abstract long Get(int docID);
public static readonly Int64s EMPTY = new EmptyInt64s();
/// <summary>
/// NOTE: This was EmptyLongs in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptyInt64s : Int64s
{
public override long Get(int docID)
{
return 0;
}
}
}
/// <summary>
/// NOTE: This was Floats in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Singles
{
public abstract float Get(int docID);
public static readonly Singles EMPTY = new EmptySingles();
/// <summary>
/// NOTE: This was EmptySingles in Lucene
/// </summary>
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptySingles : Singles
{
public override float Get(int docID)
{
return 0;
}
}
}
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public abstract class Doubles
{
public abstract double Get(int docID);
public static readonly Doubles EMPTY = new EmptyDoubles();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class EmptyDoubles : Doubles
{
public override double Get(int docID)
{
return 0;
}
}
}
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class CreationPlaceholder
{
internal object Value { get; set; }
}
public interface IParser
{
TermsEnum TermsEnum(Terms terms);
}
public interface IByteParser : IParser
{
byte ParseByte(BytesRef term);
}
/// <summary>
/// NOTE: This was ShortParser in Lucene
/// </summary>
public interface IInt16Parser : IParser
{
/// <summary>
/// NOTE: This was parseShort() in Lucene
/// </summary>
short ParseInt16(BytesRef term);
}
/// <summary>
/// NOTE: This was IntParser in Lucene
/// </summary>
public interface IInt32Parser : IParser
{
/// <summary>
/// NOTE: This was parseInt() in Lucene
/// </summary>
int ParseInt32(BytesRef term);
}
/// <summary>
/// NOTE: This was FloatParser in Lucene
/// </summary>
public interface ISingleParser : IParser
{
/// <summary>
/// NOTE: This was parseFloat() in Lucene
/// </summary>
float ParseSingle(BytesRef term);
}
/// <summary>
/// NOTE: This was LongParser in Lucene
/// </summary>
public interface IInt64Parser : IParser
{
/// <summary>
/// NOTE: This was parseLong() in Lucene
/// </summary>
long ParseInt64(BytesRef term);
}
public interface IDoubleParser : IParser
{
double ParseDouble(BytesRef term);
}
public static IFieldCache DEFAULT = new FieldCacheImpl();
public static readonly IByteParser DEFAULT_BYTE_PARSER = new AnonymousByteParser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousByteParser : IByteParser
{
public byte ParseByte(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// IntField, instead, which already decodes
// directly from byte[]
return (byte)sbyte.Parse(term.Utf8ToString(), CultureInfo.InvariantCulture);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_BYTE_PARSER";
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
}
/// <summary>
/// NOTE: This was DEFAULT_SHORT_PARSER in Lucene
/// </summary>
public static readonly IInt16Parser DEFAULT_INT16_PARSER = new AnonymousInt16Parser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousInt16Parser : IInt16Parser
{
/// <summary>
/// NOTE: This was parseShort() in Lucene
/// </summary>
public short ParseInt16(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// IntField, instead, which already decodes
// directly from byte[]
return short.Parse(term.Utf8ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_INT16_PARSER";
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
}
/// <summary>
/// NOTE: This was DEFAULT_INT_PARSER in Lucene
/// </summary>
public static readonly IInt32Parser DEFAULT_INT32_PARSER = new AnonymousInt32Parser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousInt32Parser : IInt32Parser
{
/// <summary>
/// NOTE: This was parseInt() in Lucene
/// </summary>
public int ParseInt32(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// IntField, instead, which already decodes
// directly from byte[]
return int.Parse(term.Utf8ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture);
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_INT32_PARSER";
}
}
/// <summary>
/// NOTE: This was DEFAULT_FLOAT_PARSER in Lucene
/// </summary>
public static readonly ISingleParser DEFAULT_SINGLE_PARSER = new AnonymousSingleParser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousSingleParser : ISingleParser
{
/// <summary>
/// NOTE: This was parseFloat() in Lucene
/// </summary>
public float ParseSingle(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// FloatField, instead, which already decodes
// directly from byte[]
// LUCENENET: We parse to double first and then cast to float, which allows us to parse
// double.MaxValue.ToString("R") (resulting in Infinity). This is how it worked in Java
// and the TestFieldCache.TestInfoStream() test depends on this behavior to pass.
// We also need to use the same logic as DEFAULT_DOUBLE_PARSER to ensure we have signed zero
// support, so just call it directly rather than duplicating the logic here.
return (float)DEFAULT_DOUBLE_PARSER.ParseDouble(term);
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_SINGLE_PARSER";
}
}
/// <summary>
/// NOTE: This was DEFAULT_LONG_PARSER in Lucene
/// </summary>
public static readonly IInt64Parser DEFAULT_INT64_PARSER = new AnonymousInt64Parser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousInt64Parser : IInt64Parser
{
/// <summary>
/// NOTE: This was parseLong() in Lucene
/// </summary>
public long ParseInt64(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// LongField, instead, which already decodes
// directly from byte[]
return long.Parse(term.Utf8ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture);
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_INT64_PARSER";
}
}
public static readonly IDoubleParser DEFAULT_DOUBLE_PARSER = new AnonymousDoubleParser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousDoubleParser : IDoubleParser
{
public double ParseDouble(BytesRef term)
{
// TODO: would be far better to directly parse from
// UTF8 bytes... but really users should use
// DoubleField, instead, which already decodes
// directly from byte[]
string text = term.Utf8ToString();
double value = double.Parse(text, NumberStyles.Float, CultureInfo.InvariantCulture);
// LUCENENET specific special case - check whether a negative
// zero was passed in and, if so, convert the sign. Unfotunately, double.Parse()
// doesn't take care of this for us.
if (value == 0 && text.TrimStart().StartsWith("-", StringComparison.Ordinal))
{
value = -0d; // Hard-coding the value in case double.Parse() works right someday (which would break if we did value * -1)
}
return value;
}
public TermsEnum TermsEnum(Terms terms)
{
return terms.GetIterator(null);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".DEFAULT_DOUBLE_PARSER";
}
}
/// <summary>
/// NOTE: This was NUMERIC_UTILS_INT_PARSER in Lucene
/// </summary>
public static readonly IInt32Parser NUMERIC_UTILS_INT32_PARSER = new AnonymousNumericUtilsInt32Parser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousNumericUtilsInt32Parser : IInt32Parser
{
/// <summary>
/// NOTE: This was parseInt() in Lucene
/// </summary>
public int ParseInt32(BytesRef term)
{
return NumericUtils.PrefixCodedToInt32(term);
}
public TermsEnum TermsEnum(Terms terms)
{
return NumericUtils.FilterPrefixCodedInt32s(terms.GetIterator(null));
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".NUMERIC_UTILS_INT32_PARSER";
}
}
/// <summary>
/// NOTE: This was NUMERIC_UTILS_FLOAT_PARSER in Lucene
/// </summary>
public static readonly ISingleParser NUMERIC_UTILS_SINGLE_PARSER = new AnonymousNumericUtilsSingleParser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousNumericUtilsSingleParser : ISingleParser
{
/// <summary>
/// NOTE: This was parseFloat() in Lucene
/// </summary>
public float ParseSingle(BytesRef term)
{
return NumericUtils.SortableInt32ToSingle(NumericUtils.PrefixCodedToInt32(term));
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".NUMERIC_UTILS_SINGLE_PARSER";
}
public TermsEnum TermsEnum(Terms terms)
{
return NumericUtils.FilterPrefixCodedInt32s(terms.GetIterator(null));
}
}
/// <summary>
/// NOTE: This was NUMERIC_UTILS_LONG_PARSER in Lucene
/// </summary>
public static readonly IInt64Parser NUMERIC_UTILS_INT64_PARSER = new AnonymousNumericUtilsInt64Parser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousNumericUtilsInt64Parser : IInt64Parser
{
/// <summary>
/// NOTE: This was parseLong() in Lucene
/// </summary>
public long ParseInt64(BytesRef term)
{
return NumericUtils.PrefixCodedToInt64(term);
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".NUMERIC_UTILS_INT64_PARSER";
}
public TermsEnum TermsEnum(Terms terms)
{
return NumericUtils.FilterPrefixCodedInt64s(terms.GetIterator(null));
}
}
public static readonly IDoubleParser NUMERIC_UTILS_DOUBLE_PARSER = new AnonymousNumericUtilsDoubleParser();
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
private sealed class AnonymousNumericUtilsDoubleParser : IDoubleParser
{
public double ParseDouble(BytesRef term)
{
return NumericUtils.SortableInt64ToDouble(NumericUtils.PrefixCodedToInt64(term));
}
public override string ToString()
{
return typeof(IFieldCache).FullName + ".NUMERIC_UTILS_DOUBLE_PARSER";
}
public TermsEnum TermsEnum(Terms terms)
{
return NumericUtils.FilterPrefixCodedInt64s(terms.GetIterator(null));
}
}
// .NET Port: skipping down to about line 681 of java version. The actual interface methods of FieldCache are in IFieldCache below.
#if FEATURE_SERIALIZABLE
[Serializable]
#endif
public sealed class CacheEntry
{
private readonly object readerKey;
private readonly string fieldName;
private readonly Type cacheType;
private readonly object custom;
private readonly object value;
private string size;
public CacheEntry(object readerKey, string fieldName,
Type cacheType,
object custom,
object value)
{
this.readerKey = readerKey;
this.fieldName = fieldName;
this.cacheType = cacheType;
this.custom = custom;
this.value = value;
}
public object ReaderKey
{
get { return readerKey; }
}
public string FieldName
{
get { return fieldName; }
}
public Type CacheType
{
get { return cacheType; }
}
public object Custom
{
get { return custom; }
}
public object Value
{
get { return value; }
}
public void EstimateSize()
{
long bytesUsed = RamUsageEstimator.SizeOf(Value);
size = RamUsageEstimator.HumanReadableUnits(bytesUsed);
}
public string EstimatedSize
{
get { return size; }
}
public override string ToString()
{
StringBuilder b = new StringBuilder();
b.Append("'").Append(ReaderKey).Append("'=>");
b.Append("'").Append(FieldName).Append("',");
b.Append(CacheType).Append(",").Append(Custom);
b.Append("=>").Append(Value.GetType().FullName).Append("#");
b.Append(RuntimeHelpers.GetHashCode(Value));
String s = EstimatedSize;
if (null != s)
{
b.Append(" (size =~ ").Append(s).Append(')');
}
return b.ToString();
}
}
}
// // LUCENENET NOTE: refactoring because of enum nonsense
// public static readonly FieldCache DEFAULT = new FieldCacheImpl();
// private class FieldCache_ByteParserAnonymousInnerClassHelper : FieldCache_ByteParser
// {
// public FieldCache_ByteParserAnonymousInnerClassHelper()
// {
// }
// public virtual sbyte ParseByte(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // IntField, instead, which already decodes
// // directly from byte[]
// return (sbyte)Convert.ToByte(term.Utf8ToString());
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_BYTE_PARSER";
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// }
// private class FieldCache_ShortParserAnonymousInnerClassHelper : FieldCache_ShortParser
// {
// public FieldCache_ShortParserAnonymousInnerClassHelper()
// {
// }
// public virtual short ParseShort(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // IntField, instead, which already decodes
// // directly from byte[]
// return Convert.ToInt16(term.Utf8ToString());
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_SHORT_PARSER";
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// }
// private class FieldCache_IntParserAnonymousInnerClassHelper : FieldCache_IntParser
// {
// public FieldCache_IntParserAnonymousInnerClassHelper()
// {
// }
// public virtual int ParseInt(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // IntField, instead, which already decodes
// // directly from byte[]
// return Convert.ToInt32(term.Utf8ToString());
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_INT_PARSER";
// }
// }
// private class FieldCache_FloatParserAnonymousInnerClassHelper : FieldCache_FloatParser
// {
// public FieldCache_FloatParserAnonymousInnerClassHelper()
// {
// }
// public virtual float ParseFloat(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // FloatField, instead, which already decodes
// // directly from byte[]
// return Convert.ToSingle(term.Utf8ToString());
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_FLOAT_PARSER";
// }
// }
// private class FieldCache_LongParserAnonymousInnerClassHelper : FieldCache_LongParser
// {
// public FieldCache_LongParserAnonymousInnerClassHelper()
// {
// }
// public virtual long ParseLong(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // LongField, instead, which already decodes
// // directly from byte[]
// return Convert.ToInt64(term.Utf8ToString());
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_LONG_PARSER";
// }
// }
// private class FieldCache_DoubleParserAnonymousInnerClassHelper : FieldCache_DoubleParser
// {
// public FieldCache_DoubleParserAnonymousInnerClassHelper()
// {
// }
// public virtual double ParseDouble(BytesRef term)
// {
// // TODO: would be far better to directly parse from
// // UTF8 bytes... but really users should use
// // DoubleField, instead, which already decodes
// // directly from byte[]
// return Convert.ToDouble(term.Utf8ToString());
// }
// public virtual TermsEnum TermsEnum(Terms terms)
// {
// return terms.Iterator(null);
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".DEFAULT_DOUBLE_PARSER";
// }
// }
// private class FieldCache_IntParserAnonymousInnerClassHelper2 : FieldCache_IntParser
// {
// public FieldCache_IntParserAnonymousInnerClassHelper2()
// {
// }
// public override int ParseInt(BytesRef term)
// {
// return NumericUtils.PrefixCodedToInt(term);
// }
// public override TermsEnum TermsEnum(Terms terms)
// {
// return NumericUtils.FilterPrefixCodedInts(terms.Iterator(null));
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".NUMERIC_UTILS_INT_PARSER";
// }
// }
// private class FieldCache_FloatParserAnonymousInnerClassHelper2 : FieldCache_FloatParser
// {
// public FieldCache_FloatParserAnonymousInnerClassHelper2()
// {
// }
// public override float ParseFloat(BytesRef term)
// {
// return NumericUtils.SortableIntToFloat(NumericUtils.PrefixCodedToInt(term));
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".NUMERIC_UTILS_FLOAT_PARSER";
// }
// public override TermsEnum TermsEnum(Terms terms)
// {
// return NumericUtils.FilterPrefixCodedInts(terms.Iterator(null));
// }
// }
// private class FieldCache_LongParserAnonymousInnerClassHelper2 : FieldCache_LongParser
// {
// public FieldCache_LongParserAnonymousInnerClassHelper2()
// {
// }
// public override long ParseLong(BytesRef term)
// {
// return NumericUtils.PrefixCodedToLong(term);
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".NUMERIC_UTILS_LONG_PARSER";
// }
// public override TermsEnum TermsEnum(Terms terms)
// {
// return NumericUtils.FilterPrefixCodedLongs(terms.Iterator(null));
// }
// }
// private class FieldCache_DoubleParserAnonymousInnerClassHelper2 : FieldCache_DoubleParser
// {
// public FieldCache_DoubleParserAnonymousInnerClassHelper2()
// {
// }
// public override double ParseDouble(BytesRef term)
// {
// return NumericUtils.SortableLongToDouble(NumericUtils.PrefixCodedToLong(term));
// }
// public override string ToString()
// {
// return typeof(FieldCache).Name + ".NUMERIC_UTILS_DOUBLE_PARSER";
// }
// public override TermsEnum TermsEnum(Terms terms)
// {
// return NumericUtils.FilterPrefixCodedLongs(terms.Iterator(null));
// }
// }
//}
// public abstract class FieldCache_Bytes
// {
// /// <summary>
// /// Return a single Byte representation of this field's value. </summary>
// public abstract sbyte Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Bytes EMPTY = new FieldCache_BytesAnonymousInnerClassHelper();
// private class FieldCache_BytesAnonymousInnerClassHelper : FieldCache_Bytes
// {
// public FieldCache_BytesAnonymousInnerClassHelper()
// {
// }
// public override sbyte Get(int docID)
// {
// return 0;
// }
// }
// }
// public abstract class FieldCache_Shorts
// {
// /// <summary>
// /// Return a short representation of this field's value. </summary>
// public abstract short Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Shorts EMPTY = new FieldCache_ShortsAnonymousInnerClassHelper();
// private class FieldCache_ShortsAnonymousInnerClassHelper : FieldCache_Shorts
// {
// public FieldCache_ShortsAnonymousInnerClassHelper()
// {
// }
// public override short Get(int docID)
// {
// return 0;
// }
// }
// }
// public abstract class FieldCache_Ints
// {
// /// <summary>
// /// Return an integer representation of this field's value. </summary>
// public abstract int Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Ints EMPTY = new FieldCache_IntsAnonymousInnerClassHelper();
// private class FieldCache_IntsAnonymousInnerClassHelper : FieldCache_Ints
// {
// public FieldCache_IntsAnonymousInnerClassHelper()
// {
// }
// public override int Get(int docID)
// {
// return 0;
// }
// }
// }
// public abstract class FieldCache_Longs
// {
// /// <summary>
// /// Return an long representation of this field's value. </summary>
// public abstract long Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Longs EMPTY = new FieldCache_LongsAnonymousInnerClassHelper();
// private class FieldCache_LongsAnonymousInnerClassHelper : FieldCache_Longs
// {
// public FieldCache_LongsAnonymousInnerClassHelper()
// {
// }
// public override long Get(int docID)
// {
// return 0;
// }
// }
// }
// public abstract class FieldCache_Floats
// {
// /// <summary>
// /// Return an float representation of this field's value. </summary>
// public abstract float Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Floats EMPTY = new FieldCache_FloatsAnonymousInnerClassHelper();
// private class FieldCache_FloatsAnonymousInnerClassHelper : FieldCache_Floats
// {
// public FieldCache_FloatsAnonymousInnerClassHelper()
// {
// }
// public override float Get(int docID)
// {
// return 0;
// }
// }
// }
// public abstract class FieldCache_Doubles
// {
// /// <summary>
// /// Return an double representation of this field's value. </summary>
// public abstract double Get(int docID);
// /// <summary>
// /// Zero value for every document </summary>
// public static readonly FieldCache_Doubles EMPTY = new FieldCache_DoublesAnonymousInnerClassHelper();
// private class FieldCache_DoublesAnonymousInnerClassHelper : FieldCache_Doubles
// {
// public FieldCache_DoublesAnonymousInnerClassHelper()
// {
// }
// public override double Get(int docID)
// {
// return 0;
// }
// }
// }
// public sealed class FieldCache_CreationPlaceholder
// {
// internal object Value;
// }
// public interface FieldCache_Parser
// {
// /// <summary>
// /// Pulls a <seealso cref="TermsEnum"/> from the given <seealso cref="Terms"/>. this method allows certain parsers
// /// to filter the actual TermsEnum before the field cache is filled.
// /// </summary>
// /// <param name="terms"> the <seealso cref="Terms"/> instance to create the <seealso cref="TermsEnum"/> from. </param>
// /// <returns> a possibly filtered <seealso cref="TermsEnum"/> instance, this method must not return <code>null</code>. </returns>
// /// <exception cref="IOException"> if an <seealso cref="IOException"/> occurs </exception>
// TermsEnum TermsEnum(Terms terms);
// }
// [Obsolete]
// public interface FieldCache_ByteParser : FieldCache_Parser
// {
// /// <summary>
// /// Return a single Byte representation of this field's value. </summary>
// sbyte ParseByte(BytesRef term);
// }
// [Obsolete]
// public interface FieldCache_ShortParser : FieldCache_Parser
// {
// /// <summary>
// /// Return a short representation of this field's value. </summary>
// short ParseShort(BytesRef term);
// }
// public interface FieldCache_IntParser : FieldCache_Parser
// {
// /// <summary>
// /// Return an integer representation of this field's value. </summary>
// int ParseInt(BytesRef term);
// }
// public interface FieldCache_FloatParser : FieldCache_Parser
// {
// /// <summary>
// /// Return an float representation of this field's value. </summary>
// float ParseFloat(BytesRef term);
// }
// public interface FieldCache_LongParser : FieldCache_Parser
// {
// /// <summary>
// /// Return an long representation of this field's value. </summary>
// long ParseLong(BytesRef term);
// }
// public interface FieldCache_DoubleParser : FieldCache_Parser
// {
// /// <summary>
// /// Return an double representation of this field's value. </summary>
// double ParseDouble(BytesRef term);
// }
// public sealed class FieldCache_CacheEntry
// {
// private readonly object readerKey;
// private readonly string fieldName;
// private readonly Type cacheType;
// private readonly object custom;
// private readonly object value;
// private string Size;
// public FieldCache_CacheEntry(object readerKey, string fieldName, Type cacheType, object custom, object value)
// {
// this.readerKey = readerKey;
// this.fieldName = fieldName;
// this.cacheType = cacheType;
// this.custom = custom;
// this.value = value;
// }
// public object ReaderKey
// {
// get
// {
// return readerKey;
// }
// }
// public string FieldName
// {
// get
// {
// return fieldName;
// }
// }
// public Type CacheType
// {
// get
// {
// return cacheType;
// }
// }
// public object Custom
// {
// get
// {
// return custom;
// }
// }
// public object Value
// {
// get
// {
// return value;
// }
// }
// /// <summary>
// /// Computes (and stores) the estimated size of the cache Value </summary>
// /// <seealso cref= #getEstimatedSize </seealso>
// public void EstimateSize()
// {
// long bytesUsed = RamUsageEstimator.SizeOf(Value);
// Size = RamUsageEstimator.HumanReadableUnits(bytesUsed);
// }
// /// <summary>
// /// The most recently estimated size of the value, null unless
// /// estimateSize has been called.
// /// </summary>
// public string EstimatedSize
// {
// get
// {
// return Size;
// }
// }
// public override string ToString()
// {
// StringBuilder b = new StringBuilder();
// b.Append("'").Append(ReaderKey).Append("'=>");
// b.Append("'").Append(FieldName).Append("',");
// b.Append(CacheType).Append(",").Append(Custom);
// b.Append("=>").Append(Value.GetType().Name).Append("#");
// b.Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(Value));
// string s = EstimatedSize;
// if (null != s)
// {
// b.Append(" (size =~ ").Append(s).Append(')');
// }
// return b.ToString();
// }
}