Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>3.0.54013</Version>
<FileVersion>3.0.54013.0</FileVersion>
<Version>3.0.54014</Version>
<FileVersion>3.0.54014.0</FileVersion>
<LangVersion>latest</LangVersion>
<DebugType>embedded</DebugType>

Expand Down
59 changes: 21 additions & 38 deletions src/Lucene.Net/Index/ArrayHolder.cs
Original file line number Diff line number Diff line change
@@ -1,51 +1,40 @@
using System;
using System.Buffers;
using System.Threading;
using Lucene.Net.Store;
using Lucene.Net.Util;

namespace Lucene.Net.Index
{
public class ArrayHolder : IDisposable
{
private readonly int _size;
private readonly Directory _directory;
private readonly string _name;
private readonly long[] _longArray;
private readonly TermInfo[] _termInfoArray;
private readonly IArray<long> _indexPointers;
private readonly IArray<TermInfo> _termInfos;
private readonly UnmanagedIndexTerms _unmanagedIndexTerms;

private int _usages;
private long _managedAllocations;

public Span<long> LongArray => _longArray.AsSpan(0, _size);
public Span<TermInfo> InfoArray => _termInfoArray.AsSpan(0, _size);
public IArray<long> IndexPointers => _indexPointers;
public IArray<TermInfo> TermInfos => _termInfos;
public UnmanagedIndexTerms UnmanagedIndexTerms => _unmanagedIndexTerms;
public int ActualArraySize => _longArray.Length;

public static Action<long> OnArrayHolderCreated;

public static Action<long> OnArrayHolderDisposed;

public const int ArrayPoolThreshold = 128 * 1024;
public long TotalManagedAllocations => _indexPointers.TotalManagedAllocations + _termInfos.TotalManagedAllocations + _unmanagedIndexTerms.TotalManagedAllocations;

public ArrayHolder(int size, Directory directory, string name)
public ArrayHolder(int size, Directory directory, string name, FieldInfos fieldInfos)
{
_size = size;
_directory = directory;
_name = name;

if (size > ArrayPoolThreshold)
{
_longArray = new long[size];
_termInfoArray = new TermInfo[size];
}
else
{
_longArray = ArrayPool<long>.Shared.Rent(size);
_termInfoArray = ArrayPool<TermInfo>.Shared.Rent(size);
}
_indexPointers = HybridArray.Create<long>(size, UnmanagedStringArray.Type.TermCache, clear: false);
_termInfos = HybridArray.Create<TermInfo>(size, UnmanagedStringArray.Type.TermCache, clear: false);

_unmanagedIndexTerms = new UnmanagedIndexTerms(size);
_unmanagedIndexTerms = new UnmanagedIndexTerms(size, fieldInfos);
}

public void AddRef()
Expand All @@ -67,20 +56,20 @@ public static ArrayHolder GenerateArrayHolder(Directory directory, string name,
{
int indexSize = 1 + ((int)indexEnum.size - 1) / indexDivisor; // otherwise read index

var holder = new ArrayHolder(indexSize, directory, name);
var holder = new ArrayHolder(indexSize, directory, name, fieldInfos);

for (int i = 0; indexEnum.Next(state); i++)
{
holder.UnmanagedIndexTerms.Add(i, indexEnum.Field, indexEnum.TextAsSpan);
holder.InfoArray[i] = indexEnum.TermInfo();
holder.LongArray[i] = indexEnum.indexPointer;
holder.UnmanagedIndexTerms.Add(i, indexEnum.FieldNumber, indexEnum.TextAsSpan);
holder.TermInfos[i] = indexEnum.TermInfo();
holder.IndexPointers[i] = indexEnum.indexPointer;

for (int j = 1; j < indexDivisor; j++)
if (!indexEnum.Next(state))
break;
}

holder._managedAllocations = (holder.ActualArraySize * (TermInfo.SizeOf + sizeof(long)));
holder._managedAllocations = holder.TotalManagedAllocations;

OnArrayHolderCreated?.Invoke(holder._managedAllocations);

Expand All @@ -98,18 +87,12 @@ public void Dispose()
{
GC.SuppressFinalize(this);

OnArrayHolderDisposed?.Invoke(_managedAllocations);

_unmanagedIndexTerms?.Dispose();

if (_size > ArrayPoolThreshold)
return;

if (_longArray != null)
ArrayPool<long>.Shared.Return(_longArray);

if (_termInfoArray != null)
ArrayPool<TermInfo>.Shared.Return(_termInfoArray);
using (_unmanagedIndexTerms)
using (_indexPointers)
using (_termInfos)
{
OnArrayHolderDisposed?.Invoke(_managedAllocations);
}
}

~ArrayHolder()
Expand Down
9 changes: 7 additions & 2 deletions src/Lucene.Net/Index/SegmentTermEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ public System.Object Clone(IState state)
return clone;
}

internal void Seek(long pointer, long p, Term t, TermInfo ti, IState state)
internal void Seek(long pointer, long p, (string Field, UnmanagedStringArray.UnmanagedString Text) tuple, TermInfo ti, IState state)
{
input.Seek(pointer, state);
position = p;
termBuffer.Set(t);
termBuffer.Set(tuple);
prevBuffer.Reset();
termInfo.Set(ti);
}
Expand Down Expand Up @@ -202,6 +202,11 @@ public string Field
get { return termBuffer.Field; }
}

public int FieldNumber
{
get { return termBuffer.FieldNumber; }
}

public Span<char> TextAsSpan
{
get { return termBuffer.TextAsSpan; }
Expand Down
9 changes: 5 additions & 4 deletions src/Lucene.Net/Index/Term.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

using System;
using System.Runtime.CompilerServices;
using Lucene.Net.Util;
using StringHelper = Lucene.Net.Util.StringHelper;

namespace Lucene.Net.Index
Expand Down Expand Up @@ -141,12 +142,12 @@ public int CompareTo(Term other)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int CompareTo(UnmanagedTerm other)
public int CompareTo((string Field, UnmanagedStringArray.UnmanagedString Text) tuple)
{
if (ReferenceEquals(field, other.Field))
return -other.Text.CompareTo(text);
if (ReferenceEquals(field, tuple.Field))
return -tuple.Text.CompareTo(text);

return String.CompareOrdinal(field, other.Field);
return String.CompareOrdinal(field, tuple.Field);
}

///// <summary>Resets the field and text of a Term. </summary>
Expand Down
28 changes: 22 additions & 6 deletions src/Lucene.Net/Index/TermBuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
* limitations under the License.
*/

using System;
using Lucene.Net.Store;
using Lucene.Net.Support;
using Lucene.Net.Util;
using System;
using IndexInput = Lucene.Net.Store.IndexInput;
using UnicodeUtil = Lucene.Net.Util.UnicodeUtil;

Expand All @@ -28,6 +29,7 @@ public sealed class TermBuffer : System.ICloneable
{

private System.String field;
private int fieldNumber = -1;
private Term term; // cached
private bool preUTF8Strings; // true if strings are stored in modified UTF8 encoding (LUCENE-510)
private bool dirty; // true if text was set externally (ie not read via UTF8 bytes)
Expand All @@ -37,6 +39,7 @@ public sealed class TermBuffer : System.ICloneable

public Span<char> TextAsSpan => new Span<char>(text.result, 0, text.length);
public string Field => field;
public int FieldNumber => fieldNumber;

public int CompareTo(TermBuffer other)
{
Expand Down Expand Up @@ -71,7 +74,7 @@ internal void SetPreUTF8Strings()
preUTF8Strings = true;
}

public void Read(IndexInput input, FieldInfos fieldInfos, IState state)
public void Read(IndexInput input, FieldInfos fieldInfos, IState state)
{
this.term = null; // invalidate cache
int start = input.ReadVInt(state);
Expand Down Expand Up @@ -102,10 +105,12 @@ public void Read(IndexInput input, FieldInfos fieldInfos, IState state)
UnicodeUtil.UTF8toUTF16(bytes.result, start, length, text);
}
}
this.field = fieldInfos.FieldName(input.ReadVInt(state));
}

this.fieldNumber = input.ReadVInt(state);
this.field = fieldInfos.FieldName(fieldNumber);
}

public void Set(Term term)
public void Set(Term term)
{
if (term == null)
{
Expand All @@ -121,17 +126,28 @@ public void Set(Term term)
this.term = term;
}

public void Set(TermBuffer other)
public void Set((string Field, UnmanagedStringArray.UnmanagedString Text) tuple)
{
text.SetLength(tuple.Text.Size);
TextSupport.GetCharsFromUnmanagedString(tuple.Text, text.result);
dirty = true;
field = tuple.Field;
term = null;
}

public void Set(TermBuffer other)
{
text.CopyText(other.text);
dirty = true;
field = other.field;
fieldNumber = other.fieldNumber;
term = other.term;
}

public void Reset()
{
field = null;
fieldNumber = -1;
text.SetLength(0);
term = null;
dirty = true;
Expand Down
2 changes: 0 additions & 2 deletions src/Lucene.Net/Index/TermInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ namespace Lucene.Net.Index

public struct TermInfo
{
public static int SizeOf = sizeof(int) + sizeof(long) + sizeof(long) + sizeof(int);

/// <summary>The number of documents which contain the term. </summary>
internal int docFreq;

Expand Down
32 changes: 13 additions & 19 deletions src/Lucene.Net/Index/TermInfosReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,13 @@ sealed class TermInfosReader : IDisposable
{
private readonly Directory directory;
private readonly String segment;
private readonly FieldInfos fieldInfos;

private bool isDisposed;

private readonly LightWeightThreadLocal<ThreadResources> threadResources = new LightWeightThreadLocal<ThreadResources>();
private readonly SegmentTermEnum origEnum;
private readonly long size;

private UnmanagedIndexTerms unmanagedIndexTerms => _termsIndexCache.UnmanagedIndexTerms;
private Span<TermInfo> indexInfos => _termsIndexCache.InfoArray;
private Span<long> indexPointers =>_termsIndexCache.LongArray;

private readonly int totalIndexInterval;

private const int DEFAULT_CACHE_SIZE = 1024;
Expand Down Expand Up @@ -101,16 +96,15 @@ internal TermInfosReader(Directory dir, System.String seg, FieldInfos fis, int r
{
directory = dir;
segment = seg;
fieldInfos = fis;

origEnum = new SegmentTermEnum(directory.OpenInput(segment + "." + IndexFileNames.TERMS_EXTENSION, readBufferSize, state), fieldInfos, false, state);
origEnum = new SegmentTermEnum(directory.OpenInput(segment + "." + IndexFileNames.TERMS_EXTENSION, readBufferSize, state), fis, false, state);
size = origEnum.size;

if (indexDivisor != - 1)
{
// Load terms index
totalIndexInterval = origEnum.indexInterval * indexDivisor;
_termsIndexCache = directory.GetCache(segment + "." + IndexFileNames.TERMS_INDEX_EXTENSION, fieldInfos, readBufferSize, indexDivisor, state);
_termsIndexCache = directory.GetCache(segment + "." + IndexFileNames.TERMS_INDEX_EXTENSION, fis, readBufferSize, indexDivisor, state);
_termsIndexCache.AddRef();
}
else
Expand Down Expand Up @@ -197,7 +191,7 @@ private ThreadResources GetThreadResources(IState state)
private unsafe int GetIndexOffset(Term term)
{
int lo = 0; // binary search unmanagedIndexTerms[]
int hi = unmanagedIndexTerms.Length - 1;
int hi = _termsIndexCache.UnmanagedIndexTerms.Length - 1;

byte[] arr = null;
Span<byte> stringAsBytes;
Expand All @@ -223,7 +217,7 @@ private unsafe int GetIndexOffset(Term term)
while (hi >= lo)
{
int mid = Number.URShift((lo + hi), 1);
int delta = CompareTerms(term.Field, stringAsBytes, stringAsSpan, unmanagedIndexTerms[mid]);
int delta = CompareTerms(term.Field, stringAsBytes, stringAsSpan, _termsIndexCache.UnmanagedIndexTerms[mid]);
if (delta < 0)
hi = mid - 1;
else if (delta > 0)
Expand All @@ -241,12 +235,12 @@ private unsafe int GetIndexOffset(Term term)
}
}

private static int CompareTerms(string field, Span<byte> stringAsBytes, ReadOnlySpan<char> stringAsChar, UnmanagedTerm unmanagedTerm)
private static int CompareTerms(string field, Span<byte> stringAsBytes, ReadOnlySpan<char> stringAsChar, (string Field, UnmanagedString Text) tuple)
{
if (ReferenceEquals(field, unmanagedTerm.Field))
return UnmanagedString.CompareOrdinal(stringAsBytes, stringAsChar, unmanagedTerm.Text);
if (ReferenceEquals(field, tuple.Field))
return UnmanagedString.CompareOrdinal(stringAsBytes, stringAsChar, tuple.Text);

return String.CompareOrdinal(field, unmanagedTerm.Field);
return String.CompareOrdinal(field, tuple.Field);
}

internal static Term DeepCopyOf(Term other)
Expand All @@ -257,8 +251,8 @@ internal static Term DeepCopyOf(Term other)
}

private void SeekEnum(SegmentTermEnum enumerator, int indexOffset, IState state)
{
enumerator.Seek(indexPointers[indexOffset], ((long)indexOffset * totalIndexInterval) - 1, unmanagedIndexTerms[indexOffset].ToTerm(), indexInfos[indexOffset], state);
{
enumerator.Seek(_termsIndexCache.IndexPointers[indexOffset], ((long)indexOffset * totalIndexInterval) - 1, _termsIndexCache.UnmanagedIndexTerms[indexOffset], _termsIndexCache.TermInfos[indexOffset], state);
}

/// <summary>Returns the TermInfo for a Term in the set, or null. </summary>
Expand Down Expand Up @@ -295,7 +289,7 @@ private TermInfo Get(Term term, bool useCache, IState state)
if (enumerator.Term != null && ((enumerator.Prev() != null && term.CompareTo(enumerator.Prev()) > 0) || term.CompareTo(enumerator.Term) >= 0))
{
int enumOffset = (int) (enumerator.position / totalIndexInterval) + 1;
if (unmanagedIndexTerms.Length == enumOffset || term.CompareTo(unmanagedIndexTerms[enumOffset]) < 0)
if (_termsIndexCache.UnmanagedIndexTerms.Length == enumOffset || term.CompareTo(_termsIndexCache.UnmanagedIndexTerms[enumOffset]) < 0)
{
// no need to seek

Expand Down Expand Up @@ -340,9 +334,9 @@ private TermInfo Get(Term term, bool useCache, IState state)
return ti;
}

private void EnsureIndexIsRead()
private void EnsureIndexIsRead()
{
if (unmanagedIndexTerms == null)
if (_termsIndexCache.UnmanagedIndexTerms == null)
{
throw new SystemException("terms index was not loaded when this reader was created");
}
Expand Down
Loading
Loading