blob: 6852168f5be0c6e6f771760f030506e452a71c7c [file] [log] [blame]
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace Lucene.Net.Index
{
using System;
/*
* 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 BytesRef = Lucene.Net.Util.BytesRef;
using CompiledAutomaton = Lucene.Net.Util.Automaton.CompiledAutomaton;
/// <summary>
/// Exposes flex API, merged from flex API of
/// sub-segments.
///
/// @lucene.experimental
/// </summary>
public sealed class MultiTerms : Terms
{
private readonly Terms[] Subs;
private readonly ReaderSlice[] SubSlices;
private readonly IComparer<BytesRef> TermComp;
private readonly bool HasFreqs_Renamed;
private readonly bool HasOffsets_Renamed;
private readonly bool HasPositions_Renamed;
private readonly bool HasPayloads_Renamed;
/// <summary>
/// Sole constructor.
/// </summary>
/// <param name="subs"> The <seealso cref="Terms"/> instances of all sub-readers. </param>
/// <param name="subSlices"> A parallel array (matching {@code
/// subs}) describing the sub-reader slices. </param>
public MultiTerms(Terms[] subs, ReaderSlice[] subSlices)
{
this.Subs = subs;
this.SubSlices = subSlices;
IComparer<BytesRef> _termComp = null;
Debug.Assert(subs.Length > 0, "inefficient: don't use MultiTerms over one sub");
bool _hasFreqs = true;
bool _hasOffsets = true;
bool _hasPositions = true;
bool _hasPayloads = false;
for (int i = 0; i < subs.Length; i++)
{
if (_termComp == null)
{
_termComp = subs[i].Comparator;
}
else
{
// We cannot merge sub-readers that have
// different TermComps
IComparer<BytesRef> subTermComp = subs[i].Comparator;
if (subTermComp != null && !subTermComp.Equals(_termComp))
{
throw new InvalidOperationException("sub-readers have different BytesRef.Comparators; cannot merge");
}
}
_hasFreqs &= subs[i].HasFreqs();
_hasOffsets &= subs[i].HasOffsets();
_hasPositions &= subs[i].HasPositions();
_hasPayloads |= subs[i].HasPayloads();
}
TermComp = _termComp;
HasFreqs_Renamed = _hasFreqs;
HasOffsets_Renamed = _hasOffsets;
HasPositions_Renamed = _hasPositions;
HasPayloads_Renamed = HasPositions_Renamed && _hasPayloads; // if all subs have pos, and at least one has payloads.
}
public override TermsEnum Intersect(CompiledAutomaton compiled, BytesRef startTerm)
{
IList<MultiTermsEnum.TermsEnumIndex> termsEnums = new List<MultiTermsEnum.TermsEnumIndex>();
for (int i = 0; i < Subs.Length; i++)
{
TermsEnum termsEnum = Subs[i].Intersect(compiled, startTerm);
if (termsEnum != null)
{
termsEnums.Add(new MultiTermsEnum.TermsEnumIndex(termsEnum, i));
}
}
if (termsEnums.Count > 0)
{
return (new MultiTermsEnum(SubSlices)).Reset(termsEnums.ToArray(/*MultiTermsEnum.TermsEnumIndex.EMPTY_ARRAY*/));
}
else
{
return TermsEnum.EMPTY;
}
}
public override TermsEnum Iterator(TermsEnum reuse)
{
IList<MultiTermsEnum.TermsEnumIndex> termsEnums = new List<MultiTermsEnum.TermsEnumIndex>();
for (int i = 0; i < Subs.Length; i++)
{
TermsEnum termsEnum = Subs[i].Iterator(null);
if (termsEnum != null)
{
termsEnums.Add(new MultiTermsEnum.TermsEnumIndex(termsEnum, i));
}
}
if (termsEnums.Count > 0)
{
return (new MultiTermsEnum(SubSlices)).Reset(termsEnums.ToArray(/*MultiTermsEnum.TermsEnumIndex.EMPTY_ARRAY*/));
}
else
{
return TermsEnum.EMPTY;
}
}
public override long Size()
{
return -1;
}
public override long SumTotalTermFreq
{
get
{
long sum = 0;
foreach (Terms terms in Subs)
{
long v = terms.SumTotalTermFreq;
if (v == -1)
{
return -1;
}
sum += v;
}
return sum;
}
}
public override long SumDocFreq
{
get
{
long sum = 0;
foreach (Terms terms in Subs)
{
long v = terms.SumDocFreq;
if (v == -1)
{
return -1;
}
sum += v;
}
return sum;
}
}
public override int DocCount
{
get
{
int sum = 0;
foreach (Terms terms in Subs)
{
int v = terms.DocCount;
if (v == -1)
{
return -1;
}
sum += v;
}
return sum;
}
}
public override IComparer<BytesRef> Comparator
{
get
{
return TermComp;
}
}
public override bool HasFreqs()
{
return HasFreqs_Renamed;
}
public override bool HasOffsets()
{
return HasOffsets_Renamed;
}
public override bool HasPositions()
{
return HasPositions_Renamed;
}
public override bool HasPayloads()
{
return HasPayloads_Renamed;
}
}
}