| using Lucene.Net.Diagnostics; |
| using Lucene.Net.Index; |
| using Lucene.Net.Queries.Function; |
| using Lucene.Net.Search; |
| using System; |
| using System.Collections.Generic; |
| using System.Diagnostics; |
| using System.IO; |
| |
| namespace Lucene.Net.Expressions |
| { |
| /* |
| * 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. |
| */ |
| |
| /// <summary>A custom comparer for sorting documents by an expression</summary> |
| internal class ExpressionComparer : FieldComparer<double> |
| { |
| private readonly double[] values; |
| private double bottom; |
| private double topValue; |
| |
| private ValueSource source; |
| private FunctionValues scores; |
| private AtomicReaderContext readerContext; |
| |
| public ExpressionComparer(ValueSource source, int numHits) |
| { |
| values = new double[numHits]; |
| this.source = source; |
| } |
| |
| // TODO: change FieldComparer.setScorer to throw IOException and remove this try-catch |
| public override void SetScorer(Scorer scorer) |
| { |
| base.SetScorer(scorer); |
| // TODO: might be cleaner to lazy-init 'source' and set scorer after? |
| |
| if (Debugging.AssertsEnabled) Debugging.Assert(readerContext != null); |
| try |
| { |
| var context = new Dictionary<string, object>(); |
| if (Debugging.AssertsEnabled) Debugging.Assert(scorer != null); |
| context["scorer"] = scorer; |
| scores = source.GetValues(context, readerContext); |
| } |
| catch (IOException e) |
| { |
| throw new Exception(e.ToString(), e); |
| } |
| } |
| |
| public override int Compare(int slot1, int slot2) |
| { |
| return values[slot1].CompareTo(values[slot2]); |
| } |
| |
| public override void SetBottom(int slot) |
| { |
| bottom = values[slot]; |
| } |
| |
| public override void SetTopValue(object value) |
| { |
| topValue = (double)value; |
| } |
| |
| public override int CompareBottom(int doc) |
| { |
| return bottom.CompareTo(scores.DoubleVal(doc)); |
| } |
| |
| public override void Copy(int slot, int doc) |
| { |
| values[slot] = scores.DoubleVal(doc); |
| } |
| |
| public override FieldComparer SetNextReader(AtomicReaderContext context) |
| { |
| this.readerContext = context; |
| return this; |
| } |
| |
| // LUCENENET NOTE: This was value(int) in Lucene. |
| public override IComparable this[int slot] => values[slot]; |
| |
| public override int CompareTop(int doc) |
| { |
| return topValue.CompareTo(scores.DoubleVal(doc)); |
| } |
| } |
| } |