Skip to content

Commit 57e0b8c

Browse files
paulirwinCopilot
andauthored
BREAKING: Add cancellation support to IndexSearcher, apache#922 (apache#1080)
* Add CancellationToken parameter to IndexSearcher methods, apache#922 * Pass cancellation token and throw if requested, apache#922 * Pass cancellation token further down in multithreaded code, apache#922 * PR feedback * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add unit tests for cancellation support --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent e4d5f41 commit 57e0b8c

19 files changed

Lines changed: 493 additions & 119 deletions

src/Lucene.Net.Grouping/package.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,4 @@ int maxDoc = s.MaxDoc;
166166
FixedBitSet groupHeadsBitSet = c.RetrieveGroupHeads(maxDoc);
167167
```
168168

169-
For each of the above collector types there is also a variant that works with `ValueSource` instead of of fields. Concretely this means that these variants can work with functions. These variants are slower than there term based counter parts. These implementations are located in the `Lucene.Net.Search.Grouping.Function` package, but can also be used with the `GroupingSearch` convenience utility
169+
For each of the above collector types there is also a variant that works with `ValueSource` instead of fields. Concretely, this means that these variants can work with functions. These variants are slower than their term-based counterparts. These implementations are located in the `Lucene.Net.Search.Grouping.Function` package, but can also be used with the `GroupingSearch` convenience utility.

src/Lucene.Net.Misc/Index/Sorter/BlockJoinComparatorSource.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using Lucene.Net.Util;
33
using System;
44
using System.IO;
5+
using System.Threading;
56

67
namespace Lucene.Net.Index.Sorter
78
{
@@ -28,7 +29,7 @@ namespace Lucene.Net.Index.Sorter
2829
/// Note that this class is intended to used with <see cref="SortingMergePolicy"/>,
2930
/// and for other purposes has some limitations:
3031
/// <list type="bullet">
31-
/// <item><description>Cannot yet be used with <see cref="IndexSearcher.SearchAfter(ScoreDoc, Query, Filter, int, Sort)">
32+
/// <item><description>Cannot yet be used with <see cref="IndexSearcher.SearchAfter(ScoreDoc, Query, Filter, int, Sort, CancellationToken)">
3233
/// IndexSearcher.SearchAfter</see></description></item>
3334
/// <item><description>Filling sort field values is not yet supported.</description></item>
3435
/// </list>

src/Lucene.Net.TestFramework/Search/AssertingIndexSearcher.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using RandomizedTesting.Generators;
44
using System;
55
using System.Collections.Generic;
6+
using System.Threading;
67
using System.Threading.Tasks;
78

89
namespace Lucene.Net.Search
@@ -100,10 +101,10 @@ protected override Query WrapFilter(Query query, Filter filter)
100101
return (filter is null) ? query : new FilteredQuery(query, filter, TestUtil.RandomFilterStrategy(random));
101102
}
102103

103-
protected override void Search(IList<AtomicReaderContext> leaves, Weight weight, ICollector collector)
104+
protected override void Search(IList<AtomicReaderContext> leaves, Weight weight, ICollector collector, CancellationToken cancellationToken = default)
104105
{
105106
// TODO: shouldn't we AssertingCollector.wrap(collector) here?
106-
base.Search(leaves, AssertingWeight.Wrap(random, weight), collector);
107+
base.Search(leaves, AssertingWeight.Wrap(random, weight), collector, cancellationToken);
107108
}
108109

109110
public override string ToString()

src/Lucene.Net.TestFramework/Search/CheckHits.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Diagnostics;
66
using System.Globalization;
77
using System.Text;
8+
using System.Threading;
89
using JCG = J2N.Collections.Generic;
910
using Assert = Lucene.Net.TestFramework.Assert;
1011

@@ -450,28 +451,28 @@ protected virtual void CheckExplanations(Query q)
450451
base.Search(q, null, new ExplanationAsserter(q, null, this));
451452
}
452453

453-
public override TopFieldDocs Search(Query query, Filter filter, int n, Sort sort)
454+
public override TopFieldDocs Search(Query query, Filter filter, int n, Sort sort, CancellationToken cancellationToken = default)
454455
{
455456
CheckExplanations(query);
456-
return base.Search(query, filter, n, sort);
457+
return base.Search(query, filter, n, sort, cancellationToken);
457458
}
458459

459-
public override void Search(Query query, ICollector results)
460+
public override void Search(Query query, ICollector results, CancellationToken cancellationToken = default)
460461
{
461462
CheckExplanations(query);
462-
base.Search(query, results);
463+
base.Search(query, results, cancellationToken);
463464
}
464465

465-
public override void Search(Query query, Filter filter, ICollector results)
466+
public override void Search(Query query, Filter filter, ICollector results, CancellationToken cancellationToken = default)
466467
{
467468
CheckExplanations(query);
468-
base.Search(query, filter, results);
469+
base.Search(query, filter, results, cancellationToken);
469470
}
470471

471-
public override TopDocs Search(Query query, Filter filter, int n)
472+
public override TopDocs Search(Query query, Filter filter, int n, CancellationToken cancellationToken = default)
472473
{
473474
CheckExplanations(query);
474-
return base.Search(query, filter, n);
475+
return base.Search(query, filter, n, cancellationToken);
475476
}
476477
}
477478

src/Lucene.Net.TestFramework/Search/ShardSearchingTestBase.cs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Collections.Concurrent;
1212
using System.Collections.Generic;
1313
using System.Runtime.CompilerServices;
14+
using System.Threading;
1415
using JCG = J2N.Collections.Generic;
1516
#if FEATURE_SERIALIZABLE_EXCEPTIONS
1617
using System.ComponentModel;
@@ -192,7 +193,7 @@ internal virtual void BroadcastNodeReopen(int nodeID, long version, IndexSearche
192193
// MOCK: in a real env you have to hit the wire
193194
// (send this query to all remote nodes
194195
// concurrently):
195-
internal virtual TopDocs SearchNode(int nodeID, long[] nodeVersions, Query q, Sort sort, int numHits, ScoreDoc searchAfter)
196+
internal virtual TopDocs SearchNode(int nodeID, long[] nodeVersions, Query q, Sort sort, int numHits, ScoreDoc searchAfter, CancellationToken cancellationToken = default)
196197
{
197198
NodeState.ShardIndexSearcher s = m_nodes[nodeID].Acquire(nodeVersions);
198199
try
@@ -201,17 +202,17 @@ internal virtual TopDocs SearchNode(int nodeID, long[] nodeVersions, Query q, So
201202
{
202203
if (searchAfter != null)
203204
{
204-
return s.LocalSearchAfter(searchAfter, q, numHits);
205+
return s.LocalSearchAfter(searchAfter, q, numHits, cancellationToken);
205206
}
206207
else
207208
{
208-
return s.LocalSearch(q, numHits);
209+
return s.LocalSearch(q, numHits, cancellationToken);
209210
}
210211
}
211212
else
212213
{
213214
if (Debugging.AssertsEnabled) Debugging.Assert(searchAfter is null); // not supported yet
214-
return s.LocalSearch(q, numHits, sort);
215+
return s.LocalSearch(q, numHits, sort, cancellationToken);
215216
}
216217
}
217218
finally
@@ -448,7 +449,7 @@ public override CollectionStatistics CollectionStatistics(string field)
448449
return new CollectionStatistics(field, maxDoc, docCount, sumTotalTermFreq, sumDocFreq);
449450
}
450451

451-
public override TopDocs Search(Query query, int numHits)
452+
public override TopDocs Search(Query query, int numHits, CancellationToken cancellationToken = default)
452453
{
453454
TopDocs[] shardHits = new TopDocs[nodeVersions.Length];
454455
for (int nodeID = 0; nodeID < nodeVersions.Length; nodeID++)
@@ -457,7 +458,7 @@ public override TopDocs Search(Query query, int numHits)
457458
{
458459
// My node; run using local shard searcher we
459460
// already aquired:
460-
shardHits[nodeID] = LocalSearch(query, numHits);
461+
shardHits[nodeID] = LocalSearch(query, numHits, cancellationToken);
461462
}
462463
else
463464
{
@@ -469,12 +470,12 @@ public override TopDocs Search(Query query, int numHits)
469470
return TopDocs.Merge(null, numHits, shardHits);
470471
}
471472

472-
public virtual TopDocs LocalSearch(Query query, int numHits)
473+
public virtual TopDocs LocalSearch(Query query, int numHits, CancellationToken cancellationToken = default)
473474
{
474-
return base.Search(query, numHits);
475+
return base.Search(query, numHits, cancellationToken);
475476
}
476477

477-
public override TopDocs SearchAfter(ScoreDoc after, Query query, int numHits)
478+
public override TopDocs SearchAfter(ScoreDoc after, Query query, int numHits, CancellationToken cancellationToken = default)
478479
{
479480
TopDocs[] shardHits = new TopDocs[nodeVersions.Length];
480481
// results are merged in that order: score, shardIndex, doc. therefore we set
@@ -521,7 +522,7 @@ public override TopDocs SearchAfter(ScoreDoc after, Query query, int numHits)
521522
{
522523
// My node; run using local shard searcher we
523524
// already aquired:
524-
shardHits[nodeID] = LocalSearchAfter(shardAfter, query, numHits);
525+
shardHits[nodeID] = LocalSearchAfter(shardAfter, query, numHits, cancellationToken);
525526
}
526527
else
527528
{
@@ -534,12 +535,12 @@ public override TopDocs SearchAfter(ScoreDoc after, Query query, int numHits)
534535
return TopDocs.Merge(null, numHits, shardHits);
535536
}
536537

537-
public virtual TopDocs LocalSearchAfter(ScoreDoc after, Query query, int numHits)
538+
public virtual TopDocs LocalSearchAfter(ScoreDoc after, Query query, int numHits, CancellationToken cancellationToken = default)
538539
{
539-
return base.SearchAfter(after, query, numHits);
540+
return base.SearchAfter(after, query, numHits, cancellationToken);
540541
}
541542

542-
public override TopFieldDocs Search(Query query, int numHits, Sort sort)
543+
public override TopFieldDocs Search(Query query, int numHits, Sort sort, CancellationToken cancellationToken = default)
543544
{
544545
if (Debugging.AssertsEnabled) Debugging.Assert(sort != null);
545546
TopDocs[] shardHits = new TopDocs[nodeVersions.Length];
@@ -549,21 +550,21 @@ public override TopFieldDocs Search(Query query, int numHits, Sort sort)
549550
{
550551
// My node; run using local shard searcher we
551552
// already aquired:
552-
shardHits[nodeID] = LocalSearch(query, numHits, sort);
553+
shardHits[nodeID] = LocalSearch(query, numHits, sort, cancellationToken);
553554
}
554555
else
555556
{
556-
shardHits[nodeID] = outerInstance.outerInstance.SearchNode(nodeID, nodeVersions, query, sort, numHits, null);
557+
shardHits[nodeID] = outerInstance.outerInstance.SearchNode(nodeID, nodeVersions, query, sort, numHits, null, cancellationToken);
557558
}
558559
}
559560

560561
// Merge:
561562
return (TopFieldDocs)TopDocs.Merge(sort, numHits, shardHits);
562563
}
563564

564-
public virtual TopFieldDocs LocalSearch(Query query, int numHits, Sort sort)
565+
public virtual TopFieldDocs LocalSearch(Query query, int numHits, Sort sort, CancellationToken cancellationToken = default)
565566
{
566-
return base.Search(query, numHits, sort);
567+
return base.Search(query, numHits, sort, cancellationToken);
567568
}
568569
}
569570

src/Lucene.Net.Tests/Search/TestBooleanQuery.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NUnit.Framework;
44
using System;
55
using System.Collections.Generic;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using JCG = J2N.Collections.Generic;
89
using Assert = Lucene.Net.TestFramework.Assert;
@@ -395,10 +396,10 @@ public IndexSearcherAnonymousClass(IndexReader r)
395396
{
396397
}
397398

398-
protected override void Search(IList<AtomicReaderContext> leaves, Weight weight, ICollector collector)
399+
protected override void Search(IList<AtomicReaderContext> leaves, Weight weight, ICollector collector, CancellationToken cancellationToken = default)
399400
{
400401
Assert.AreEqual(-1, collector.GetType().Name.IndexOf("OutOfOrder", StringComparison.Ordinal));
401-
base.Search(leaves, weight, collector);
402+
base.Search(leaves, weight, collector, cancellationToken);
402403
}
403404
}
404405
}

src/Lucene.Net.Tests/Search/TestCustomSearcherSort.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Text;
6+
using System.Threading;
67
using Assert = Lucene.Net.TestFramework.Assert;
78
using JCG = J2N.Collections.Generic;
89

@@ -212,20 +213,20 @@ public CustomSearcher(IndexReader r, int switcher)
212213
this.switcher = switcher;
213214
}
214215

215-
public override TopFieldDocs Search(Query query, Filter filter, int nDocs, Sort sort)
216+
public override TopFieldDocs Search(Query query, Filter filter, int nDocs, Sort sort, CancellationToken cancellationToken = default)
216217
{
217218
BooleanQuery bq = new BooleanQuery();
218219
bq.Add(query, Occur.MUST);
219220
bq.Add(new TermQuery(new Term("mandant", Convert.ToString(switcher))), Occur.MUST);
220-
return base.Search(bq, filter, nDocs, sort);
221+
return base.Search(bq, filter, nDocs, sort, cancellationToken);
221222
}
222223

223-
public override TopDocs Search(Query query, Filter filter, int nDocs)
224+
public override TopDocs Search(Query query, Filter filter, int nDocs, CancellationToken cancellationToken = default)
224225
{
225226
BooleanQuery bq = new BooleanQuery();
226227
bq.Add(query, Occur.MUST);
227228
bq.Add(new TermQuery(new Term("mandant", Convert.ToString(switcher))), Occur.MUST);
228-
return base.Search(bq, filter, nDocs);
229+
return base.Search(bq, filter, nDocs, cancellationToken);
229230
}
230231
}
231232

0 commit comments

Comments
 (0)