blob: 038a5695b3244a169268a6b29e67f779f5f9e083 [file] [log] [blame]
using J2N.Threading.Atomic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
namespace Lucene.Net.Codecs.Lucene40
{
/*
* 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 BinaryDocValues = Lucene.Net.Index.BinaryDocValues;
using IBits = Lucene.Net.Util.IBits;
using BytesRef = Lucene.Net.Util.BytesRef;
using CompoundFileDirectory = Lucene.Net.Store.CompoundFileDirectory;
using CorruptIndexException = Lucene.Net.Index.CorruptIndexException;
using Directory = Lucene.Net.Store.Directory;
using FieldInfo = Lucene.Net.Index.FieldInfo;
using IndexFileNames = Lucene.Net.Index.IndexFileNames;
using IndexInput = Lucene.Net.Store.IndexInput;
using IOUtils = Lucene.Net.Util.IOUtils;
//using LegacyDocValuesType = Lucene.Net.Codecs.Lucene40.LegacyDocValuesType;
using NumericDocValues = Lucene.Net.Index.NumericDocValues;
using PackedInt32s = Lucene.Net.Util.Packed.PackedInt32s;
using PagedBytes = Lucene.Net.Util.PagedBytes;
using RamUsageEstimator = Lucene.Net.Util.RamUsageEstimator;
using SegmentReadState = Lucene.Net.Index.SegmentReadState;
using SortedDocValues = Lucene.Net.Index.SortedDocValues;
using SortedSetDocValues = Lucene.Net.Index.SortedSetDocValues;
/// <summary>
/// Reads the 4.0 format of norms/docvalues.
/// <para/>
/// @lucene.experimental
/// </summary>
[Obsolete("Only for reading old 4.0 and 4.1 segments")]
internal sealed class Lucene40DocValuesReader : DocValuesProducer
{
private readonly Directory dir;
private readonly SegmentReadState state;
private readonly string legacyKey;
private const string segmentSuffix = "dv";
// ram instances we have already loaded
private readonly IDictionary<int, NumericDocValues> numericInstances = new Dictionary<int, NumericDocValues>();
private readonly IDictionary<int, BinaryDocValues> binaryInstances = new Dictionary<int, BinaryDocValues>();
private readonly IDictionary<int, SortedDocValues> sortedInstances = new Dictionary<int, SortedDocValues>();
private readonly AtomicInt64 ramBytesUsed;
internal Lucene40DocValuesReader(SegmentReadState state, string filename, string legacyKey)
{
this.state = state;
this.legacyKey = legacyKey;
this.dir = new CompoundFileDirectory(state.Directory, filename, state.Context, false);
ramBytesUsed = new AtomicInt64(RamUsageEstimator.ShallowSizeOf(this.GetType()));
}
public override NumericDocValues GetNumeric(FieldInfo field)
{
lock (this)
{
if (!numericInstances.TryGetValue(field.Number, out NumericDocValues instance))
{
string fileName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
IndexInput input = dir.OpenInput(fileName, state.Context);
bool success = false;
try
{
var type = field.GetAttribute(legacyKey).ToLegacyDocValuesType();
//switch (Enum.Parse(typeof(LegacyDocValuesType), field.GetAttribute(LegacyKey)))
//{
if (type == LegacyDocValuesType.VAR_INTS)
{
instance = LoadVarInt32sField(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FIXED_INTS_8)
{
instance = LoadByteField(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FIXED_INTS_16)
{
instance = LoadInt16Field(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FIXED_INTS_32)
{
instance = LoadInt32Field(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FIXED_INTS_64)
{
instance = LoadInt64Field(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FLOAT_32)
{
instance = LoadSingleField(/* field, // LUCENENET: Never read */ input);
}
else if (type == LegacyDocValuesType.FLOAT_64)
{
instance = LoadDoubleField(/* field, // LUCENENET: Never read */ input);
}
else
{
throw new InvalidOperationException();
}
CodecUtil.CheckEOF(input);
success = true;
}
finally
{
if (success)
{
IOUtils.Dispose(input);
}
else
{
IOUtils.DisposeWhileHandlingException(input);
}
}
numericInstances[field.Number] = instance;
}
return instance;
}
}
/// <summary>
/// NOTE: This was loadVarIntsField() in Lucene.
/// </summary>
private NumericDocValues LoadVarInt32sField(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.VAR_INTS_CODEC_NAME, Lucene40DocValuesFormat.VAR_INTS_VERSION_START, Lucene40DocValuesFormat.VAR_INTS_VERSION_CURRENT);
var header = (sbyte)input.ReadByte();
if (header == Lucene40DocValuesFormat.VAR_INTS_FIXED_64)
{
int maxDoc = state.SegmentInfo.DocCount;
var values = new long[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt64();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass(values);
}
else if (header == Lucene40DocValuesFormat.VAR_INTS_PACKED)
{
long minValue = input.ReadInt64();
long defaultValue = input.ReadInt64();
PackedInt32s.Reader reader = PackedInt32s.GetReader(input);
ramBytesUsed.AddAndGet(reader.RamBytesUsed());
return new NumericDocValuesAnonymousClass2(minValue, defaultValue, reader);
}
else
{
throw new CorruptIndexException("invalid VAR_INTS header byte: " + header + " (resource=" + input + ")");
}
}
private class NumericDocValuesAnonymousClass : NumericDocValues
{
private readonly long[] values;
public NumericDocValuesAnonymousClass(long[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
private class NumericDocValuesAnonymousClass2 : NumericDocValues
{
private readonly long minValue;
private readonly long defaultValue;
private readonly PackedInt32s.Reader reader;
public NumericDocValuesAnonymousClass2(long minValue, long defaultValue, PackedInt32s.Reader reader)
{
this.minValue = minValue;
this.defaultValue = defaultValue;
this.reader = reader;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
long value = reader.Get(docID);
if (value == defaultValue)
{
return 0;
}
else
{
return minValue + value;
}
}
}
private NumericDocValues LoadByteField(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.INTS_CODEC_NAME, Lucene40DocValuesFormat.INTS_VERSION_START, Lucene40DocValuesFormat.INTS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 1)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
var values = new byte[maxDoc];
input.ReadBytes(values, 0, values.Length);
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass3(values);
}
private class NumericDocValuesAnonymousClass3 : NumericDocValues
{
private readonly byte[] values;
public NumericDocValuesAnonymousClass3(byte[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return (sbyte)values[docID];
}
}
/// <summary>
/// NOTE: This was loadShortField() in Lucene.
/// </summary>
private NumericDocValues LoadInt16Field(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.INTS_CODEC_NAME, Lucene40DocValuesFormat.INTS_VERSION_START, Lucene40DocValuesFormat.INTS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 2)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
short[] values = new short[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt16();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass4(values);
}
private class NumericDocValuesAnonymousClass4 : NumericDocValues
{
private readonly short[] values;
public NumericDocValuesAnonymousClass4(short[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
/// <summary>
/// NOTE: This was loadIntField() in Lucene.
/// </summary>
private NumericDocValues LoadInt32Field(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.INTS_CODEC_NAME, Lucene40DocValuesFormat.INTS_VERSION_START, Lucene40DocValuesFormat.INTS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 4)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
var values = new int[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt32();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass5(values);
}
private class NumericDocValuesAnonymousClass5 : NumericDocValues
{
private readonly int[] values;
public NumericDocValuesAnonymousClass5(int[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
/// <summary>
/// NOTE: This was loadLongField() in Lucene.
/// </summary>
private NumericDocValues LoadInt64Field(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.INTS_CODEC_NAME, Lucene40DocValuesFormat.INTS_VERSION_START, Lucene40DocValuesFormat.INTS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 8)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
long[] values = new long[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt64();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass6(values);
}
private class NumericDocValuesAnonymousClass6 : NumericDocValues
{
private readonly long[] values;
public NumericDocValuesAnonymousClass6(long[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
/// <summary>
/// NOTE: This was loadFloatField() in Lucene.
/// </summary>
private NumericDocValues LoadSingleField(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.FLOATS_CODEC_NAME, Lucene40DocValuesFormat.FLOATS_VERSION_START, Lucene40DocValuesFormat.FLOATS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 4)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
int[] values = new int[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt32();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass7(values);
}
private class NumericDocValuesAnonymousClass7 : NumericDocValues
{
private readonly int[] values;
public NumericDocValuesAnonymousClass7(int[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
private NumericDocValues LoadDoubleField(/*FieldInfo field, // LUCENENET: Never read */ IndexInput input)
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.FLOATS_CODEC_NAME, Lucene40DocValuesFormat.FLOATS_VERSION_START, Lucene40DocValuesFormat.FLOATS_VERSION_CURRENT);
int valueSize = input.ReadInt32();
if (valueSize != 8)
{
throw new CorruptIndexException("invalid valueSize: " + valueSize);
}
int maxDoc = state.SegmentInfo.DocCount;
long[] values = new long[maxDoc];
for (int i = 0; i < values.Length; i++)
{
values[i] = input.ReadInt64();
}
ramBytesUsed.AddAndGet(RamUsageEstimator.SizeOf(values));
return new NumericDocValuesAnonymousClass8(values);
}
private class NumericDocValuesAnonymousClass8 : NumericDocValues
{
private readonly long[] values;
public NumericDocValuesAnonymousClass8(long[] values)
{
this.values = values;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override long Get(int docID)
{
return values[docID];
}
}
public override BinaryDocValues GetBinary(FieldInfo field)
{
lock (this)
{
if (!binaryInstances.TryGetValue(field.Number, out BinaryDocValues instance))
{
var type = field.GetAttribute(legacyKey).ToLegacyDocValuesType();
if (type == LegacyDocValuesType.BYTES_FIXED_STRAIGHT)
{
instance = LoadBytesFixedStraight(field);
}
else if (type == LegacyDocValuesType.BYTES_VAR_STRAIGHT)
{
instance = LoadBytesVarStraight(field);
}
else if (type == LegacyDocValuesType.BYTES_FIXED_DEREF)
{
instance = LoadBytesFixedDeref(field);
}
else if (type == LegacyDocValuesType.BYTES_VAR_DEREF)
{
instance = LoadBytesVarDeref(field);
}
else
{
throw new InvalidOperationException();
}
binaryInstances[field.Number] = instance;
}
return instance;
}
}
private BinaryDocValues LoadBytesFixedStraight(FieldInfo field)
{
string fileName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
IndexInput input = dir.OpenInput(fileName, state.Context);
bool success = false;
try
{
CodecUtil.CheckHeader(input, Lucene40DocValuesFormat.BYTES_FIXED_STRAIGHT_CODEC_NAME, Lucene40DocValuesFormat.BYTES_FIXED_STRAIGHT_VERSION_START, Lucene40DocValuesFormat.BYTES_FIXED_STRAIGHT_VERSION_CURRENT);
int fixedLength = input.ReadInt32();
var bytes = new PagedBytes(16);
bytes.Copy(input, fixedLength * (long)state.SegmentInfo.DocCount);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
CodecUtil.CheckEOF(input);
success = true;
ramBytesUsed.AddAndGet(bytes.RamBytesUsed());
return new BinaryDocValuesAnonymousClass(fixedLength, bytesReader);
}
finally
{
if (success)
{
IOUtils.Dispose(input);
}
else
{
IOUtils.DisposeWhileHandlingException(input);
}
}
}
private class BinaryDocValuesAnonymousClass : BinaryDocValues
{
private readonly int fixedLength;
private readonly PagedBytes.Reader bytesReader;
public BinaryDocValuesAnonymousClass(int fixedLength, PagedBytes.Reader bytesReader)
{
this.fixedLength = fixedLength;
this.bytesReader = bytesReader;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Get(int docID, BytesRef result)
{
bytesReader.FillSlice(result, fixedLength * (long)docID, fixedLength);
}
}
private BinaryDocValues LoadBytesVarStraight(FieldInfo field)
{
string dataName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
string indexName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "idx");
IndexInput data = null;
IndexInput index = null;
bool success = false;
try
{
data = dir.OpenInput(dataName, state.Context);
CodecUtil.CheckHeader(data, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_CODEC_NAME_DAT, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_VERSION_CURRENT);
index = dir.OpenInput(indexName, state.Context);
CodecUtil.CheckHeader(index, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_CODEC_NAME_IDX, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_STRAIGHT_VERSION_CURRENT);
long totalBytes = index.ReadVInt64();
PagedBytes bytes = new PagedBytes(16);
bytes.Copy(data, totalBytes);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
PackedInt32s.Reader reader = PackedInt32s.GetReader(index);
CodecUtil.CheckEOF(data);
CodecUtil.CheckEOF(index);
success = true;
ramBytesUsed.AddAndGet(bytes.RamBytesUsed() + reader.RamBytesUsed());
return new BinaryDocValuesAnonymousClass2(bytesReader, reader);
}
finally
{
if (success)
{
IOUtils.Dispose(data, index);
}
else
{
IOUtils.DisposeWhileHandlingException(data, index);
}
}
}
private class BinaryDocValuesAnonymousClass2 : BinaryDocValues
{
private readonly PagedBytes.Reader bytesReader;
private readonly PackedInt32s.Reader reader;
public BinaryDocValuesAnonymousClass2(PagedBytes.Reader bytesReader, PackedInt32s.Reader reader)
{
this.bytesReader = bytesReader;
this.reader = reader;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Get(int docID, BytesRef result)
{
long startAddress = reader.Get(docID);
long endAddress = reader.Get(docID + 1);
bytesReader.FillSlice(result, startAddress, (int)(endAddress - startAddress));
}
}
private BinaryDocValues LoadBytesFixedDeref(FieldInfo field)
{
string dataName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
string indexName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "idx");
IndexInput data = null;
IndexInput index = null;
bool success = false;
try
{
data = dir.OpenInput(dataName, state.Context);
CodecUtil.CheckHeader(data, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_CODEC_NAME_DAT, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_VERSION_START, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_VERSION_CURRENT);
index = dir.OpenInput(indexName, state.Context);
CodecUtil.CheckHeader(index, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_CODEC_NAME_IDX, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_VERSION_START, Lucene40DocValuesFormat.BYTES_FIXED_DEREF_VERSION_CURRENT);
int fixedLength = data.ReadInt32();
int valueCount = index.ReadInt32();
PagedBytes bytes = new PagedBytes(16);
bytes.Copy(data, fixedLength * (long)valueCount);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
PackedInt32s.Reader reader = PackedInt32s.GetReader(index);
CodecUtil.CheckEOF(data);
CodecUtil.CheckEOF(index);
ramBytesUsed.AddAndGet(bytes.RamBytesUsed() + reader.RamBytesUsed());
success = true;
return new BinaryDocValuesAnonymousClass3(fixedLength, bytesReader, reader);
}
finally
{
if (success)
{
IOUtils.Dispose(data, index);
}
else
{
IOUtils.DisposeWhileHandlingException(data, index);
}
}
}
private class BinaryDocValuesAnonymousClass3 : BinaryDocValues
{
private readonly int fixedLength;
private readonly PagedBytes.Reader bytesReader;
private readonly PackedInt32s.Reader reader;
public BinaryDocValuesAnonymousClass3(int fixedLength, PagedBytes.Reader bytesReader, PackedInt32s.Reader reader)
{
this.fixedLength = fixedLength;
this.bytesReader = bytesReader;
this.reader = reader;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void Get(int docID, BytesRef result)
{
long offset = fixedLength * reader.Get(docID);
bytesReader.FillSlice(result, offset, fixedLength);
}
}
private BinaryDocValues LoadBytesVarDeref(FieldInfo field)
{
string dataName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
string indexName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "idx");
IndexInput data = null;
IndexInput index = null;
bool success = false;
try
{
data = dir.OpenInput(dataName, state.Context);
CodecUtil.CheckHeader(data, Lucene40DocValuesFormat.BYTES_VAR_DEREF_CODEC_NAME_DAT, Lucene40DocValuesFormat.BYTES_VAR_DEREF_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_DEREF_VERSION_CURRENT);
index = dir.OpenInput(indexName, state.Context);
CodecUtil.CheckHeader(index, Lucene40DocValuesFormat.BYTES_VAR_DEREF_CODEC_NAME_IDX, Lucene40DocValuesFormat.BYTES_VAR_DEREF_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_DEREF_VERSION_CURRENT);
long totalBytes = index.ReadInt64();
PagedBytes bytes = new PagedBytes(16);
bytes.Copy(data, totalBytes);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
PackedInt32s.Reader reader = PackedInt32s.GetReader(index);
CodecUtil.CheckEOF(data);
CodecUtil.CheckEOF(index);
ramBytesUsed.AddAndGet(bytes.RamBytesUsed() + reader.RamBytesUsed());
success = true;
return new BinaryDocValuesAnonymousClass4(bytesReader, reader);
}
finally
{
if (success)
{
IOUtils.Dispose(data, index);
}
else
{
IOUtils.DisposeWhileHandlingException(data, index);
}
}
}
private class BinaryDocValuesAnonymousClass4 : BinaryDocValues
{
private readonly PagedBytes.Reader bytesReader;
private readonly PackedInt32s.Reader reader;
public BinaryDocValuesAnonymousClass4(PagedBytes.Reader bytesReader, PackedInt32s.Reader reader)
{
this.bytesReader = bytesReader;
this.reader = reader;
}
public override void Get(int docID, BytesRef result)
{
long startAddress = reader.Get(docID);
BytesRef lengthBytes = new BytesRef();
bytesReader.FillSlice(lengthBytes, startAddress, 1);
var code = lengthBytes.Bytes[lengthBytes.Offset];
if ((code & 128) == 0)
{
// length is 1 byte
bytesReader.FillSlice(result, startAddress + 1, (int)code);
}
else
{
bytesReader.FillSlice(lengthBytes, startAddress + 1, 1);
int length = ((code & 0x7f) << 8) | (lengthBytes.Bytes[lengthBytes.Offset] & 0xff);
bytesReader.FillSlice(result, startAddress + 2, length);
}
}
}
public override SortedDocValues GetSorted(FieldInfo field)
{
lock (this)
{
if (!sortedInstances.TryGetValue(field.Number, out SortedDocValues instance))
{
string dataName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "dat");
string indexName = IndexFileNames.SegmentFileName(state.SegmentInfo.Name + "_" + Convert.ToString(field.Number, CultureInfo.InvariantCulture), segmentSuffix, "idx");
IndexInput data = null;
IndexInput index = null;
bool success = false;
try
{
data = dir.OpenInput(dataName, state.Context);
index = dir.OpenInput(indexName, state.Context);
var type = field.GetAttribute(legacyKey).ToLegacyDocValuesType();
if (type == LegacyDocValuesType.BYTES_FIXED_SORTED)
{
instance = LoadBytesFixedSorted(/* field, // LUCENENET: Never read */ data, index);
}
else if (type == LegacyDocValuesType.BYTES_VAR_SORTED)
{
instance = LoadBytesVarSorted(/* field, // LUCENENET: Never read */ data, index);
}
else
{
throw new InvalidOperationException();
}
CodecUtil.CheckEOF(data);
CodecUtil.CheckEOF(index);
success = true;
}
finally
{
if (success)
{
IOUtils.Dispose(data, index);
}
else
{
IOUtils.DisposeWhileHandlingException(data, index);
}
}
sortedInstances[field.Number] = instance;
}
return instance;
}
}
private SortedDocValues LoadBytesFixedSorted(/*FieldInfo field, // LUCENENET: Never read */ IndexInput data, IndexInput index)
{
CodecUtil.CheckHeader(data, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_CODEC_NAME_DAT, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_VERSION_START, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_VERSION_CURRENT);
CodecUtil.CheckHeader(index, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_CODEC_NAME_IDX, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_VERSION_START, Lucene40DocValuesFormat.BYTES_FIXED_SORTED_VERSION_CURRENT);
int fixedLength = data.ReadInt32();
int valueCount = index.ReadInt32();
PagedBytes bytes = new PagedBytes(16);
bytes.Copy(data, fixedLength * (long)valueCount);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
PackedInt32s.Reader reader = PackedInt32s.GetReader(index);
ramBytesUsed.AddAndGet(bytes.RamBytesUsed() + reader.RamBytesUsed());
return CorrectBuggyOrds(new SortedDocValuesAnonymousClass(fixedLength, valueCount, bytesReader, reader));
}
private class SortedDocValuesAnonymousClass : SortedDocValues
{
private readonly int fixedLength;
private readonly int valueCount;
private readonly PagedBytes.Reader bytesReader;
private readonly PackedInt32s.Reader reader;
public SortedDocValuesAnonymousClass(int fixedLength, int valueCount, PagedBytes.Reader bytesReader, PackedInt32s.Reader reader)
{
this.fixedLength = fixedLength;
this.valueCount = valueCount;
this.bytesReader = bytesReader;
this.reader = reader;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetOrd(int docID)
{
return (int)reader.Get(docID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void LookupOrd(int ord, BytesRef result)
{
bytesReader.FillSlice(result, fixedLength * (long)ord, fixedLength);
}
public override int ValueCount => valueCount;
}
private SortedDocValues LoadBytesVarSorted(/*FieldInfo field, // LUCENENET: Never read */ IndexInput data, IndexInput index)
{
CodecUtil.CheckHeader(data, Lucene40DocValuesFormat.BYTES_VAR_SORTED_CODEC_NAME_DAT, Lucene40DocValuesFormat.BYTES_VAR_SORTED_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_SORTED_VERSION_CURRENT);
CodecUtil.CheckHeader(index, Lucene40DocValuesFormat.BYTES_VAR_SORTED_CODEC_NAME_IDX, Lucene40DocValuesFormat.BYTES_VAR_SORTED_VERSION_START, Lucene40DocValuesFormat.BYTES_VAR_SORTED_VERSION_CURRENT);
long maxAddress = index.ReadInt64();
PagedBytes bytes = new PagedBytes(16);
bytes.Copy(data, maxAddress);
PagedBytes.Reader bytesReader = bytes.Freeze(true);
PackedInt32s.Reader addressReader = PackedInt32s.GetReader(index);
PackedInt32s.Reader ordsReader = PackedInt32s.GetReader(index);
int valueCount = addressReader.Count - 1;
ramBytesUsed.AddAndGet(bytes.RamBytesUsed() + addressReader.RamBytesUsed() + ordsReader.RamBytesUsed());
return CorrectBuggyOrds(new SortedDocValuesAnonymousClass2(bytesReader, addressReader, ordsReader, valueCount));
}
private class SortedDocValuesAnonymousClass2 : SortedDocValues
{
private readonly PagedBytes.Reader bytesReader;
private readonly PackedInt32s.Reader addressReader;
private readonly PackedInt32s.Reader ordsReader;
private readonly int valueCount;
public SortedDocValuesAnonymousClass2(PagedBytes.Reader bytesReader, PackedInt32s.Reader addressReader, PackedInt32s.Reader ordsReader, int valueCount)
{
this.bytesReader = bytesReader;
this.addressReader = addressReader;
this.ordsReader = ordsReader;
this.valueCount = valueCount;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetOrd(int docID)
{
return (int)ordsReader.Get(docID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void LookupOrd(int ord, BytesRef result)
{
long startAddress = addressReader.Get(ord);
long endAddress = addressReader.Get(ord + 1);
bytesReader.FillSlice(result, startAddress, (int)(endAddress - startAddress));
}
public override int ValueCount => valueCount;
}
// detects and corrects LUCENE-4717 in old indexes
private SortedDocValues CorrectBuggyOrds(SortedDocValues @in)
{
int maxDoc = state.SegmentInfo.DocCount;
for (int i = 0; i < maxDoc; i++)
{
if (@in.GetOrd(i) == 0)
{
return @in; // ok
}
}
// we had ord holes, return an ord-shifting-impl that corrects the bug
return new SortedDocValuesAnonymousClass3(@in);
}
private class SortedDocValuesAnonymousClass3 : SortedDocValues
{
private readonly SortedDocValues @in;
public SortedDocValuesAnonymousClass3(SortedDocValues @in)
{
this.@in = @in;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetOrd(int docID)
{
return @in.GetOrd(docID) - 1;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void LookupOrd(int ord, BytesRef result)
{
@in.LookupOrd(ord + 1, result);
}
public override int ValueCount => @in.ValueCount - 1;
}
public override SortedSetDocValues GetSortedSet(FieldInfo field)
{
throw new InvalidOperationException("Lucene 4.0 does not support SortedSet: how did you pull this off?");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override IBits GetDocsWithField(FieldInfo field)
{
return new Lucene.Net.Util.Bits.MatchAllBits(state.SegmentInfo.DocCount);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void Dispose(bool disposing)
{
if (disposing)
{
dir.Dispose();
}
}
public override long RamBytesUsed() => ramBytesUsed;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override void CheckIntegrity() { }
}
}