You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2022/02/12 06:53:50 UTC
[lucenenet] branch master updated: BREAKING: Lucene.Net.Spatial Updates (#619)
This is an automated email from the ASF dual-hosted git repository.
nightowl888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucenenet.git
The following commit(s) were added to refs/heads/master by this push:
new d0d1d54 BREAKING: Lucene.Net.Spatial Updates (#619)
d0d1d54 is described below
commit d0d1d5432a20e1f1114f39eaf8a02b03013bffe3
Author: Shad Storhaug <sh...@shadstorhaug.com>
AuthorDate: Sat Feb 12 13:53:39 2022 +0700
BREAKING: Lucene.Net.Spatial Updates (#619)
* .build/dependencies.props: Upgraded Spatial4n to 0.4.1.1 and changed packages from Spatial4n.Core and Spatial4n.Core.NTS to Spatial4n.
* Lucene.Net.Spatial: Migrated to non-obsolete members in Spatial4n
* BREAKING: Lucene.Net.Spatial.Prefix.Tree.Cell: Renamed m_outerInstance > m_spatialPrefixTree and constructor parameters outerInstance > spatialPrefixTree
* BREAKING: Lucene.Net.Spatial.Prefix.AbstractPrefixTreeFilter.BaseTermsEnumTransverser: renamed m_outerInstance > m_filter, constructor parameters outerInstance > filter
* BREAKING: Lucene.Net.Spatial.Prefix.AbstractPrefixTreeFilter: Denested BaseTermsEnumTraverser
* BREAKING: Lucene.Net.Spatial.Prefix.Tree.GeohashPrefixTree.Factory: de-nested and renamed GeohashPrefixTreeFactory
* Lucene.Net.Spatial.Prefix.Tree.QuadPrefixTree.Factory: de-nested and renamed QuadPrefixTreeFactory
* BUG: Lucene.Net.Spatial.Query.SpatialArgs::ctor(): Set operation and shape fields rather than calling the virtual properties to set them (which can cause initialization issues)
* Lucene.Net.Spatial.Query.SpatialArgsParser: Added missing guard clauses
* Lucene.Net.Spatial.Prefix.Tree.Cell: Added guard clauses for both constructors and Reset() method
* Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree: Added guard clauses
* Lucene.Net.Spatial.Prefix.Tree.GeohashPrefixTree: Added guard clauses
* Lucene.Net.Spatial.Prefix.Tree.QuadPrefixTree: Added guard clauses
* Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTreeFactory: Added guard clauses
* Lucene.Net.Spatial.Prefix.AbstractPrefixTreeFilter: Added guard clauses, enabled nullable reference type support
* Lucene.Net.Spatial.Prefix.Tree.Cell: Enabled nullable reference type support; fixed potential NullReferenceException in CompareTo() implementation
* Lucene.Net.Spatial.Prefix.Tree.QuadPrefixTree: Enabled nullable reference type support
* Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree: Added nullable reference type support
* Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTreeFactory: Enabled nullable reference type support. Added missing overload to MakeSPT() with an Assembly parameter for loading types from external assemblies.
* Lucene.Net.Spatial.Prefix.AbstractVisitionPrefixTreeFilter: Added nullable reference type support and updated docs
* BREAKING: Lucene.Net.Spatial.Prefix.AbstractVisitingPrefixTreeFilter: De-nested VisitorTemplate class and changed protected field m_prefixGridScanLevel to a public property named PrefixGridScanLevel.
* Lucene.Net.Spatial.Prefix.ContainsPrefixTreeFilter: Enabled nullable reference type support
* Lucene.Net.Spatial.Prefix.IntersectsPrefixTreeFilter: Added nullable reference type support
* Lucene.Net.Spatial.Prefix.PointPrefixTreeFieldCacheProvider: Added nullable reference type support
* Lucene.Net.Spatial.Prefix.PrefixTreeStrategy: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Prefix.RecursivePrefixTreeStrategy: Enabled nullable reference type support
* Lucene.Net.Spatial.Prefix.TermQueryPrefixTreeStrategy: Added nullable reference type support
* Lucene.Net.Spatial.Prefix.WithinPrefixTreeFilter: Added nullable reference type support and guard clauses (including AbstractPrefixTreeFilter and AbstractVisitingPrevixTreeFilter constructors)
* Lucene.Net.Spatial.Query.SpatialArgs: Added support for nullable reference types and added guard clauses
* Lucene.Net.Spatial.Query.SpatialArgsParser: Added nullable reference type support
* Lucene.Net.Spatail.Query.SpatialOperation: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Query.UnsupportedSpatialOperation: Added nullable reference type support
* Lucene.Net.Spatial.Serialized.SerializedDVStrategy: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.CachingDoubleValueSource: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.DistanceToShapeValueSource: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.ShapeFieldCache: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.ShapeFieldCacheDistanceValueSource: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.ShapeFieldCacheProvider: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.ShapePredicateValueSource: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Util.ValueSourceFilter: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Vector.DistanceValueSource: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.Vector.PointVectorStrategy: Added nullable reference type support and guard clauses. Changed SUFFIX_X and SUFFIX_Y to constants.
* Lucene.Net.Spatial.DisjointSpatialFilter: Added nullable reference type support and guard clauses
* Lucene.Net.Spatial.SpatialStrategy: Added nullable reference type support and guard clauses
* Lucene.Net.Spatiial.Prefix.Tree.GeohashPrefixTree: Added nullable reference type support and guard clauses
* SWEEP: Lucene.Net.Spatial: Enabled nullable reference type support in the project, and removed declaration in individual files
* BREAKING: Lucene.Net.Spatial.Query: Renamed UnsupportedSpatialOperation > UnsupportedSpatialOperationException to match .NET conventions
---
.build/dependencies.props | 3 +-
.../ByTask/Feeds/SpatialDocMaker.cs | 11 +-
.../ByTask/Feeds/SpatialFileQueryMaker.cs | 4 +-
.../Lucene.Net.Benchmark.csproj | 2 +-
src/Lucene.Net.Spatial/DisjointSpatialFilter.cs | 30 +-
src/Lucene.Net.Spatial/Lucene.Net.Spatial.csproj | 3 +-
.../Prefix/AbstractPrefixTreeFilter.cs | 108 ++--
.../Prefix/AbstractVisitingPrefixTreeFilter.cs | 699 +++++++++++----------
.../Prefix/ContainsPrefixTreeFilter.cs | 54 +-
.../Prefix/IntersectsPrefixTreeFilter.cs | 45 +-
.../Prefix/PointPrefixTreeFieldCacheProvider.cs | 18 +-
.../Prefix/PrefixTreeStrategy.cs | 37 +-
.../Prefix/RecursivePrefixTreeStrategy.cs | 13 +-
.../Prefix/TermQueryPrefixTreeStrategy.cs | 17 +-
src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs | 93 ++-
.../Prefix/Tree/GeohashPrefixTree.cs | 74 ++-
.../Prefix/Tree/QuadPrefixTree.cs | 110 +++-
.../Prefix/Tree/SpatialPrefixTree.cs | 52 +-
.../Prefix/Tree/SpatialPrefixTreeFactory.cs | 61 +-
.../Prefix/WithinPrefixTreeFilter.cs | 101 +--
src/Lucene.Net.Spatial/Query/SpatialArgs.cs | 21 +-
src/Lucene.Net.Spatial/Query/SpatialArgsParser.cs | 58 +-
src/Lucene.Net.Spatial/Query/SpatialOperation.cs | 59 +-
.../Query/UnsupportedSpatialOperation.cs | 12 +-
.../Serialized/SerializedDVStrategy.cs | 65 +-
src/Lucene.Net.Spatial/SpatialStrategy.cs | 17 +-
.../Util/CachingDoubleValueSource.cs | 22 +-
.../Util/DistanceToShapeValueSource.cs | 28 +-
src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs | 17 +-
.../Util/ShapeFieldCacheDistanceValueSource.cs | 44 +-
.../Util/ShapeFieldCacheProvider.cs | 31 +-
.../Util/ShapePredicateValueSource.cs | 39 +-
src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs | 14 +-
.../Vector/DistanceValueSource.cs | 27 +-
.../Vector/PointVectorStrategy.cs | 46 +-
.../ExceptionHandling/ExceptionScanningTestCase.cs | 2 +-
.../DistanceStrategyTest.cs | 8 +-
.../Lucene.Net.Tests.Spatial.csproj | 3 +-
src/Lucene.Net.Tests.Spatial/PortedSolr3Test.cs | 10 +-
.../Prefix/NtsPolygonTest.cs | 16 +-
.../Prefix/SpatialOpRecursivePrefixTreeTest.cs | 68 +-
.../Prefix/TestRecursivePrefixTreeStrategy.cs | 20 +-
.../Prefix/TestTermQueryPrefixGridStrategy.cs | 11 +-
.../Prefix/Tree/SpatialPrefixTreeTest.cs | 6 +-
.../Query/SpatialArgsParserTest.cs | 6 +-
.../QueryEqualsHashCodeTest.cs | 6 +-
.../Serialized/SerializedStrategyTest.cs | 4 +-
src/Lucene.Net.Tests.Spatial/SpatialArgsTest.cs | 6 +-
src/Lucene.Net.Tests.Spatial/SpatialExample.cs | 18 +-
src/Lucene.Net.Tests.Spatial/SpatialTestCase.cs | 6 +-
src/Lucene.Net.Tests.Spatial/SpatialTestData.cs | 6 +-
src/Lucene.Net.Tests.Spatial/SpatialTestQuery.cs | 2 +-
src/Lucene.Net.Tests.Spatial/StrategyTestCase.cs | 4 +-
src/Lucene.Net.Tests.Spatial/TestTestFramework.cs | 6 +-
.../Vector/TestPointVectorStrategy.cs | 6 +-
55 files changed, 1333 insertions(+), 916 deletions(-)
diff --git a/.build/dependencies.props b/.build/dependencies.props
index 3245a77..98836d4 100644
--- a/.build/dependencies.props
+++ b/.build/dependencies.props
@@ -74,8 +74,7 @@
<PrismCorePackageVersion>7.2.0.1422</PrismCorePackageVersion>
<RandomizedTestingGeneratorsPackageVersion>2.7.8</RandomizedTestingGeneratorsPackageVersion>
<SharpZipLibPackageVersion>1.1.0</SharpZipLibPackageVersion>
- <Spatial4nCorePackageVersion>0.4.1</Spatial4nCorePackageVersion>
- <Spatial4nCoreNTSPackageVersion>$(Spatial4nCorePackageVersion)</Spatial4nCoreNTSPackageVersion>
+ <Spatial4nPackageVersion>0.4.1.1</Spatial4nPackageVersion>
<SystemNetPrimitivesPackageVersion>4.3.0</SystemNetPrimitivesPackageVersion>
<SystemReflectionEmitPackageVersion>4.3.0</SystemReflectionEmitPackageVersion>
<SystemReflectionEmitILGenerationPackageVersion>4.3.0</SystemReflectionEmitILGenerationPackageVersion>
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialDocMaker.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialDocMaker.cs
index fa0f407..c3c8f88 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialDocMaker.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialDocMaker.cs
@@ -3,8 +3,8 @@ using Lucene.Net.Documents;
using Lucene.Net.Spatial;
using Lucene.Net.Spatial.Prefix;
using Lucene.Net.Spatial.Prefix.Tree;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -141,12 +141,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
SpatialContext ctx)
{
//A factory for the prefix tree grid
- // LUCENENET: The second argument was ClassLoader in Java, which should be made into
- // Assembly in .NET. However, Spatial4n currently doesn't support it.
- // In .NET it makes more logical sense to make 2 overloads and throw ArgumentNullException
- // if the second argument is null, anyway. So no need to change this once support has been added.
- // See: https://github.com/NightOwl888/Spatial4n/issues/1
- SpatialPrefixTree grid = SpatialPrefixTreeFactory.MakeSPT(configMap/*, assembly: null*/, ctx);
+ SpatialPrefixTree grid = SpatialPrefixTreeFactory.MakeSPT(configMap, assembly: null, ctx);
RecursivePrefixTreeStrategy strategy = new RecursivePrefixTreeStrategyAnonymousClass(grid, SPATIAL_FIELD, config);
diff --git a/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialFileQueryMaker.cs b/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialFileQueryMaker.cs
index a2e469e..bd80009 100644
--- a/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialFileQueryMaker.cs
+++ b/src/Lucene.Net.Benchmark/ByTask/Feeds/SpatialFileQueryMaker.cs
@@ -4,7 +4,7 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Search;
using Lucene.Net.Spatial;
using Lucene.Net.Spatial.Queries;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -29,7 +29,7 @@ namespace Lucene.Net.Benchmarks.ByTask.Feeds
/// <summary>
/// Reads spatial data from the body field docs from an internally created <see cref="LineDocSource"/>.
- /// It's parsed by <see cref="Spatial4n.Core.Context.SpatialContext.ReadShapeFromWkt(string)"/> and then
+ /// It's parsed by <see cref="Spatial4n.Context.SpatialContext.ReadShapeFromWkt(string)"/> and then
/// further manipulated via a configurable <see cref="IShapeConverter"/>. When using point
/// data, it's likely you'll want to configure the shape converter so that the query shapes actually
/// cover a region. The queries are all created & cached in advance. This query maker works in
diff --git a/src/Lucene.Net.Benchmark/Lucene.Net.Benchmark.csproj b/src/Lucene.Net.Benchmark/Lucene.Net.Benchmark.csproj
index 5ffa901..0b60a06 100644
--- a/src/Lucene.Net.Benchmark/Lucene.Net.Benchmark.csproj
+++ b/src/Lucene.Net.Benchmark/Lucene.Net.Benchmark.csproj
@@ -54,7 +54,7 @@
<ItemGroup>
<PackageReference Include="J2N" Version="$(J2NPackageVersion)" />
<PackageReference Include="ICU4N.Collation" Version="$(ICU4NCollationPackageVersion)" />
- <PackageReference Include="Spatial4n.Core" Version="$(Spatial4nCorePackageVersion)" />
+ <PackageReference Include="Spatial4n" Version="$(Spatial4nPackageVersion)" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
diff --git a/src/Lucene.Net.Spatial/DisjointSpatialFilter.cs b/src/Lucene.Net.Spatial/DisjointSpatialFilter.cs
index 9e12dfc..88156bc 100644
--- a/src/Lucene.Net.Spatial/DisjointSpatialFilter.cs
+++ b/src/Lucene.Net.Spatial/DisjointSpatialFilter.cs
@@ -1,4 +1,4 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
using Lucene.Net.Queries;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
@@ -32,12 +32,12 @@ namespace Lucene.Net.Spatial
/// A document is considered disjoint if it has spatial data that does not
/// intersect with the query shape. Another way of looking at this is that it's
/// a way to invert a query shape.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class DisjointSpatialFilter : Filter
{
- private readonly string field;//maybe null
+ private readonly string? field;//maybe null
private readonly Filter intersectsFilter;
/// <param name="strategy">Needed to compute intersects</param>
@@ -45,10 +45,16 @@ namespace Lucene.Net.Spatial
/// <param name="field">
/// This field is used to determine which docs have spatial data via
/// <see cref="IFieldCache.GetDocsWithField(AtomicReader, string)"/>.
- /// Passing null will assume all docs have spatial data.
+ /// Passing <c>null</c> will assume all docs have spatial data.
/// </param>
- public DisjointSpatialFilter(SpatialStrategy strategy, SpatialArgs args, string field)
+ public DisjointSpatialFilter(SpatialStrategy strategy, SpatialArgs args, string? field)
{
+ // LUCENENET specific - added guard clauses
+ if (strategy is null)
+ throw new ArgumentNullException(nameof(strategy));
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
this.field = field;
// TODO consider making SpatialArgs cloneable
@@ -59,7 +65,7 @@ namespace Lucene.Net.Spatial
}
//restore so it looks like it was
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o)
{
@@ -83,15 +89,19 @@ namespace Lucene.Net.Spatial
public override int GetHashCode()
{
- int result = field != null ? field.GetHashCode() : 0;
+ int result = field is null ? 0 : field.GetHashCode();
result = 31 * result + intersectsFilter.GetHashCode();
return result;
}
/// <exception cref="IOException"></exception>
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet? GetDocIdSet(AtomicReaderContext context, IBits? acceptDocs)
{
- IBits docsWithField;
+ // LUCENENET specific - added guard clause
+ if (context is null)
+ throw new ArgumentNullException(nameof(context));
+
+ IBits? docsWithField;
if (field is null)
{
docsWithField = null;
@@ -102,7 +112,7 @@ namespace Lucene.Net.Spatial
// which is nice but loading it in this way might be slower than say using an
// intersects filter against the world bounds. So do we add a method to the
// strategy, perhaps? But the strategy can't cache it.
- docsWithField = FieldCache.DEFAULT.GetDocsWithField((context.AtomicReader), field);
+ docsWithField = FieldCache.DEFAULT.GetDocsWithField(context.AtomicReader, field);
int maxDoc = context.AtomicReader.MaxDoc;
if (docsWithField.Length != maxDoc)
diff --git a/src/Lucene.Net.Spatial/Lucene.Net.Spatial.csproj b/src/Lucene.Net.Spatial/Lucene.Net.Spatial.csproj
index 9848aa4..00cb63f 100644
--- a/src/Lucene.Net.Spatial/Lucene.Net.Spatial.csproj
+++ b/src/Lucene.Net.Spatial/Lucene.Net.Spatial.csproj
@@ -36,6 +36,7 @@
<PackageTags>$(PackageTags);spatial;geo;geospatial;2d</PackageTags>
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
<NoWarn>$(NoWarn);1591;1573</NoWarn>
+ <Nullable>enable</Nullable>
</PropertyGroup>
@@ -46,7 +47,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Spatial4n.Core" Version="$(Spatial4nCorePackageVersion)" />
+ <PackageReference Include="Spatial4n" Version="$(Spatial4nPackageVersion)" />
</ItemGroup>
<ItemGroup>
diff --git a/src/Lucene.Net.Spatial/Prefix/AbstractPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/AbstractPrefixTreeFilter.cs
index f49f841..40dbb43 100644
--- a/src/Lucene.Net.Spatial/Prefix/AbstractPrefixTreeFilter.cs
+++ b/src/Lucene.Net.Spatial/Prefix/AbstractPrefixTreeFilter.cs
@@ -1,11 +1,9 @@
-using Lucene.Net.Diagnostics;
-using Lucene.Net.Index;
+using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
-using System.Diagnostics;
namespace Lucene.Net.Spatial.Prefix
{
@@ -39,18 +37,20 @@ namespace Lucene.Net.Spatial.Prefix
protected AbstractPrefixTreeFilter(IShape queryShape, string fieldName, SpatialPrefixTree grid, int detailLevel) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
{
- this.m_queryShape = queryShape;
- this.m_fieldName = fieldName;
- this.m_grid = grid;
+ // LUCENENET specific - added guard clauses
+ this.m_queryShape = queryShape ?? throw new ArgumentNullException(nameof(queryShape));
+ this.m_fieldName = fieldName ?? throw new ArgumentNullException(nameof(fieldName));
+ this.m_grid = grid ?? throw new ArgumentNullException(nameof(grid));
this.m_detailLevel = detailLevel;
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o)
{
return true;
}
+ if (o is null) return false; // LUCENENET specific: null check
if (!GetType().Equals(o.GetType()))
{
return false;
@@ -79,51 +79,7 @@ namespace Lucene.Net.Spatial.Prefix
return result;
}
- #region Nested type: BaseTermsEnumTraverser
-
- /// <summary>
- /// Holds transient state and docid collecting utility methods as part of
- /// traversing a <see cref="TermsEnum">Lucene.Net.Index.TermsEnum</see>.
- /// </summary>
- public abstract class BaseTermsEnumTraverser
- {
- protected readonly AbstractPrefixTreeFilter m_outerInstance;
- protected readonly AtomicReaderContext m_context;
- protected IBits m_acceptDocs;
- protected readonly int m_maxDoc;
-
- protected TermsEnum m_termsEnum;//remember to check for null in getDocIdSet
- protected DocsEnum m_docsEnum;
-
- protected BaseTermsEnumTraverser(AbstractPrefixTreeFilter outerInstance, AtomicReaderContext context, IBits acceptDocs) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
- {
- this.m_outerInstance = outerInstance;
-
- this.m_context = context;
- AtomicReader reader = context.AtomicReader;
- this.m_acceptDocs = acceptDocs;
- m_maxDoc = reader.MaxDoc;
- Terms terms = reader.GetTerms(outerInstance.m_fieldName);
- if (terms != null)
- {
- m_termsEnum = terms.GetEnumerator();
- }
- }
-
- protected virtual void CollectDocs(FixedBitSet bitSet)
- {
- //WARN: keep this specialization in sync
- if (Debugging.AssertsEnabled) Debugging.Assert(m_termsEnum != null);
- m_docsEnum = m_termsEnum.Docs(m_acceptDocs, m_docsEnum, DocsFlags.NONE);
- int docid;
- while ((docid = m_docsEnum.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
- {
- bitSet.Set(docid);
- }
- }
- }
-
- #endregion
+ // LUCENENET specific - de-nested BaseTermsEnumTraverser
/* Eventually uncomment when needed.
@@ -142,4 +98,50 @@ namespace Lucene.Net.Spatial.Prefix
}
*/
}
+
+ /// <summary>
+ /// Holds transient state and docid collecting utility methods as part of
+ /// traversing a <see cref="TermsEnum">Lucene.Net.Index.TermsEnum</see>.
+ /// </summary>
+ public abstract class BaseTermsEnumTraverser
+ {
+ protected readonly AbstractPrefixTreeFilter m_filter;
+ protected readonly AtomicReaderContext m_context;
+ protected IBits? m_acceptDocs;
+ protected readonly int m_maxDoc;
+
+ protected TermsEnum? m_termsEnum;//remember to check for null in getDocIdSet
+ protected DocsEnum? m_docsEnum;
+
+ protected BaseTermsEnumTraverser(AbstractPrefixTreeFilter filter, AtomicReaderContext context, IBits? acceptDocs) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
+ {
+ // LUCENENET specific - added guard clauses
+ this.m_filter = filter ?? throw new ArgumentNullException(nameof(filter));
+ this.m_context = context ?? throw new ArgumentNullException(nameof(context));
+ AtomicReader reader = context.AtomicReader;
+ this.m_acceptDocs = acceptDocs;
+ m_maxDoc = reader.MaxDoc;
+ Terms? terms = reader.GetTerms(filter.m_fieldName);
+ if (terms != null)
+ {
+ m_termsEnum = terms.GetEnumerator();
+ }
+ }
+
+ protected virtual void CollectDocs(FixedBitSet bitSet)
+ {
+ // LUCENENET specific - use guard clause instead of assert
+ if (m_termsEnum is null)
+ throw new InvalidOperationException($"{nameof(m_termsEnum)} must not be null.");
+ if (bitSet is null)
+ throw new ArgumentNullException(nameof(bitSet));
+ //WARN: keep this specialization in sync
+ m_docsEnum = m_termsEnum.Docs(m_acceptDocs, m_docsEnum, DocsFlags.NONE);
+ int docid;
+ while ((docid = m_docsEnum.NextDoc()) != DocIdSetIterator.NO_MORE_DOCS)
+ {
+ bitSet.Set(docid);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Spatial/Prefix/AbstractVisitingPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/AbstractVisitingPrefixTreeFilter.cs
index a500c8b..f403253 100644
--- a/src/Lucene.Net.Spatial/Prefix/AbstractVisitingPrefixTreeFilter.cs
+++ b/src/Lucene.Net.Spatial/Prefix/AbstractVisitingPrefixTreeFilter.cs
@@ -1,13 +1,12 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
namespace Lucene.Net.Spatial.Prefix
@@ -37,7 +36,7 @@ namespace Lucene.Net.Spatial.Prefix
/// Subclasses implement <see cref="Filter.GetDocIdSet(AtomicReaderContext, IBits)"/>
/// by instantiating a custom <see cref="VisitorTemplate"/> subclass (i.e. an anonymous inner class) and implement the
/// required methods.
- ///
+ /// <para/>
/// @lucene.internal
/// </summary>
public abstract class AbstractVisitingPrefixTreeFilter : AbstractPrefixTreeFilter
@@ -45,431 +44,438 @@ namespace Lucene.Net.Spatial.Prefix
// Historical note: this code resulted from a refactoring of RecursivePrefixTreeFilter,
// which in turn came out of SOLR-2155
- protected readonly int m_prefixGridScanLevel;//at least one less than grid.getMaxLevels()
+ public int PrefixGridScanLevel { get; }//at least one less than grid.getMaxLevels()
protected AbstractVisitingPrefixTreeFilter(IShape queryShape, string fieldName, SpatialPrefixTree grid,
int detailLevel, int prefixGridScanLevel) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
: base(queryShape, fieldName, grid, detailLevel)
{
- this.m_prefixGridScanLevel = Math.Max(0, Math.Min(prefixGridScanLevel, grid.MaxLevels - 1));
+ this.PrefixGridScanLevel = Math.Max(0, Math.Min(prefixGridScanLevel, grid.MaxLevels - 1));
if (Debugging.AssertsEnabled) Debugging.Assert(detailLevel <= grid.MaxLevels);
}
- public override bool Equals(object o)
- {
- if (!base.Equals(o))
- {
- return false;//checks getClass == o.getClass & instanceof
- }
+ // LUCENENET: Removed these because they are simply calling the base implementation
+ //public override bool Equals(object? o)
+ //{
+ // if (!base.Equals(o))
+ // {
+ // return false;//checks getClass == o.getClass & instanceof
+ // }
- //Ignore prefixGridScanLevel as it is merely a tuning parameter.
+ // //Ignore prefixGridScanLevel as it is merely a tuning parameter.
- return true;
- }
+ // return true;
+ //}
- public override int GetHashCode()
- {
- int result = base.GetHashCode();
- return result;
- }
+ //public override int GetHashCode()
+ //{
+ // int result = base.GetHashCode();
+ // return result;
+ //}
+ }
- #region Nested type: VisitorTemplate
+ /// <summary>
+ /// An abstract class designed to make it easy to implement predicates or
+ /// other operations on a <see cref="SpatialPrefixTree"/> indexed field. An instance
+ /// of this class is not designed to be re-used across AtomicReaderContext
+ /// instances so simply create a new one for each call to, say a
+ /// <see cref="Filter.GetDocIdSet(AtomicReaderContext, IBits)"/>.
+ /// The <see cref="GetDocIdSet()"/> method here starts the work. It first checks
+ /// that there are indexed terms; if not it quickly returns null. Then it calls
+ /// <see cref="Start()">Start()</see> so a subclass can set up a return value, like an
+ /// <see cref="FixedBitSet"/>. Then it starts the traversal
+ /// process, calling <see cref="FindSubCellsToVisit(Cell)"/>
+ /// which by default finds the top cells that intersect <c>queryShape</c>. If
+ /// there isn't an indexed cell for a corresponding cell returned for this
+ /// method then it's short-circuited until it finds one, at which point
+ /// <see cref="Visit(Cell)"/> is called. At
+ /// some depths, of the tree, the algorithm switches to a scanning mode that
+ /// calls <see cref="VisitScanned(Cell)"/>
+ /// for each leaf cell found.
+ /// <para/>
+ /// @lucene.internal
+ /// </summary>
+ public abstract class VisitorTemplate : BaseTermsEnumTraverser
+ {
+ /* Future potential optimizations:
- /// <summary>
- /// An abstract class designed to make it easy to implement predicates or
- /// other operations on a <see cref="SpatialPrefixTree"/> indexed field. An instance
- /// of this class is not designed to be re-used across AtomicReaderContext
- /// instances so simply create a new one for each call to, say a
- /// <see cref="Lucene.Net.Search.Filter.GetDocIdSet(Lucene.Net.Index.AtomicReaderContext, Lucene.Net.Util.IBits)"/>.
- /// The <see cref="GetDocIdSet()"/> method here starts the work. It first checks
- /// that there are indexed terms; if not it quickly returns null. Then it calls
- /// <see cref="Start()">Start()</see> so a subclass can set up a return value, like an
- /// <see cref="Lucene.Net.Util.FixedBitSet"/>. Then it starts the traversal
- /// process, calling <see cref="FindSubCellsToVisit(Lucene.Net.Spatial.Prefix.Tree.Cell)"/>
- /// which by default finds the top cells that intersect <c>queryShape</c>. If
- /// there isn't an indexed cell for a corresponding cell returned for this
- /// method then it's short-circuited until it finds one, at which point
- /// <see cref="Visit(Lucene.Net.Spatial.Prefix.Tree.Cell)"/> is called. At
- /// some depths, of the tree, the algorithm switches to a scanning mode that
- /// calls <see cref="VisitScanned(Lucene.Net.Spatial.Prefix.Tree.Cell)"/>
- /// for each leaf cell found.
- ///
- /// @lucene.internal
- /// </summary>
- public abstract class VisitorTemplate : BaseTermsEnumTraverser
- {
- /* Future potential optimizations:
+ * Can a polygon query shape be optimized / made-simpler at recursive depths
+ (e.g. intersection of shape + cell box)
- * Can a polygon query shape be optimized / made-simpler at recursive depths
- (e.g. intersection of shape + cell box)
+ * RE "scan" vs divide & conquer performance decision:
+ We should use termsEnum.docFreq() as an estimate on the number of places at
+ this depth. It would be nice if termsEnum knew how many terms
+ start with the current term without having to repeatedly next() & test to find out.
- * RE "scan" vs divide & conquer performance decision:
- We should use termsEnum.docFreq() as an estimate on the number of places at
- this depth. It would be nice if termsEnum knew how many terms
- start with the current term without having to repeatedly next() & test to find out.
+ * Perhaps don't do intermediate seek()'s to cells above detailLevel that have Intersects
+ relation because we won't be collecting those docs any way. However seeking
+ does act as a short-circuit. So maybe do some percent of the time or when the level
+ is above some threshold.
- * Perhaps don't do intermediate seek()'s to cells above detailLevel that have Intersects
- relation because we won't be collecting those docs any way. However seeking
- does act as a short-circuit. So maybe do some percent of the time or when the level
- is above some threshold.
+ * Each shape.relate(otherShape) result could be cached since much of the same relations
+ will be invoked when multiple segments are involved.
- * Each shape.relate(otherShape) result could be cached since much of the same relations
- will be invoked when multiple segments are involved.
+ */
- */
+ protected readonly bool m_hasIndexedLeaves;//if false then we can skip looking for them
- protected readonly bool m_hasIndexedLeaves;//if false then we can skip looking for them
+ private VNode? curVNode;//current pointer, derived from query shape
+ private readonly BytesRef curVNodeTerm = new BytesRef();//curVNode.cell's term. // LUCENENET: marked readonly
+ private Cell? scanCell;
- private VNode curVNode;//current pointer, derived from query shape
- private readonly BytesRef curVNodeTerm = new BytesRef();//curVNode.cell's term. // LUCENENET: marked readonly
- private Cell scanCell;
+ private BytesRef? thisTerm; //the result of termsEnum.term()
- private BytesRef thisTerm; //the result of termsEnum.term()
+ protected VisitorTemplate(AbstractVisitingPrefixTreeFilter outerInstance, AtomicReaderContext context, IBits? acceptDocs,
+ bool hasIndexedLeaves) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
+ : base(outerInstance, context, acceptDocs)
+ {
+ this.m_hasIndexedLeaves = hasIndexedLeaves;
+ }
- protected VisitorTemplate(AbstractVisitingPrefixTreeFilter outerInstance, AtomicReaderContext context, IBits acceptDocs,
- bool hasIndexedLeaves) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
- : base(outerInstance, context, acceptDocs)
+ public virtual DocIdSet? GetDocIdSet()
+ {
+ if (Debugging.AssertsEnabled) Debugging.Assert(curVNode is null, "Called more than once?");
+ if (m_termsEnum is null)
{
- this.m_hasIndexedLeaves = hasIndexedLeaves;
+ return null;
}
-
- public virtual DocIdSet GetDocIdSet()
+ //advance
+ if (!m_termsEnum.MoveNext())
{
- if (Debugging.AssertsEnabled) Debugging.Assert(curVNode is null, "Called more than once?");
- if (m_termsEnum is null)
- {
- return null;
- }
- //advance
- if (!m_termsEnum.MoveNext())
- {
- return null;// all done
- }
- thisTerm = m_termsEnum.Term;
+ return null;// all done
+ }
+ thisTerm = m_termsEnum.Term;
- curVNode = new VNode(null);
- curVNode.Reset(m_outerInstance.m_grid.WorldCell);
+ curVNode = new VNode(null);
+ curVNode.Reset(m_filter.m_grid.WorldCell);
- Start();
+ Start();
- AddIntersectingChildren();
+ AddIntersectingChildren();
- while (thisTerm != null)//terminates for other reasons too!
+ while (thisTerm != null)//terminates for other reasons too!
+ {
+ //Advance curVNode pointer
+ if (curVNode.children != null)
{
- //Advance curVNode pointer
- if (curVNode.children != null)
- {
- //-- HAVE CHILDREN: DESCEND
+ //-- HAVE CHILDREN: DESCEND
- // LUCENENET NOTE: Must call this line before calling MoveNext()
- // on the enumerator.
+ // LUCENENET NOTE: Must call this line before calling MoveNext()
+ // on the enumerator.
- //if we put it there then it has something
- PreSiblings(curVNode);
+ //if we put it there then it has something
+ PreSiblings(curVNode);
- // LUCENENET IMPORTANT: Must not call this inline with Debug.Assert
- // because the compiler removes Debug.Assert statements in release mode!!
- bool hasNext = curVNode.children.MoveNext();
- if (Debugging.AssertsEnabled) Debugging.Assert(hasNext);
+ // LUCENENET IMPORTANT: Must not call this inline with Debug.Assert
+ // because the compiler removes Debug.Assert statements in release mode!!
+ bool hasNext = curVNode.children.MoveNext();
+ if (Debugging.AssertsEnabled) Debugging.Assert(hasNext);
- curVNode = curVNode.children.Current;
- }
- else
- {
- //-- NO CHILDREN: ADVANCE TO NEXT SIBLING
- VNode parentVNode = curVNode.parent;
- while (true)
- {
- if (parentVNode is null)
- {
- goto main_break;// all done
- }
- if (parentVNode.children.MoveNext())
- {
- //advance next sibling
- curVNode = parentVNode.children.Current;
- break;
- }
- else
- {
- //reached end of siblings; pop up
- PostSiblings(parentVNode);
- parentVNode.children = null;
- //GC
- parentVNode = parentVNode.parent;
- }
- }
- }
- //Seek to curVNode's cell (or skip if termsEnum has moved beyond)
- curVNodeTerm.Bytes = curVNode.cell.GetTokenBytes();
- curVNodeTerm.Length = curVNodeTerm.Bytes.Length;
- int compare = m_termsEnum.Comparer.Compare(thisTerm, curVNodeTerm);
- if (compare > 0)
- {
- // leap frog (termsEnum is beyond where we would otherwise seek)
- if (Debugging.AssertsEnabled) Debugging.Assert(!m_context.AtomicReader.GetTerms(m_outerInstance.m_fieldName).GetEnumerator().SeekExact(curVNodeTerm), "should be absent");
- }
- else
+ curVNode = curVNode.children.Current;
+ }
+ else
+ {
+ //-- NO CHILDREN: ADVANCE TO NEXT SIBLING
+ VNode? parentVNode = curVNode.parent;
+ while (true)
{
- if (compare < 0)
+ if (parentVNode is null)
{
- // Seek !
- TermsEnum.SeekStatus seekStatus = m_termsEnum.SeekCeil(curVNodeTerm);
- if (seekStatus == TermsEnum.SeekStatus.END)
- {
- break;// all done
- }
- thisTerm = m_termsEnum.Term;
- if (seekStatus == TermsEnum.SeekStatus.NOT_FOUND)
- {
- continue; // leap frog
- }
+ goto main_break;// all done
}
- // Visit!
- bool descend = Visit(curVNode.cell);
- //advance
- if (!m_termsEnum.MoveNext())
+ if (parentVNode.children!.MoveNext())
{
- thisTerm = null;
- break;// all done
+ //advance next sibling
+ curVNode = parentVNode.children.Current;
+ break;
}
- thisTerm = m_termsEnum.Term;
- if (descend)
+ else
{
- AddIntersectingChildren();
+ //reached end of siblings; pop up
+ PostSiblings(parentVNode);
+ parentVNode.children = null;
+ //GC
+ parentVNode = parentVNode.parent;
}
}
- ;
- }//main loop
- main_break: { }
-
- return Finish();
- }
-
- /// <summary>
- /// Called initially, and whenever <see cref="Visit(Lucene.Net.Spatial.Prefix.Tree.Cell)"/>
- /// returns true.
- /// </summary>
- /// <exception cref="IOException"></exception>
- private void AddIntersectingChildren()
- {
- if (Debugging.AssertsEnabled) Debugging.Assert(thisTerm != null);
- Cell cell = curVNode.cell;
- if (cell.Level >= m_outerInstance.m_detailLevel)
+ }
+ //Seek to curVNode's cell (or skip if termsEnum has moved beyond)
+ curVNodeTerm.Bytes = curVNode.cell!.GetTokenBytes();
+ curVNodeTerm.Length = curVNodeTerm.Bytes.Length;
+ int compare = m_termsEnum.Comparer.Compare(thisTerm, curVNodeTerm);
+ if (compare > 0)
{
- throw IllegalStateException.Create("Spatial logic error");
+ // leap frog (termsEnum is beyond where we would otherwise seek)
+ if (Debugging.AssertsEnabled) Debugging.Assert(!m_context.AtomicReader.GetTerms(m_filter.m_fieldName).GetEnumerator().SeekExact(curVNodeTerm), "should be absent");
}
- //Check for adjacent leaf (happens for indexed non-point shapes)
- if (m_hasIndexedLeaves && cell.Level != 0)
+ else
{
- //If the next indexed term just adds a leaf marker ('+') to cell,
- // then add all of those docs
- if (Debugging.AssertsEnabled) Debugging.Assert(StringHelper.StartsWith(thisTerm, curVNodeTerm));//TODO refactor to use method on curVNode.cell
- scanCell = m_outerInstance.m_grid.GetCell(thisTerm.Bytes, thisTerm.Offset, thisTerm.Length, scanCell);
- if (scanCell.Level == cell.Level && scanCell.IsLeaf)
+ if (compare < 0)
{
- VisitLeaf(scanCell);
- //advance
- if (!m_termsEnum.MoveNext())
+ // Seek !
+ TermsEnum.SeekStatus seekStatus = m_termsEnum.SeekCeil(curVNodeTerm);
+ if (seekStatus == TermsEnum.SeekStatus.END)
{
- return;// all done
+ break;// all done
}
thisTerm = m_termsEnum.Term;
+ if (seekStatus == TermsEnum.SeekStatus.NOT_FOUND)
+ {
+ continue; // leap frog
+ }
}
- }
-
- //Decide whether to continue to divide & conquer, or whether it's time to
- // scan through terms beneath this cell.
- // Scanning is a performance optimization trade-off.
-
- //TODO use termsEnum.docFreq() as heuristic
- bool scan = cell.Level >= ((AbstractVisitingPrefixTreeFilter)m_outerInstance).m_prefixGridScanLevel;//simple heuristic
-
- if (!scan)
- {
- //Divide & conquer (ultimately termsEnum.seek())
-
- IEnumerator<Cell> subCellsIter = FindSubCellsToVisit(cell);
- if (!subCellsIter.MoveNext())
+ // Visit!
+ bool descend = Visit(curVNode.cell);
+ //advance
+ if (!m_termsEnum.MoveNext())
{
- return;//not expected
+ thisTerm = null;
+ break;// all done
+ }
+ thisTerm = m_termsEnum.Term;
+ if (descend)
+ {
+ AddIntersectingChildren();
}
- curVNode.children = new VNodeCellIterator(subCellsIter, new VNode(curVNode));
}
- else
- {
- //Scan (loop of termsEnum.next())
+ ;
+ }//main loop
+ main_break: { }
+
+ return Finish();
+ }
- Scan(m_outerInstance.m_detailLevel);
- }
- }
+ /// <summary>
+ /// Called initially, and whenever <see cref="Visit(Cell)"/>
+ /// returns true.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ private void AddIntersectingChildren()
+ {
+ // LUCENENET specific - Use guard clause instead of assert
+ if (thisTerm is null)
+ throw new InvalidOperationException($"{nameof(thisTerm)} must not be null when calling AddIntersectingChildren().");
- /// <summary>
- /// Called when doing a divide & conquer to find the next intersecting cells
- /// of the query shape that are beneath <paramref name="cell"/>. <paramref name="cell"/> is
- /// guaranteed to have an intersection and thus this must return some number
- /// of nodes.
- /// </summary>
- protected internal virtual IEnumerator<Cell> FindSubCellsToVisit(Cell cell)
+ Cell cell = curVNode!.cell!;
+ if (cell.Level >= m_filter.m_detailLevel)
{
- return cell.GetSubCells(m_outerInstance.m_queryShape).GetEnumerator();
+ throw IllegalStateException.Create("Spatial logic error");
}
-
- /// <summary>
- /// Scans (<c>termsEnum.MoveNext()</c>) terms until a term is found that does
- /// not start with curVNode's cell. If it finds a leaf cell or a cell at
- /// level <paramref name="scanDetailLevel"/> then it calls
- /// <see cref="VisitScanned(Lucene.Net.Spatial.Prefix.Tree.Cell)"/>.
- /// </summary>
- /// <exception cref="IOException"></exception>
- protected internal virtual void Scan(int scanDetailLevel)
+ //Check for adjacent leaf (happens for indexed non-point shapes)
+ if (m_hasIndexedLeaves && cell.Level != 0)
{
- // LUCENENET specific - on the first loop, we need to check for null,
- // but on each subsequent loop, we can use the result of MoveNext()
- if (!(thisTerm is null) && StringHelper.StartsWith(thisTerm, curVNodeTerm)) //TODO refactor to use method on curVNode.cell
+ //If the next indexed term just adds a leaf marker ('+') to cell,
+ // then add all of those docs
+ if (Debugging.AssertsEnabled) Debugging.Assert(StringHelper.StartsWith(thisTerm, curVNodeTerm));//TODO refactor to use method on curVNode.cell
+ scanCell = m_filter.m_grid.GetCell(thisTerm.Bytes, thisTerm.Offset, thisTerm.Length, scanCell);
+ if (scanCell.Level == cell.Level && scanCell.IsLeaf)
{
- bool moved;
- do
+ VisitLeaf(scanCell);
+ //advance
+ if (!m_termsEnum!.MoveNext())
{
- scanCell = m_outerInstance.m_grid.GetCell(thisTerm.Bytes, thisTerm.Offset, thisTerm.Length, scanCell);
-
- int termLevel = scanCell.Level;
- if (termLevel < scanDetailLevel)
- {
- if (scanCell.IsLeaf)
- VisitScanned(scanCell);
- }
- else if (termLevel == scanDetailLevel)
- {
- if (!scanCell.IsLeaf)//LUCENE-5529
- VisitScanned(scanCell);
- }
-
- } while ((moved = m_termsEnum.MoveNext()) && StringHelper.StartsWith(thisTerm = m_termsEnum.Term, curVNodeTerm));
-
- // LUCENENET: Enusure we set thisTerm to null if the iteration ends
- if (!moved)
- thisTerm = null;
+ return;// all done
+ }
+ thisTerm = m_termsEnum.Term;
}
}
+
+ //Decide whether to continue to divide & conquer, or whether it's time to
+ // scan through terms beneath this cell.
+ // Scanning is a performance optimization trade-off.
- #region Nested type: VNodeCellIterator
+ //TODO use termsEnum.docFreq() as heuristic
+ bool scan = cell.Level >= ((AbstractVisitingPrefixTreeFilter)m_filter).PrefixGridScanLevel;//simple heuristic
- /// <summary>
- /// Used for <see cref="VNode.children"/>.
- /// </summary>
- private class VNodeCellIterator : IEnumerator<VNode>
+ if (!scan)
{
- internal readonly IEnumerator<Cell> cellIter;
- private readonly VNode vNode;
- private bool first = true;
+ //Divide & conquer (ultimately termsEnum.seek())
- internal VNodeCellIterator(IEnumerator<Cell> cellIter, VNode vNode)
+ IEnumerator<Cell> subCellsIter = FindSubCellsToVisit(cell);
+ if (!subCellsIter.MoveNext())
{
- //term loop
- this.cellIter = cellIter;
- this.vNode = vNode;
+ return;//not expected
}
+ curVNode.children = new VNodeCellEnumerator(subCellsIter, new VNode(curVNode));
+ }
+ else
+ {
+ //Scan (loop of termsEnum.next())
- //it always removes
+ Scan(m_filter.m_detailLevel);
+ }
+ }
- #region IEnumerator<VNode> Members
+ /// <summary>
+ /// Called when doing a divide & conquer to find the next intersecting cells
+ /// of the query shape that are beneath <paramref name="cell"/>. <paramref name="cell"/> is
+ /// guaranteed to have an intersection and thus this must return some number
+ /// of nodes.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="cell"/> is <c>null</c>.</exception>
+ protected virtual IEnumerator<Cell> FindSubCellsToVisit(Cell cell)
+ {
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
- public void Dispose()
- {
- cellIter.Dispose();
- }
+ return cell.GetSubCells(m_filter.m_queryShape).GetEnumerator();
+ }
- public bool MoveNext()
+ /// <summary>
+ /// Scans (<c>termsEnum.MoveNext()</c>) terms until a term is found that does
+ /// not start with curVNode's cell. If it finds a leaf cell or a cell at
+ /// level <paramref name="scanDetailLevel"/> then it calls
+ /// <see cref="VisitScanned(Cell)"/>.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ protected internal virtual void Scan(int scanDetailLevel)
+ {
+ // LUCENENET specific - on the first loop, we need to check for null,
+ // but on each subsequent loop, we can use the result of MoveNext()
+ if (!(thisTerm is null) && StringHelper.StartsWith(thisTerm, curVNodeTerm)) //TODO refactor to use method on curVNode.cell
+ {
+ // LUCENENET specific - added guard clause for m_termsEnum
+ if (m_termsEnum is null)
+ throw new InvalidOperationException($"{nameof(m_termsEnum)} must be set prior to calling Scan(int).");
+
+ bool moved;
+ do
{
- //if (Debugging.AssertsEnabled) Debugging.Assert(cellIter.Current != null);
-
- // LUCENENET NOTE: The consumer of this class calls
- // cellIter.MoveNext() before it is instantiated.
- // So, the first call here
- // to MoveNext() must not move the cursor.
- bool result;
- if (!first)
+ scanCell = m_filter.m_grid.GetCell(thisTerm.Bytes, thisTerm.Offset, thisTerm.Length, scanCell);
+
+ int termLevel = scanCell.Level;
+ if (termLevel < scanDetailLevel)
{
- result = cellIter.MoveNext();
+ if (scanCell.IsLeaf)
+ VisitScanned(scanCell);
}
- else
+ else if (termLevel == scanDetailLevel)
{
- result = true;
- first = false;
+ if (!scanCell.IsLeaf)//LUCENE-5529
+ VisitScanned(scanCell);
}
- // LUCENENET NOTE: Need to skip this call
- // if there are no more results because null
- // is not allowed
- if (result == true)
- {
- vNode.Reset(cellIter.Current);
- }
- return result;
- }
+ } while ((moved = m_termsEnum.MoveNext()) && StringHelper.StartsWith(thisTerm = m_termsEnum.Term, curVNodeTerm));
- public void Reset()
- {
- cellIter.Reset();
- }
+ // LUCENENET: Enusure we set thisTerm to null if the iteration ends
+ if (!moved)
+ thisTerm = null;
+ }
+ }
- public VNode Current => vNode;
+ #region Nested type: VNodeCellEnumerator
- object IEnumerator.Current => Current;
+ /// <summary>
+ /// Used for <see cref="VNode.children"/>.
+ /// </summary>
+ private class VNodeCellEnumerator : IEnumerator<VNode>
+ {
+ internal readonly IEnumerator<Cell> cellIter;
+ private readonly VNode vNode;
+ private bool first = true;
- #endregion
+ internal VNodeCellEnumerator(IEnumerator<Cell> cellIter, VNode vNode)
+ {
+ //term loop
+ this.cellIter = cellIter;
+ this.vNode = vNode;
}
- #endregion
-
- /// <summary>Called first to setup things.</summary>
- /// <exception cref="IOException"></exception>
- protected internal abstract void Start();
-
- /// <summary>Called last to return the result.</summary>
- /// <exception cref="IOException"></exception>
- protected internal abstract DocIdSet Finish();
-
- /// <summary>
- /// Visit an indexed cell returned from
- /// <see cref="FindSubCellsToVisit(Lucene.Net.Spatial.Prefix.Tree.Cell)"/>.
- /// </summary>
- /// <param name="cell">An intersecting cell.</param>
- /// <returns>
- /// true to descend to more levels. It is an error to return true
- /// if cell.Level == detailLevel
- /// </returns>
- /// <exception cref="IOException"></exception>
- protected internal abstract bool Visit(Cell cell);
-
- /// <summary>Called after visit() returns true and an indexed leaf cell is found.</summary>
- /// <remarks>
- /// Called after Visit() returns true and an indexed leaf cell is found. An
- /// indexed leaf cell means associated documents generally won't be found at
- /// further detail levels.
- /// </remarks>
- /// <exception cref="IOException"></exception>
- protected internal abstract void VisitLeaf(Cell cell);
-
- /// <summary>
- /// The cell is either indexed as a leaf or is the last level of detail. It
- /// might not even intersect the query shape, so be sure to check for that.
- /// </summary>
- /// <exception cref="IOException"></exception>
- protected internal abstract void VisitScanned(Cell cell);
-
- protected internal virtual void PreSiblings(VNode vNode)
+ //it always removes
+
+ #region IEnumerator<VNode> Members
+
+ public void Dispose()
{
+ cellIter.Dispose();
}
- protected internal virtual void PostSiblings(VNode vNode)
+ public bool MoveNext()
{
+ //if (Debugging.AssertsEnabled) Debugging.Assert(cellIter.Current != null);
+
+ // LUCENENET NOTE: The consumer of this class calls
+ // cellIter.MoveNext() before it is instantiated.
+ // So, the first call here
+ // to MoveNext() must not move the cursor.
+ bool result;
+ if (!first)
+ {
+ result = cellIter.MoveNext();
+ }
+ else
+ {
+ result = true;
+ first = false;
+ }
+
+ // LUCENENET NOTE: Need to skip this call
+ // if there are no more results because null
+ // is not allowed
+ if (result == true)
+ {
+ vNode.Reset(cellIter.Current);
+ }
+ return result;
+ }
+
+ public void Reset()
+ {
+ cellIter.Reset();
}
- //class VisitorTemplate
+
+ public VNode Current => vNode;
+
+ object IEnumerator.Current => Current;
+
+ #endregion IEnumerator<VNode> Members
}
- #endregion
+ #endregion Nested type: VNodeCellEnumerator
+
+ /// <summary>Called first to setup things.</summary>
+ /// <exception cref="IOException"></exception>
+ protected abstract void Start();
+
+ /// <summary>Called last to return the result.</summary>
+ /// <exception cref="IOException"></exception>
+ protected abstract DocIdSet Finish();
+
+ /// <summary>
+ /// Visit an indexed cell returned from
+ /// <see cref="FindSubCellsToVisit(Cell)"/>.
+ /// </summary>
+ /// <param name="cell">An intersecting cell.</param>
+ /// <returns>
+ /// true to descend to more levels. It is an error to return true
+ /// if cell.Level == detailLevel
+ /// </returns>
+ /// <exception cref="IOException"></exception>
+ protected abstract bool Visit(Cell cell);
+
+ /// <summary>Called after <see cref="Visit(Cell)"/> returns <c>true</c> and an indexed leaf cell is found.</summary>
+ /// <remarks>
+ /// Called after <see cref="Visit(Cell)"/> returns <c>true</c> and an indexed leaf cell is found. An
+ /// indexed leaf cell means associated documents generally won't be found at
+ /// further detail levels.
+ /// </remarks>
+ /// <exception cref="IOException"></exception>
+ protected abstract void VisitLeaf(Cell cell);
+
+ /// <summary>
+ /// The cell is either indexed as a leaf or is the last level of detail. It
+ /// might not even intersect the query shape, so be sure to check for that.
+ /// </summary>
+ /// <exception cref="IOException"></exception>
+ protected abstract void VisitScanned(Cell cell);
+
+ protected virtual void PreSiblings(VNode vNode)
+ {
+ }
+
+ protected virtual void PostSiblings(VNode vNode)
+ {
+ }
#region Nested type: VNode
@@ -477,22 +483,22 @@ namespace Lucene.Net.Spatial.Prefix
/// A Visitor node/cell found via the query shape for <see cref="VisitorTemplate"/>.
/// Sometimes these are reset(cell). It's like a LinkedList node but forms a
/// tree.
- ///
+ /// <para/>
/// @lucene.internal
/// </summary>
- public class VNode
+ protected class VNode
{
//Note: The VNode tree adds more code to debug/maintain v.s. a flattened
// LinkedList that we used to have. There is more opportunity here for
// custom behavior (see preSiblings & postSiblings) but that's not
// leveraged yet. Maybe this is slightly more GC friendly.
- internal readonly VNode parent;//only null at the root
- internal IEnumerator<VNode> children;//null, then sometimes set, then null
- internal Cell cell;//not null (except initially before reset())
+ internal readonly VNode? parent;//only null at the root
+ internal IEnumerator<VNode>? children;//null, then sometimes set, then null
+ internal Cell? cell;//not null (except initially before reset())
/// <summary>Call <see cref="Reset(Cell)"/> after to set the cell.</summary>
- internal VNode(VNode parent)
+ internal VNode(VNode? parent)
{
// remember to call reset(cell) after
this.parent = parent;
@@ -506,6 +512,7 @@ namespace Lucene.Net.Spatial.Prefix
}
}
- #endregion
- }
+ #endregion Nested type: VNode
+
+ } //class VisitorTemplate
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Spatial/Prefix/ContainsPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/ContainsPrefixTreeFilter.cs
index 6790384..f28376a 100644
--- a/src/Lucene.Net.Spatial/Prefix/ContainsPrefixTreeFilter.cs
+++ b/src/Lucene.Net.Spatial/Prefix/ContainsPrefixTreeFilter.cs
@@ -1,12 +1,11 @@
-using Lucene.Net.Diagnostics;
+using Lucene.Net.Diagnostics;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
namespace Lucene.Net.Spatial.Prefix
@@ -54,7 +53,7 @@ namespace Lucene.Net.Spatial.Prefix
this.m_multiOverlappingIndexedShapes = multiOverlappingIndexedShapes;
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (!base.Equals(o))
return false;
@@ -66,7 +65,7 @@ namespace Lucene.Net.Spatial.Prefix
return base.GetHashCode() + (m_multiOverlappingIndexedShapes ? 1 : 0);
}
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet? GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
return new ContainsVisitor(this, context, acceptDocs).Visit(m_grid.WorldCell, acceptDocs);
}
@@ -79,11 +78,11 @@ namespace Lucene.Net.Spatial.Prefix
}
internal BytesRef termBytes = new BytesRef();
- internal Cell nextCell;//see getLeafDocs
+ internal Cell? nextCell;//see getLeafDocs
/// <remarks>This is the primary algorithm; recursive. Returns null if finds none.</remarks>
/// <exception cref="IOException"></exception>
- internal SmallDocSet Visit(Cell cell, IBits acceptContains)
+ internal SmallDocSet? Visit(Cell cell, IBits acceptContains)
{
if (m_termsEnum is null)
{
@@ -91,18 +90,18 @@ namespace Lucene.Net.Spatial.Prefix
return null;
}
- ContainsPrefixTreeFilter outerInstance = (ContainsPrefixTreeFilter)base.m_outerInstance;
+ ContainsPrefixTreeFilter outerInstance = (ContainsPrefixTreeFilter)base.m_filter;
//Leaf docs match all query shape
- SmallDocSet leafDocs = GetLeafDocs(cell, acceptContains);
+ SmallDocSet? leafDocs = GetLeafDocs(cell, acceptContains);
// Get the AND of all child results (into combinedSubResults)
- SmallDocSet combinedSubResults = null;
+ SmallDocSet? combinedSubResults = null;
// Optimization: use null subCellsFilter when we know cell is within the query shape.
- IShape subCellsFilter = outerInstance.m_queryShape;
- if (cell.Level != 0 && ((cell.ShapeRel == SpatialRelation.NOT_SET || cell.ShapeRel == SpatialRelation.WITHIN)))
+ IShape? subCellsFilter = outerInstance.m_queryShape;
+ if (cell.Level != 0 && ((cell.ShapeRel == SpatialRelation.None || cell.ShapeRel == SpatialRelation.Within)))
{
subCellsFilter = null;
- if (Debugging.AssertsEnabled) Debugging.Assert(cell.Shape.Relate(outerInstance.m_queryShape) == SpatialRelation.WITHIN);
+ if (Debugging.AssertsEnabled) Debugging.Assert(cell.Shape.Relate(outerInstance.m_queryShape) == SpatialRelation.Within);
}
ICollection<Cell> subCells = cell.GetSubCells(subCellsFilter);
foreach (Cell subCell in subCells)
@@ -116,7 +115,7 @@ namespace Lucene.Net.Spatial.Prefix
combinedSubResults = GetDocs(subCell, acceptContains);
}
else if (!outerInstance.m_multiOverlappingIndexedShapes &&
- subCell.ShapeRel == SpatialRelation.WITHIN)
+ subCell.ShapeRel == SpatialRelation.Within)
{
combinedSubResults = GetLeafDocs(subCell, acceptContains); //recursion
}
@@ -155,15 +154,15 @@ namespace Lucene.Net.Spatial.Prefix
return this.m_termsEnum.SeekExact(termBytes);
}
- private SmallDocSet GetDocs(Cell cell, IBits acceptContains)
+ private SmallDocSet? GetDocs(Cell cell, IBits acceptContains)
{
if (Debugging.AssertsEnabled) Debugging.Assert(new BytesRef(cell.GetTokenBytes()).Equals(termBytes));
return this.CollectDocs(acceptContains);
}
- private Cell lastLeaf = null;//just for assertion
+ private Cell? lastLeaf = null;//just for assertion
- private SmallDocSet GetLeafDocs(Cell leafCell, IBits acceptContains)
+ private SmallDocSet? GetLeafDocs(Cell leafCell, IBits acceptContains)
{
if (Debugging.AssertsEnabled)
{
@@ -180,7 +179,7 @@ namespace Lucene.Net.Spatial.Prefix
return null;
}
BytesRef nextTerm = m_termsEnum.Term;
- nextCell = m_outerInstance.m_grid.GetCell(nextTerm.Bytes, nextTerm.Offset, nextTerm.Length, this.nextCell);
+ nextCell = m_filter.m_grid.GetCell(nextTerm.Bytes, nextTerm.Offset, nextTerm.Length, this.nextCell);
if (nextCell.Level == leafCell.Level && nextCell.IsLeaf)
{
return CollectDocs(acceptContains);
@@ -191,9 +190,16 @@ namespace Lucene.Net.Spatial.Prefix
}
}
- private SmallDocSet CollectDocs(IBits acceptContains)
+ private SmallDocSet? CollectDocs(IBits acceptContains)
{
- SmallDocSet set = null;
+ // LUCENENET specific - guard against null m_termsEnum
+ if (m_termsEnum is null)
+ {
+ //signals all done
+ return null;
+ }
+
+ SmallDocSet? set = null;
m_docsEnum = m_termsEnum.Docs(acceptContains, m_docsEnum, DocsFlags.NONE);
int docid;
@@ -253,8 +259,12 @@ namespace Lucene.Net.Spatial.Prefix
public virtual int Count => intSet.Count;
/// <summary>NOTE: modifies and returns either "this" or "other"</summary>
+ /// <exception cref="ArgumentNullException"><paramref name="other"/> is <c>null</c>.</exception>
public virtual SmallDocSet Union(SmallDocSet other)
{
+ if (other is null)
+ throw new ArgumentNullException(nameof(other));
+
SmallDocSet bigger;
SmallDocSet smaller;
if (other.intSet.Count > this.intSet.Count)
@@ -279,12 +289,12 @@ namespace Lucene.Net.Spatial.Prefix
return bigger;
}
- public override IBits Bits =>
+ public override IBits? Bits =>
//if the # of docids is super small, return null since iteration is going
// to be faster
Count > 4 ? this : null;
- public override DocIdSetIterator GetIterator()
+ public override DocIdSetIterator? GetIterator()
{
if (Count == 0)
{
diff --git a/src/Lucene.Net.Spatial/Prefix/IntersectsPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/IntersectsPrefixTreeFilter.cs
index f9672c3..c5ecf29 100644
--- a/src/Lucene.Net.Spatial/Prefix/IntersectsPrefixTreeFilter.cs
+++ b/src/Lucene.Net.Spatial/Prefix/IntersectsPrefixTreeFilter.cs
@@ -1,8 +1,9 @@
-using Lucene.Net.Index;
+using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
using System.IO;
namespace Lucene.Net.Spatial.Prefix
@@ -42,7 +43,7 @@ namespace Lucene.Net.Spatial.Prefix
this.hasIndexedLeaves = hasIndexedLeaves;
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
return base.Equals(o) && hasIndexedLeaves == ((IntersectsPrefixTreeFilter)o).hasIndexedLeaves;
}
@@ -60,7 +61,7 @@ namespace Lucene.Net.Spatial.Prefix
}
/// <exception cref="IOException"></exception>
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet? GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
return new VisitorTemplateAnonymousClass(this, context, acceptDocs, hasIndexedLeaves).GetDocIdSet();
}
@@ -69,43 +70,55 @@ namespace Lucene.Net.Spatial.Prefix
private sealed class VisitorTemplateAnonymousClass : VisitorTemplate
{
- private FixedBitSet results;
+ private FixedBitSet? results;
public VisitorTemplateAnonymousClass(IntersectsPrefixTreeFilter outerInstance, AtomicReaderContext context, IBits acceptDocs, bool hasIndexedLeaves)
: base(outerInstance, context, acceptDocs, hasIndexedLeaves)
{
}
- protected internal override void Start()
+ protected override void Start()
{
results = new FixedBitSet(m_maxDoc);
}
- protected internal override DocIdSet Finish()
+ protected override DocIdSet Finish()
{
- return results;
+ return results!;
}
- protected internal override bool Visit(Cell cell)
+ protected override bool Visit(Cell cell)
{
- if (cell.ShapeRel == SpatialRelation.WITHIN || cell.Level == m_outerInstance.m_detailLevel)
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
+ if (cell.ShapeRel == SpatialRelation.Within || cell.Level == m_filter.m_detailLevel)
{
- CollectDocs(results);
+ CollectDocs(results!);
return false;
}
return true;
}
- protected internal override void VisitLeaf(Cell cell)
+ protected override void VisitLeaf(Cell cell)
{
- CollectDocs(results);
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
+ CollectDocs(results!);
}
- protected internal override void VisitScanned(Cell cell)
+ protected override void VisitScanned(Cell cell)
{
- if (m_outerInstance.m_queryShape.Relate(cell.Shape).Intersects())
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
+ if (m_filter.m_queryShape.Relate(cell.Shape).Intersects())
{
- CollectDocs(results);
+ CollectDocs(results!);
}
}
}
diff --git a/src/Lucene.Net.Spatial/Prefix/PointPrefixTreeFieldCacheProvider.cs b/src/Lucene.Net.Spatial/Prefix/PointPrefixTreeFieldCacheProvider.cs
index d7cf8bd..e2e4a65 100644
--- a/src/Lucene.Net.Spatial/Prefix/PointPrefixTreeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Prefix/PointPrefixTreeFieldCacheProvider.cs
@@ -1,7 +1,9 @@
-using Lucene.Net.Spatial.Prefix.Tree;
+using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Util;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
+using System.Diagnostics.CodeAnalysis;
namespace Lucene.Net.Spatial.Prefix
{
@@ -23,7 +25,7 @@ namespace Lucene.Net.Spatial.Prefix
*/
/// <summary>
- /// Implementation of <see cref="Lucene.Net.Spatial.Util.ShapeFieldCacheProvider{T}"/>
+ /// Implementation of <see cref="ShapeFieldCacheProvider{T}"/>
/// designed for <see cref="PrefixTreeStrategy">PrefixTreeStrategy</see>s.
///
/// Note, due to the fragmented representation of Shapes in these Strategies, this implementation
@@ -33,17 +35,19 @@ namespace Lucene.Net.Spatial.Prefix
/// </summary>
public class PointPrefixTreeFieldCacheProvider : ShapeFieldCacheProvider<IPoint>
{
- internal readonly SpatialPrefixTree grid; //
+ private readonly SpatialPrefixTree grid; //
public PointPrefixTreeFieldCacheProvider(SpatialPrefixTree grid, string shapeField, int defaultSize)
: base(shapeField, defaultSize)
{
- this.grid = grid;
+ // LUCENENT specific - added guard clause
+ this.grid = grid ?? throw new ArgumentNullException(nameof(grid));
}
- private Cell scanCell = null;//re-used in readShape to save GC
+ private Cell? scanCell = null;//re-used in readShape to save GC
- protected internal override IPoint ReadShape(BytesRef term)
+ [return: MaybeNull]
+ protected override IPoint ReadShape(BytesRef term)
{
scanCell = grid.GetCell(term.Bytes, term.Offset, term.Length, scanCell);
if (scanCell.Level == grid.MaxLevels && !scanCell.IsLeaf)
diff --git a/src/Lucene.Net.Spatial/Prefix/PrefixTreeStrategy.cs b/src/Lucene.Net.Spatial/Prefix/PrefixTreeStrategy.cs
index a8d6b5c..c01a743 100644
--- a/src/Lucene.Net.Spatial/Prefix/PrefixTreeStrategy.cs
+++ b/src/Lucene.Net.Spatial/Prefix/PrefixTreeStrategy.cs
@@ -6,7 +6,7 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Spatial.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -31,7 +31,7 @@ namespace Lucene.Net.Spatial.Prefix
*/
/// <summary>
- /// An abstract SpatialStrategy based on <see cref="Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree"/>. The two
+ /// An abstract SpatialStrategy based on <see cref="SpatialPrefixTree"/>. The two
/// subclasses are <see cref="RecursivePrefixTreeStrategy">RecursivePrefixTreeStrategy</see> and
/// <see cref="TermQueryPrefixTreeStrategy">TermQueryPrefixTreeStrategy</see>. This strategy is most effective as a fast
/// approximate spatial search filter.
@@ -62,13 +62,13 @@ namespace Lucene.Net.Spatial.Prefix
/// </list>
///
/// <h4>Implementation:</h4>
- /// The <see cref="Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree"/>
+ /// The <see cref="SpatialPrefixTree"/>
/// does most of the work, for example returning
/// a list of terms representing grids of various sizes for a supplied shape.
/// An important
/// configuration item is <see cref="DistErrPct"/> which balances
/// shape precision against scalability. See those docs.
- ///
+ /// <para/>
/// @lucene.internal
/// </summary>
public abstract class PrefixTreeStrategy : SpatialStrategy
@@ -84,7 +84,8 @@ namespace Lucene.Net.Spatial.Prefix
protected double m_distErrPct = SpatialArgs.DEFAULT_DISTERRPCT;// [ 0 TO 0.5 ]
protected PrefixTreeStrategy(SpatialPrefixTree grid, string fieldName, bool simplifyIndexedCells) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
- : base(grid.SpatialContext, fieldName)
+ // LUCENENET specific - added guard clause
+ : base(grid is null ? throw new ArgumentNullException(nameof(grid)) : grid.SpatialContext, fieldName)
{
this.m_grid = grid;
this.m_simplifyIndexedCells = simplifyIndexedCells;
@@ -109,13 +110,13 @@ namespace Lucene.Net.Spatial.Prefix
/// <remarks>
/// The default measure of shape precision affecting shapes at index and query
/// times. Points don't use this as they are always indexed at the configured
- /// maximum precision (<see cref="Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree.MaxLevels"/>);
+ /// maximum precision (<see cref="SpatialPrefixTree.MaxLevels"/>);
/// this applies to all other shapes. Specific shapes at index and query time
/// can use something different than this default value. If you don't set a
/// default then the default is <see cref="SpatialArgs.DEFAULT_DISTERRPCT"/> --
/// 2.5%.
/// </remarks>
- /// <seealso cref="Lucene.Net.Spatial.Queries.SpatialArgs.DistErrPct"/>
+ /// <seealso cref="SpatialArgs.DistErrPct"/>
public virtual double DistErrPct
{
get => m_distErrPct;
@@ -124,11 +125,15 @@ namespace Lucene.Net.Spatial.Prefix
public override Field[] CreateIndexableFields(IShape shape)
{
+ // LUCENENET: Added guard clause
+ if (shape is null)
+ throw new ArgumentNullException(nameof(shape));
+
double distErr = SpatialArgs.CalcDistanceFromErrPct(shape, m_distErrPct, m_ctx);
return CreateIndexableFields(shape, distErr);
}
- public virtual Field[] CreateIndexableFields(IShape shape, double distErr)
+ public virtual Field[] CreateIndexableFields(IShape? shape, double distErr)
{
int detailLevel = m_grid.GetLevelForDistance(distErr);
IList<Cell> cells = m_grid.GetCells(shape, detailLevel, true, m_simplifyIndexedCells);//intermediates cells
@@ -157,15 +162,16 @@ namespace Lucene.Net.Spatial.Prefix
{
private readonly ICharTermAttribute termAtt;
- private IEnumerator<Cell> iter = null;
+ private readonly IEnumerator<Cell> iter; // LUCENENET specific - marked readonly and got rid of null setting
public CellTokenStream(IEnumerator<Cell> tokens)
{
- this.iter = tokens;
+ // LUCENENET specific - added guard clause
+ this.iter = tokens ?? throw new ArgumentNullException(nameof(tokens));
termAtt = AddAttribute<ICharTermAttribute>();
}
- internal string nextTokenStringNeedingLeaf = null;
+ internal string? nextTokenStringNeedingLeaf = null;
public override bool IncrementToken()
{
@@ -205,8 +211,7 @@ namespace Lucene.Net.Spatial.Prefix
{
if (disposing)
{
- iter?.Dispose(); // LUCENENET specific - dispose iter and set to null
- iter = null;
+ iter.Dispose(); // LUCENENET specific - dispose iter
}
}
finally
@@ -218,11 +223,15 @@ namespace Lucene.Net.Spatial.Prefix
public override ValueSource MakeDistanceValueSource(IPoint queryPoint, double multiplier)
{
+ // LUCENENET specific - added guard clause
+ if (queryPoint is null)
+ throw new ArgumentNullException(nameof(queryPoint));
+
// LUCENENET specific - use Lazy<T> to make the create operation atomic. See #417.
var p = provider.GetOrAdd(FieldName,
f => new Lazy<PointPrefixTreeFieldCacheProvider>(
() => new PointPrefixTreeFieldCacheProvider(m_grid, FieldName, m_defaultFieldValuesArrayLen)));
- return new ShapeFieldCacheDistanceValueSource(m_ctx, p.Value, queryPoint, multiplier);
+ return new ShapeFieldCacheDistanceValueSource(m_ctx, p.Value!, queryPoint, multiplier);
}
public virtual SpatialPrefixTree Grid => m_grid;
diff --git a/src/Lucene.Net.Spatial/Prefix/RecursivePrefixTreeStrategy.cs b/src/Lucene.Net.Spatial/Prefix/RecursivePrefixTreeStrategy.cs
index f804a1a..7db25f9 100644
--- a/src/Lucene.Net.Spatial/Prefix/RecursivePrefixTreeStrategy.cs
+++ b/src/Lucene.Net.Spatial/Prefix/RecursivePrefixTreeStrategy.cs
@@ -1,7 +1,8 @@
-using Lucene.Net.Search;
+using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
namespace Lucene.Net.Spatial.Prefix
{
@@ -28,7 +29,7 @@ namespace Lucene.Net.Spatial.Prefix
/// Even a query shape with distErrPct=0 (fully precise to the grid) should have
/// good performance for typical data, unless there is a lot of indexed data
/// coincident with the shape's edge.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class RecursivePrefixTreeStrategy : PrefixTreeStrategy
@@ -71,6 +72,10 @@ namespace Lucene.Net.Spatial.Prefix
public override Filter MakeFilter(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
SpatialOperation op = args.Operation;
if (op == SpatialOperation.IsDisjointTo)
{
@@ -96,7 +101,7 @@ namespace Lucene.Net.Spatial.Prefix
return new ContainsPrefixTreeFilter(shape, FieldName, m_grid, detailLevel,
m_multiOverlappingIndexedShapes);
}
- throw new UnsupportedSpatialOperation(op);
+ throw new UnsupportedSpatialOperationException(op);
}
}
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Spatial/Prefix/TermQueryPrefixTreeStrategy.cs b/src/Lucene.Net.Spatial/Prefix/TermQueryPrefixTreeStrategy.cs
index b2ca3d5..81e3c30 100644
--- a/src/Lucene.Net.Spatial/Prefix/TermQueryPrefixTreeStrategy.cs
+++ b/src/Lucene.Net.Spatial/Prefix/TermQueryPrefixTreeStrategy.cs
@@ -1,9 +1,10 @@
-using Lucene.Net.Queries;
+using Lucene.Net.Queries;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
using System.Collections.Generic;
namespace Lucene.Net.Spatial.Prefix
@@ -27,14 +28,14 @@ namespace Lucene.Net.Spatial.Prefix
/// <summary>
/// A basic implementation of <see cref="PrefixTreeStrategy"/> using a large
- /// <see cref="Lucene.Net.Queries.TermsFilter"/> of all the cells from
- /// <see cref="Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree.GetCells(IShape, int, bool, bool)"/>.
+ /// <see cref="TermsFilter"/> of all the cells from
+ /// <see cref="SpatialPrefixTree.GetCells(IShape, int, bool, bool)"/>.
/// It only supports the search of indexed Point shapes.
/// <para/>
/// The precision of query shapes (DistErrPct) is an important factor in using
/// this Strategy. If the precision is too precise then it will result in many
/// terms which will amount to a slower query.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class TermQueryPrefixTreeStrategy : PrefixTreeStrategy
@@ -46,10 +47,14 @@ namespace Lucene.Net.Spatial.Prefix
public override Filter MakeFilter(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
SpatialOperation op = args.Operation;
if (op != SpatialOperation.Intersects)
{
- throw new UnsupportedSpatialOperation(op);
+ throw new UnsupportedSpatialOperationException(op);
}
IShape shape = args.Shape;
int detailLevel = m_grid.GetLevelForDistance(args.ResolveDistErr(m_ctx, m_distErrPct));
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs b/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs
index 8ed811d..8bf141d 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/Cell.cs
@@ -1,5 +1,5 @@
using Lucene.Net.Diagnostics;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -40,7 +40,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// So we need to move the reference here and also set it before running the normal constructor
/// logic.
/// </summary>
- protected readonly SpatialPrefixTree m_outerInstance;
+ protected readonly SpatialPrefixTree m_spatialPrefixTree;
public const byte LEAF_BYTE = (byte)('+');//NOTE: must sort before letters & numbers
@@ -49,11 +49,11 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// Holds a byte[] and/or String representation of the cell. Both are lazy constructed from the other.
/// Neither contains the trailing leaf byte.
/// </summary>
- private byte[] bytes;
+ private byte[]? bytes;
private int b_off;
private int b_len;
- private string token;//this is the only part of equality
+ private string? token;//this is the only part of equality
/// <summary>
/// When set via <see cref="GetSubCells(IShape)">GetSubCells(filter)</see>, it is the relationship between this cell
@@ -69,15 +69,23 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// </remarks>
protected bool m_leaf;
- protected Cell(SpatialPrefixTree outerInstance, string token)
+ /// <summary>
+ /// Initializes a new instance of <see cref="Cell"/> for the
+ /// <paramref name="spatialPrefixTree"/> with the specified <paramref name="token"/>.
+ /// </summary>
+ /// <param name="spatialPrefixTree">The <see cref="SpatialPrefixTree"/> this instance belongs to.</param>
+ /// <param name="token">The string representation of this <see cref="Cell"/>.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="spatialPrefixTree"/> or <paramref name="token"/> is <c>null</c>.</exception>
+ protected Cell(SpatialPrefixTree spatialPrefixTree, string token)
{
// LUCENENET specific - set the outer instance here
// because overrides of Shape may require it
- this.m_outerInstance = outerInstance;
+ // LUCENENET specific - added guard clauses
+ this.m_spatialPrefixTree = spatialPrefixTree ?? throw new ArgumentNullException(nameof(spatialPrefixTree));
//NOTE: must sort before letters & numbers
//this is the only part of equality
- this.token = token;
+ this.token = token ?? throw new ArgumentNullException(nameof(token));
if (token.Length > 0 && token[token.Length - 1] == (char)LEAF_BYTE)
{
this.token = token.Substring(0, (token.Length - 1) - 0);
@@ -89,34 +97,64 @@ namespace Lucene.Net.Spatial.Prefix.Tree
}
}
- protected internal Cell(SpatialPrefixTree outerInstance, byte[] bytes, int off, int len)
+ /// <summary>
+ /// Initializes a new instance of <see cref="Cell"/> for the
+ /// <paramref name="spatialPrefixTree"/> with the specified <paramref name="bytes"/>, <paramref name="offset"/> and <paramref name="length"/>.
+ /// </summary>
+ /// <param name="spatialPrefixTree">The <see cref="SpatialPrefixTree"/> this instance belongs to.</param>
+ /// <param name="bytes">The representation of this <see cref="Cell"/>.</param>
+ /// <param name="offset">The offset into <paramref name="bytes"/> to use.</param>
+ /// <param name="length">The count of <paramref name="bytes"/> to use.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="spatialPrefixTree"/> or <paramref name="bytes"/> is <c>null</c>.</exception>
+ protected Cell(SpatialPrefixTree spatialPrefixTree, byte[] bytes, int offset, int length)
{
// LUCENENET specific - set the outer instance here
// because overrides of Shape may require it
- this.m_outerInstance = outerInstance;
+ this.m_spatialPrefixTree = spatialPrefixTree ?? throw new ArgumentNullException(nameof(spatialPrefixTree));
//ensure any lazy instantiation completes to make this threadsafe
- this.bytes = bytes;
- b_off = off;
- b_len = len;
+ this.bytes = bytes ?? throw new ArgumentNullException(nameof(bytes));
+
+ // LUCENENET specific - check that the offset and length are in bounds
+ int len = bytes.Length;
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset));
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length));
+ if (offset + length > len)
+ throw new ArgumentException($"{nameof(offset)} and {nameof(length)} must refer to a location within the array.");
+
+ b_off = offset;
+ b_len = length;
B_fixLeaf();
}
- public virtual void Reset(byte[] bytes, int off, int len)
+ public virtual void Reset(byte[] bytes, int offset, int length)
{
+ // LUCENENET specific - added guard clauses
+ if (bytes is null)
+ throw new ArgumentNullException(nameof(bytes));
+ int len = bytes.Length;
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset));
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length));
+ if (offset + length > len)
+ throw new ArgumentOutOfRangeException(nameof(length), "Offset and length must refer to a location within the array.");
+
if (Debugging.AssertsEnabled) Debugging.Assert(Level != 0);
token = null;
- m_shapeRel = SpatialRelation.NOT_SET;
+ m_shapeRel = SpatialRelation.None;
this.bytes = bytes;
- b_off = off;
- b_len = len;
+ b_off = offset;
+ b_len = length;
B_fixLeaf();
}
private void B_fixLeaf()
{
//note that non-point shapes always have the maxLevels cell set with setLeaf
- if (bytes[b_off + b_len - 1] == LEAF_BYTE)
+ if (bytes![b_off + b_len - 1] == LEAF_BYTE)
{
b_len--;
SetLeaf();
@@ -151,7 +189,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
get
{
if (token is null)
- token = Encoding.UTF8.GetString(bytes, b_off, b_len);
+ token = Encoding.UTF8.GetString(bytes!, b_off, b_len);
return token;
}
}
@@ -168,7 +206,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
}
else
{
- bytes = Encoding.UTF8.GetBytes(token);
+ bytes = Encoding.UTF8.GetBytes(token!);
b_off = 0;
b_len = bytes.Length;
}
@@ -191,13 +229,13 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// </summary>
/// <param name="shapeFilter">an optional filter for the returned cells.</param>
/// <returns>A set of cells (no dups), sorted. Not Modifiable.</returns>
- public virtual ICollection<Cell> GetSubCells(IShape shapeFilter)
+ public virtual ICollection<Cell> GetSubCells(IShape? shapeFilter)
{
//Note: Higher-performing subclasses might override to consider the shape filter to generate fewer cells.
if (shapeFilter is IPoint point)
{
Cell subCell = GetSubCell(point);
- subCell.m_shapeRel = SpatialRelation.CONTAINS;
+ subCell.m_shapeRel = SpatialRelation.Contains;
return new ReadOnlyCollection<Cell>(new[] { subCell });
}
@@ -211,12 +249,12 @@ namespace Lucene.Net.Spatial.Prefix.Tree
foreach (Cell cell in cells)
{
SpatialRelation rel = cell.Shape.Relate(shapeFilter);
- if (rel == SpatialRelation.DISJOINT)
+ if (rel == SpatialRelation.Disjoint)
{
continue;
}
cell.m_shapeRel = rel;
- if (rel == SpatialRelation.WITHIN)
+ if (rel == SpatialRelation.Within)
{
cell.SetLeaf();
}
@@ -258,19 +296,20 @@ namespace Lucene.Net.Spatial.Prefix.Tree
#region IComparable<Cell> Members
- public virtual int CompareTo(Cell o)
+ public virtual int CompareTo(Cell? other)
{
- return string.CompareOrdinal(TokenString, o.TokenString);
+ if (other is null) return 1; // LUCENENET specific - match other comparers
+ return string.CompareOrdinal(TokenString, other.TokenString);
}
#endregion
#region Equality overrides
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
return !(obj is null || !(obj is Cell cell)) &&
- TokenString.Equals(cell.TokenString, StringComparison.Ordinal);
+ TokenString.Equals(cell.TokenString, StringComparison.Ordinal);
}
public override int GetHashCode()
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/GeohashPrefixTree.cs b/src/Lucene.Net.Spatial/Prefix/Tree/GeohashPrefixTree.cs
index b9e1ce7..9ababdd 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/GeohashPrefixTree.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/GeohashPrefixTree.cs
@@ -1,6 +1,6 @@
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
-using Spatial4n.Core.Util;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
+using Spatial4n.Util;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -33,28 +33,16 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// </summary>
public class GeohashPrefixTree : SpatialPrefixTree
{
- #region Nested type: Factory
+ // LUCENENET specific - de-nested Factory and renamed GeohashPrefixTreeFactory
/// <summary>
- /// Factory for creating <see cref="GeohashPrefixTree"/>
- /// instances with useful defaults
+ /// Initializes a new instance of <see cref="GeohashPrefixTree"/> with the specified
+ /// spatial context (<paramref name="ctx"/>) and <paramref name="maxLevels"/>.
/// </summary>
- public class Factory : SpatialPrefixTreeFactory
- {
- protected internal override int GetLevelForDistance(double degrees)
- {
- var grid = new GeohashPrefixTree(m_ctx, GeohashPrefixTree.MaxLevelsPossible);
- return grid.GetLevelForDistance(degrees);
- }
-
- protected internal override SpatialPrefixTree NewSPT()
- {
- return new GeohashPrefixTree(m_ctx, m_maxLevels ?? GeohashPrefixTree.MaxLevelsPossible);
- }
- }
-
- #endregion
-
+ /// <param name="ctx">The spatial context.</param>
+ /// <param name="maxLevels">The maximum number of levels in the tree.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> is <c>null</c>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxLevels"/> is less than or equal to 0 or greater than <see cref="MaxLevelsPossible"/>.</exception>
public GeohashPrefixTree(SpatialContext ctx, int maxLevels)
: base(ctx, maxLevels)
{
@@ -71,7 +59,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
}
/// <summary>Any more than this and there's no point (double lat & lon are the same).</summary>
- public static int MaxLevelsPossible => GeohashUtils.MAX_PRECISION;
+ public static int MaxLevelsPossible => GeohashUtils.MaxPrecision;
public override int GetLevelForDistance(double dist)
{
@@ -86,6 +74,10 @@ namespace Lucene.Net.Spatial.Prefix.Tree
protected internal override Cell GetCell(IPoint p, int level)
{
+ // LUCENENET specific - added guard clause
+ if (p is null)
+ throw new ArgumentNullException(nameof(p));
+
return new GhCell(this, GeohashUtils.EncodeLatLon(p.Y, p.X, level));
}
@@ -126,7 +118,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
IList<Cell> cells = new JCG.List<Cell>(hashes.Length);
foreach (string hash in hashes)
{
- cells.Add(new GhCell((GeohashPrefixTree)m_outerInstance, hash));
+ cells.Add(new GhCell((GeohashPrefixTree)m_spatialPrefixTree, hash));
}
return cells;
}
@@ -135,10 +127,10 @@ namespace Lucene.Net.Spatial.Prefix.Tree
public override Cell GetSubCell(IPoint p)
{
- return m_outerInstance.GetCell(p, Level + 1);//not performant!
+ return m_spatialPrefixTree.GetCell(p, Level + 1);//not performant!
}
- private IShape shape;//cache
+ private IShape? shape;//cache
public override IShape Shape
{
@@ -146,13 +138,13 @@ namespace Lucene.Net.Spatial.Prefix.Tree
{
if (shape is null)
{
- shape = GeohashUtils.DecodeBoundary(Geohash, m_outerInstance.m_ctx);
+ shape = GeohashUtils.DecodeBoundary(Geohash, m_spatialPrefixTree.m_ctx);
}
return shape;
}
}
- public override IPoint Center => GeohashUtils.Decode(Geohash, m_outerInstance.m_ctx);
+ public override IPoint Center => GeohashUtils.Decode(Geohash, m_spatialPrefixTree.m_ctx);
private string Geohash => TokenString;
@@ -161,4 +153,30 @@ namespace Lucene.Net.Spatial.Prefix.Tree
#endregion
}
+
+ /// <summary>
+ /// Factory for creating <see cref="GeohashPrefixTree"/>
+ /// instances with useful defaults
+ /// </summary>
+ public class GeohashPrefixTreeFactory : SpatialPrefixTreeFactory
+ {
+ protected internal override int GetLevelForDistance(double degrees)
+ {
+ // LUCENENET specific - added guard clause
+ if (m_ctx is null)
+ throw new InvalidOperationException($"{nameof(m_ctx)} must be set prior to calling GetLevelForDistance(double).");
+
+ var grid = new GeohashPrefixTree(m_ctx, GeohashPrefixTree.MaxLevelsPossible);
+ return grid.GetLevelForDistance(degrees);
+ }
+
+ protected internal override SpatialPrefixTree NewSPT()
+ {
+ // LUCENENET specific - added guard clause
+ if (m_ctx is null)
+ throw new InvalidOperationException($"{nameof(m_ctx)} must be set prior to calling NewSPT().");
+
+ return new GeohashPrefixTree(m_ctx, m_maxLevels ?? GeohashPrefixTree.MaxLevelsPossible);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/QuadPrefixTree.cs b/src/Lucene.Net.Spatial/Prefix/Tree/QuadPrefixTree.cs
index 0032c1c..1ebc3bc 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/QuadPrefixTree.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/QuadPrefixTree.cs
@@ -1,6 +1,7 @@
using Lucene.Net.Diagnostics;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
@@ -29,31 +30,12 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// A <see cref="SpatialPrefixTree"/> which uses a
/// <a href="http://en.wikipedia.org/wiki/Quadtree">quad tree</a> in which an
/// indexed term will be generated for each cell, 'A', 'B', 'C', 'D'.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class QuadPrefixTree : SpatialPrefixTree
{
- #region Nested type: Factory
-
- /// <summary>
- /// Factory for creating <see cref="QuadPrefixTree"/> instances with useful defaults
- /// </summary>
- public class Factory : SpatialPrefixTreeFactory
- {
- protected internal override int GetLevelForDistance(double degrees)
- {
- var grid = new QuadPrefixTree(m_ctx, MAX_LEVELS_POSSIBLE);
- return grid.GetLevelForDistance(degrees);
- }
-
- protected internal override SpatialPrefixTree NewSPT()
- {
- return new QuadPrefixTree(m_ctx, m_maxLevels ?? MAX_LEVELS_POSSIBLE);
- }
- }
-
- #endregion
+ // LUCENENET specific - de-nested Factory and renamed QuadPrefixTreeFactory
public const int MAX_LEVELS_POSSIBLE = 50;//not really sure how big this should be
@@ -74,9 +56,22 @@ namespace Lucene.Net.Spatial.Prefix.Tree
internal readonly int[] levelS; // side
internal readonly int[] levelN; // number
+ /// <summary>
+ /// Initializes a new instance of <see cref="QuadPrefixTree"/> with the specified
+ /// spatial context (<paramref name="ctx"/>), <paramref name="bounds"/> and <paramref name="maxLevels"/>.
+ /// </summary>
+ /// <param name="ctx">The spatial context.</param>
+ /// <param name="bounds">The bounded rectangle.</param>
+ /// <param name="maxLevels">The maximum number of levels in the tree.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> or <paramref name="bounds"/> is <c>null</c>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxLevels"/> is less than or equal to 0.</exception>
public QuadPrefixTree(SpatialContext ctx, IRectangle bounds, int maxLevels)
: base(ctx, maxLevels)
{
+ // LUCENENET specific - added guard clause
+ if (bounds is null)
+ throw new ArgumentNullException(nameof(bounds));
+
xmin = bounds.MinX;
xmax = bounds.MaxX;
ymin = bounds.MinY;
@@ -105,23 +100,41 @@ namespace Lucene.Net.Spatial.Prefix.Tree
}
}
+ /// <summary>
+ /// Initializes a new instance of <see cref="QuadPrefixTree"/> with the specified
+ /// spatial context (<paramref name="ctx"/>).
+ /// </summary>
+ /// <param name="ctx">The spatial context.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> is <c>null</c>.</exception>
public QuadPrefixTree(SpatialContext ctx)
: this(ctx, DEFAULT_MAX_LEVELS)
{
}
+ /// <summary>
+ /// Initializes a new instance of <see cref="QuadPrefixTree"/> with the specified
+ /// spatial context (<paramref name="ctx"/>) and <paramref name="maxLevels"/>.
+ /// </summary>
+ /// <param name="ctx">The spatial context.</param>
+ /// <param name="maxLevels">The maximum number of levels in the tree.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> is <c>null</c>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxLevels"/> is less than or equal to 0.</exception>
public QuadPrefixTree(SpatialContext ctx, int maxLevels)
- : this(ctx, ctx.WorldBounds, maxLevels)
+ : this(ctx, ctx?.WorldBounds!, maxLevels)
{
}
- public virtual void PrintInfo(TextWriter @out)
+ public virtual void PrintInfo(TextWriter output)
{
+ // LUCENENET specific - added guard clause
+ if (output is null)
+ throw new ArgumentNullException(nameof(output));
+
// Format the number to min 3 integer digits and exactly 5 fraction digits
const string FORMAT_STR = @"000.00000";
for (int i = 0; i < m_maxLevels; i++)
{
- @out.WriteLine(i + "]\t" + levelW[i].ToString(FORMAT_STR) + "\t" + levelH[i].ToString(FORMAT_STR) + "\t" +
+ output.WriteLine(i + "]\t" + levelW[i].ToString(FORMAT_STR) + "\t" + levelH[i].ToString(FORMAT_STR) + "\t" +
levelS[i] + "\t" + (levelS[i] * levelS[i]));
}
}
@@ -145,6 +158,10 @@ namespace Lucene.Net.Spatial.Prefix.Tree
protected internal override Cell GetCell(IPoint p, int level)
{
+ // LUCENENET specific - added guard clause
+ if (p is null)
+ throw new ArgumentNullException(nameof(p));
+
IList<Cell> cells = new JCG.List<Cell>(1);
Build(xmid, ymid, 0, cells, new StringBuilder(), m_ctx.MakePoint(p.X, p.Y), level);
return cells[0];
@@ -156,9 +173,9 @@ namespace Lucene.Net.Spatial.Prefix.Tree
return new QuadCell(this, token);
}
- public override Cell GetCell(byte[] bytes, int offset, int len)
+ public override Cell GetCell(byte[] bytes, int offset, int length)
{
- return new QuadCell(this, bytes, offset, len);
+ return new QuadCell(this, bytes, offset, length);
}
private void Build(
@@ -203,13 +220,13 @@ namespace Lucene.Net.Spatial.Prefix.Tree
int strlen = str.Length;
IRectangle rectangle = m_ctx.MakeRectangle(cx - w, cx + w, cy - h, cy + h);
SpatialRelation v = shape.Relate(rectangle);
- if (SpatialRelation.CONTAINS == v)
+ if (SpatialRelation.Contains == v)
{
str.Append(c);
//str.append(SpatialPrefixGrid.COVER);
matches.Add(new QuadCell(this, str.ToString(), v.Transpose()));
}
- else if (SpatialRelation.DISJOINT == v)
+ else if (SpatialRelation.Disjoint == v)
{
// nothing
}
@@ -259,7 +276,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
protected internal override ICollection<Cell> GetSubCells()
{
- QuadPrefixTree outerInstance = (QuadPrefixTree)this.m_outerInstance;
+ QuadPrefixTree outerInstance = (QuadPrefixTree)this.m_spatialPrefixTree;
return new JCG.List<Cell>(4)
{
new QuadCell(outerInstance, TokenString + "A"),
@@ -273,10 +290,10 @@ namespace Lucene.Net.Spatial.Prefix.Tree
public override Cell GetSubCell(IPoint p)
{
- return m_outerInstance.GetCell(p, Level + 1);//not performant!
+ return m_spatialPrefixTree.GetCell(p, Level + 1);//not performant!
}
- private IShape shape; //cache
+ private IShape? shape; //cache
public override IShape Shape
{
@@ -292,7 +309,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
private IRectangle MakeShape()
{
- QuadPrefixTree outerInstance = (QuadPrefixTree)this.m_outerInstance;
+ QuadPrefixTree outerInstance = (QuadPrefixTree)this.m_spatialPrefixTree;
string token = TokenString;
double xmin = outerInstance.xmin;
double ymin = outerInstance.ymin;
@@ -340,4 +357,29 @@ namespace Lucene.Net.Spatial.Prefix.Tree
#endregion
}
+
+ /// <summary>
+ /// Factory for creating <see cref="QuadPrefixTree"/> instances with useful defaults
+ /// </summary>
+ public class QuadPrefixTreeFactory : SpatialPrefixTreeFactory
+ {
+ protected internal override int GetLevelForDistance(double degrees)
+ {
+ // LUCENENET specific - added guard clause
+ if (m_ctx is null)
+ throw new InvalidOperationException($"{nameof(m_ctx)} must be set prior to calling GetLevelForDistance(double).");
+
+ var grid = new QuadPrefixTree(m_ctx, QuadPrefixTree.MAX_LEVELS_POSSIBLE);
+ return grid.GetLevelForDistance(degrees);
+ }
+
+ protected internal override SpatialPrefixTree NewSPT()
+ {
+ // LUCENENET specific - added guard clause
+ if (m_ctx is null)
+ throw new InvalidOperationException($"{nameof(m_ctx)} must be set prior to calling NewSPT().");
+
+ return new QuadPrefixTree(m_ctx, m_maxLevels ?? QuadPrefixTree.MAX_LEVELS_POSSIBLE);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTree.cs b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTree.cs
index af69659..b60118b 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTree.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTree.cs
@@ -1,9 +1,9 @@
-using Lucene.Net.Diagnostics;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using J2N.Collections.Generic.Extensions;
+using Lucene.Net.Diagnostics;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using JCG = J2N.Collections.Generic;
namespace Lucene.Net.Spatial.Prefix.Tree
@@ -34,10 +34,10 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// at variable lengths corresponding to variable precision. Each string
/// corresponds to a rectangular spatial region. This approach is
/// also referred to "Grids", "Tiles", and "Spatial Tiers".
- /// <p/>
+ /// <para/>
/// Implementations of this class should be thread-safe and immutable once
/// initialized.
- ///
+ /// <para/>
/// @lucene.experimental
/// </remarks>
public abstract class SpatialPrefixTree
@@ -46,9 +46,22 @@ namespace Lucene.Net.Spatial.Prefix.Tree
protected internal readonly SpatialContext m_ctx;
+ /// <summary>
+ /// Initializes a new instance of <see cref="SpatialPrefixTree"/> with the
+ /// specified spatial context and <paramref name="maxLevels"/>.
+ /// </summary>
+ /// <param name="ctx">The spatial context.</param>
+ /// <param name="maxLevels">The maximum number of levels in the tree.</param>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> is <c>null</c>.</exception>
+ /// <exception cref="ArgumentOutOfRangeException"><paramref name="maxLevels"/> is less than or equal to 0.</exception>
protected SpatialPrefixTree(SpatialContext ctx, int maxLevels) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
{
- if (Debugging.AssertsEnabled) Debugging.Assert(maxLevels > 0);
+ // LUCENENET specific - added guard clauses
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
+ if (maxLevels <= 0)
+ throw new ArgumentOutOfRangeException(nameof(maxLevels), $"{nameof(maxLevels)} must be greater than 0.");
+
this.m_ctx = ctx;
this.m_maxLevels = maxLevels;
}
@@ -104,7 +117,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
return Math.Sqrt(width * width + height * height);
}
- private Cell worldCell;//cached
+ private Cell? worldCell;//cached
/// <summary>Returns the level 0 cell which encompasses all spatial data.</summary>
/// <remarks>
@@ -136,7 +149,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
public abstract Cell GetCell(byte[] bytes, int offset, int len);
- public Cell GetCell(byte[] bytes, int offset, int len, Cell target)
+ public Cell GetCell(byte[] bytes, int offset, int len, Cell? target)
{
if (target is null)
{
@@ -166,7 +179,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// This implementation checks if shape is a <see cref="IPoint"/> and if so returns
/// <see cref="GetCells(IPoint, int, bool)"/>.
/// </remarks>
- /// <param name="shape">the shape; non-null</param>
+ /// <param name="shape">the shape</param>
/// <param name="detailLevel">the maximum detail level to get cells for</param>
/// <param name="inclParents">
/// if true then all parent cells of leaves are returned
@@ -178,7 +191,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// ~20-25% fewer cells.
/// </param>
/// <returns>a set of cells (no dups), sorted, immutable, non-null</returns>
- public virtual IList<Cell> GetCells(IShape shape, int detailLevel, bool inclParents,
+ public virtual IList<Cell> GetCells(IShape? shape, int detailLevel, bool inclParents,
bool simplify)
{
//TODO consider an on-demand iterator -- it won't build up all cells in memory.
@@ -200,10 +213,15 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// Returns true if cell was added as a leaf. If it wasn't it recursively
/// descends.
/// </remarks>
- private bool RecursiveGetCells(Cell cell, IShape shape, int detailLevel,
+ /// <exception cref="ArgumentNullException"><paramref name="cell"/> is <c>null</c>.</exception>
+ private bool RecursiveGetCells(Cell cell, IShape? shape, int detailLevel,
bool inclParents, bool simplify,
IList<Cell> result)
{
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
if (cell.Level == detailLevel)
{
cell.SetLeaf();//FYI might already be a leaf
@@ -258,12 +276,17 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// This implementation depends on <see cref="GetCell(string)"/> being fast, as its
/// called repeatedly when incPlarents is true.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="p"/> is <c>null</c>.</exception>
public virtual IList<Cell> GetCells(IPoint p, int detailLevel, bool inclParents)
{
+ // LUCENENET specific - added guard clause
+ if (p is null)
+ throw new ArgumentNullException(nameof(p));
+
Cell cell = GetCell(p, detailLevel);
if (!inclParents)
{
- return new ReadOnlyCollection<Cell>(new[] { cell });
+ return new[] { cell }.AsReadOnly();
}
string endToken = cell.TokenString;
if (Debugging.AssertsEnabled) Debugging.Assert(endToken.Length == detailLevel);
@@ -280,6 +303,9 @@ namespace Lucene.Net.Spatial.Prefix.Tree
[Obsolete("TODO remove; not used and not interesting, don't need collection in & out")]
public static IList<string> CellsToTokenStrings(ICollection<Cell> cells)
{
+ if (cells is null)
+ throw new ArgumentNullException(nameof(cells));
+
IList<string> tokens = new JCG.List<string>((cells.Count));
foreach (Cell cell in cells)
{
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
index da0ce34..05af159 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
@@ -1,8 +1,9 @@
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
+using Spatial4n.Context;
+using Spatial4n.Distance;
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.Reflection;
namespace Lucene.Net.Spatial.Prefix.Tree
{
@@ -26,7 +27,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// <summary>
/// Abstract Factory for creating <see cref="SpatialPrefixTree"/> instances with useful
/// defaults and passed on configurations defined in a <see cref="IDictionary{TKey, TValue}"/>.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public abstract class SpatialPrefixTreeFactory
@@ -36,8 +37,8 @@ namespace Lucene.Net.Spatial.Prefix.Tree
public const string MAX_LEVELS = "maxLevels";
public const string MAX_DIST_ERR = "maxDistErr";
- protected IDictionary<string, string> m_args;
- protected SpatialContext m_ctx;
+ protected IDictionary<string, string>? m_args;
+ protected SpatialContext? m_ctx;
protected int? m_maxLevels;
/// <summary>The factory is looked up via "prefixTree" in <paramref name="args"/>, expecting "geohash" or "quad".</summary>
@@ -45,27 +46,47 @@ namespace Lucene.Net.Spatial.Prefix.Tree
/// The factory is looked up via "prefixTree" in <paramref name="args"/>, expecting "geohash" or "quad".
/// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
/// </remarks>
- public static SpatialPrefixTree MakeSPT(IDictionary<string, string> args, SpatialContext ctx)
+ /// <exception cref="ArgumentNullException"><paramref name="args"/> or <paramref name="ctx"/> is <c>null</c>.</exception>
+ public static SpatialPrefixTree MakeSPT(IDictionary<string, string> args, SpatialContext ctx) // LUCENENET specific overload for convenience.
+ => MakeSPT(args, null, ctx);
+
+ /// <summary>The factory is looked up via "prefixTree" in <paramref name="args"/>, expecting "geohash" or "quad".</summary>
+ /// <remarks>
+ /// The factory is looked up via "prefixTree" in <paramref name="args"/>, expecting "geohash" or "quad".
+ /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
+ /// </remarks>
+ /// <exception cref="ArgumentNullException"><paramref name="args"/> or <paramref name="ctx"/> is <c>null</c>.</exception>
+ public static SpatialPrefixTree MakeSPT(IDictionary<string, string> args, Assembly? assembly, SpatialContext ctx)
{
- SpatialPrefixTreeFactory instance;
- if (!args.TryGetValue(PREFIX_TREE, out string cname))
+ // LUCENENET specific - added guard clauses
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+ if (assembly is null)
+ assembly = typeof(SpatialPrefixTreeFactory).Assembly;
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
+
+ SpatialPrefixTreeFactory? instance;
+ if (!args.TryGetValue(PREFIX_TREE, out string? cname))
{
cname = ctx.IsGeo ? "geohash" : "quad";
}
if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase))
{
- instance = new GeohashPrefixTree.Factory();
+ instance = new GeohashPrefixTreeFactory();
}
else if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase))
{
- instance = new QuadPrefixTree.Factory();
+ instance = new QuadPrefixTreeFactory();
}
else
{
try
{
- Type c = Type.GetType(cname);
- instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(c);
+ Type? c = assembly.GetType(cname) ?? Type.GetType(cname);
+ if (c is null)
+ throw RuntimeException.Create($"{cname} not found in {assembly.GetName().FullName} or by using Type.GetType(string).");// LUCENENET specific - .NET doesn't throw when the type is not found.
+ instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(c)!;
}
catch (Exception e) when (e.IsException())
{
@@ -78,27 +99,31 @@ namespace Lucene.Net.Spatial.Prefix.Tree
protected internal virtual void Init(IDictionary<string, string> args, SpatialContext ctx)
{
- this.m_args = args;
- this.m_ctx = ctx;
+ // LUCENENET specific - added guard clauses
+ this.m_args = args ?? throw new ArgumentNullException(nameof(args));
+ this.m_ctx = ctx ?? throw new ArgumentNullException(nameof(ctx));
InitMaxLevels();
}
protected internal virtual void InitMaxLevels()
{
- if (m_args.TryGetValue(MAX_LEVELS, out string mlStr))
+ if (m_args is null || m_ctx is null)
+ throw new InvalidOperationException($"Init(IDictionary<string, string>, SpatialContext) must be called prior to calling InitMaxLevels()");
+
+ if (m_args.TryGetValue(MAX_LEVELS, out string? mlStr))
{
m_maxLevels = int.Parse(mlStr, CultureInfo.InvariantCulture);
return;
}
double degrees;
- if (!m_args.TryGetValue(MAX_DIST_ERR, out string maxDetailDistStr))
+ if (!m_args.TryGetValue(MAX_DIST_ERR, out string? maxDetailDistStr))
{
if (!m_ctx.IsGeo)
{
return;
}
//let default to max
- degrees = DistanceUtils.Dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+ degrees = DistanceUtils.Dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EarthMeanRadiusKilometers);
}
else
{
@@ -108,7 +133,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
}
/// <summary>
- /// Calls <see cref="SpatialPrefixTree.GetLevelForDistance(double)">SpatialPrefixTree.GetLevelForDistance(double)</see>.
+ /// Calls <see cref="SpatialPrefixTree.GetLevelForDistance(double)" />.
/// </summary>
protected internal abstract int GetLevelForDistance(double degrees);
diff --git a/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
index d61fc10..ca88222 100644
--- a/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
+++ b/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
@@ -3,12 +3,11 @@ using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Util;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.IO;
namespace Lucene.Net.Spatial.Prefix
@@ -42,7 +41,7 @@ namespace Lucene.Net.Spatial.Prefix
/// beyond the query shape's edge. Even if the indexed shapes are sometimes
/// comprised of multiple disjoint parts, you might want to use this option with
/// a large buffer as a faster approximation with minimal false-positives.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class WithinPrefixTreeFilter : AbstractVisitingPrefixTreeFilter
@@ -51,10 +50,10 @@ namespace Lucene.Net.Spatial.Prefix
// minimal query buffer by looking in a DocValues cache holding a representative
// point of each disjoint component of a document's shape(s).
- private readonly IShape bufferedQueryShape;//if null then the whole world
+ private readonly IShape? bufferedQueryShape;//if null then the whole world
/// <summary>
- /// See <see cref="AbstractVisitingPrefixTreeFilter.AbstractVisitingPrefixTreeFilter(IShape, string, SpatialPrefixTree, int, int)"/>.
+ /// See <see cref="AbstractVisitingPrefixTreeFilter(IShape, string, SpatialPrefixTree, int, int)"/>.
/// <c>queryBuffer</c> is the (minimum) distance beyond the query shape edge
/// where non-matching documents are looked for so they can be excluded. If
/// -1 is used then the whole world is examined (a good default for correctness).
@@ -78,6 +77,10 @@ namespace Lucene.Net.Spatial.Prefix
/// </summary>
protected virtual IShape BufferShape(IShape shape, double distErr)
{
+ // LUCENENET specific - added guard clause
+ if (shape is null)
+ throw new ArgumentNullException(nameof(shape));
+
//TODO move this generic code elsewhere? Spatial4j?
if (distErr <= 0)
{
@@ -138,7 +141,7 @@ namespace Lucene.Net.Spatial.Prefix
}
/// <exception cref="IOException"></exception>
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet? GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
{
return new VisitorTemplateAnonymousClass(this, context, acceptDocs, true).GetDocIdSet();
}
@@ -147,73 +150,85 @@ namespace Lucene.Net.Spatial.Prefix
private sealed class VisitorTemplateAnonymousClass : VisitorTemplate
{
- private FixedBitSet inside;
- private FixedBitSet outside;
+ private FixedBitSet? inside;
+ private FixedBitSet? outside;
private SpatialRelation visitRelation;
public VisitorTemplateAnonymousClass(WithinPrefixTreeFilter outerInstance, AtomicReaderContext context,
- IBits acceptDocs, bool hasIndexedLeaves)
+ IBits? acceptDocs, bool hasIndexedLeaves)
: base(outerInstance, context, acceptDocs, hasIndexedLeaves)
{
}
- protected internal override void Start()
+ protected override void Start()
{
inside = new FixedBitSet(m_maxDoc);
outside = new FixedBitSet(m_maxDoc);
}
- protected internal override DocIdSet Finish()
+ protected override DocIdSet Finish()
{
- inside.AndNot(outside);
+ inside!.AndNot(outside!);
return inside;
}
- protected internal override IEnumerator<Cell> FindSubCellsToVisit(Cell cell)
+ protected override IEnumerator<Cell> FindSubCellsToVisit(Cell cell)
{
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
//use buffered query shape instead of orig. Works with null too.
- return cell.GetSubCells(((WithinPrefixTreeFilter)m_outerInstance).bufferedQueryShape).GetEnumerator();
+ return cell.GetSubCells(((WithinPrefixTreeFilter)m_filter).bufferedQueryShape).GetEnumerator();
}
- protected internal override bool Visit(Cell cell)
+ protected override bool Visit(Cell cell)
{
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
//cell.relate is based on the bufferedQueryShape; we need to examine what
// the relation is against the queryShape
- visitRelation = cell.Shape.Relate(m_outerInstance.m_queryShape);
- if (visitRelation == SpatialRelation.WITHIN)
+ visitRelation = cell.Shape.Relate(m_filter.m_queryShape);
+ if (visitRelation == SpatialRelation.Within)
{
- CollectDocs(inside);
+ CollectDocs(inside!);
return false;
}
- else if (visitRelation == SpatialRelation.DISJOINT)
+ else if (visitRelation == SpatialRelation.Disjoint)
{
- CollectDocs(outside);
+ CollectDocs(outside!);
return false;
}
- else if (cell.Level == m_outerInstance.m_detailLevel)
+ else if (cell.Level == m_filter.m_detailLevel)
{
- CollectDocs(inside);
+ CollectDocs(inside!);
return false;
}
return true;
}
/// <exception cref="IOException"></exception>
- protected internal override void VisitLeaf(Cell cell)
+ protected override void VisitLeaf(Cell cell)
{
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
//visitRelation is declared as a field, populated by visit() so we don't recompute it
if (Debugging.AssertsEnabled)
{
- Debugging.Assert(m_outerInstance.m_detailLevel != cell.Level);
- Debugging.Assert(visitRelation == cell.Shape.Relate(m_outerInstance.m_queryShape));
+ Debugging.Assert(m_filter.m_detailLevel != cell.Level);
+ Debugging.Assert(visitRelation == cell.Shape.Relate(m_filter.m_queryShape));
}
if (AllCellsIntersectQuery(cell, visitRelation))
{
- CollectDocs(inside);
+ CollectDocs(inside!);
}
else
{
- CollectDocs(outside);
+ CollectDocs(outside!);
}
}
@@ -223,19 +238,23 @@ namespace Lucene.Net.Spatial.Prefix
/// </summary>
private bool AllCellsIntersectQuery(Cell cell, SpatialRelation relate/*cell to query*/)
{
- if (relate == SpatialRelation.NOT_SET)
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
+ if (relate == SpatialRelation.None)
{
- relate = cell.Shape.Relate(m_outerInstance.m_queryShape);
+ relate = cell.Shape.Relate(m_filter.m_queryShape);
}
- if (cell.Level == m_outerInstance.m_detailLevel)
+ if (cell.Level == m_filter.m_detailLevel)
{
return relate.Intersects();
}
- if (relate == SpatialRelation.WITHIN)
+ if (relate == SpatialRelation.Within)
{
return true;
}
- if (relate == SpatialRelation.DISJOINT)
+ if (relate == SpatialRelation.Disjoint)
{
return false;
}
@@ -245,7 +264,7 @@ namespace Lucene.Net.Spatial.Prefix
ICollection<Cell> subCells = cell.GetSubCells(null);
foreach (Cell subCell in subCells)
{
- if (!AllCellsIntersectQuery(subCell, SpatialRelation.NOT_SET))
+ if (!AllCellsIntersectQuery(subCell, SpatialRelation.None))
{
//recursion
return false;
@@ -255,15 +274,19 @@ namespace Lucene.Net.Spatial.Prefix
}
/// <exception cref="IOException"></exception>
- protected internal override void VisitScanned(Cell cell)
+ protected override void VisitScanned(Cell cell)
{
- if (AllCellsIntersectQuery(cell, SpatialRelation.NOT_SET))
+ // LUCENENET specific - added guard clause
+ if (cell is null)
+ throw new ArgumentNullException(nameof(cell));
+
+ if (AllCellsIntersectQuery(cell, SpatialRelation.None))
{
- CollectDocs(inside);
+ CollectDocs(inside!);
}
else
{
- CollectDocs(outside);
+ CollectDocs(outside!);
}
}
}
diff --git a/src/Lucene.Net.Spatial/Query/SpatialArgs.cs b/src/Lucene.Net.Spatial/Query/SpatialArgs.cs
index 2927c9f..2a2c05c 100644
--- a/src/Lucene.Net.Spatial/Query/SpatialArgs.cs
+++ b/src/Lucene.Net.Spatial/Query/SpatialArgs.cs
@@ -1,5 +1,5 @@
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial.Queries
@@ -39,8 +39,8 @@ namespace Lucene.Net.Spatial.Queries
public SpatialArgs(SpatialOperation operation, IShape shape)
{
// LUCENENET specific - changed from IllegalArgumentException to ArgumentNullException (.NET convention)
- this.Operation = operation ?? throw new ArgumentNullException(nameof(operation), "operation and shape are required");
- this.Shape = shape ?? throw new ArgumentNullException(nameof(shape), "operation and shape are required");
+ this.operation = operation ?? throw new ArgumentNullException(nameof(operation), "operation and shape are required");
+ this.shape = shape ?? throw new ArgumentNullException(nameof(shape), "operation and shape are required");
}
/// <summary>
@@ -54,7 +54,9 @@ namespace Lucene.Net.Spatial.Queries
/// <returns>A distance (in degrees).</returns>
public static double CalcDistanceFromErrPct(IShape shape, double distErrPct, SpatialContext ctx)
{
- // LUCENENET: Added null guard clause
+ // LUCENENET: Added null guard clauses
+ if (shape is null)
+ throw new ArgumentNullException(nameof(shape));
if (ctx is null)
throw new ArgumentNullException(nameof(ctx));
@@ -73,7 +75,7 @@ namespace Lucene.Net.Spatial.Queries
// take the closest one (greater precision).
IPoint ctr = bbox.Center;
double y = (ctr.Y >= 0 ? bbox.MaxY : bbox.MinY);
- double diagonalDist = ctx.DistCalc.Distance(ctr, bbox.MaxX, y);
+ double diagonalDist = ctx.DistanceCalculator.Distance(ctr, bbox.MaxX, y);
return diagonalDist * distErrPct;
}
@@ -89,6 +91,9 @@ namespace Lucene.Net.Spatial.Queries
{
if (DistErr != null)
return DistErr.Value;
+ // LUCENENET specific - added guard clause
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
double distErrPct = (this.distErrPct ?? defaultDistErrPct);
return CalcDistanceFromErrPct(Shape, distErrPct, ctx);
}
@@ -121,13 +126,13 @@ namespace Lucene.Net.Spatial.Queries
public virtual SpatialOperation Operation
{
get => operation;
- set => operation = value;
+ set => operation = value ?? throw new ArgumentNullException(nameof(Operation)); // LUCENENET specific - added guard clause
}
public virtual IShape Shape
{
get => shape;
- set => shape = value;
+ set => shape = value ?? throw new ArgumentNullException(nameof(Shape)); // LUCENENET specific - added guard clause
}
/// <summary>
diff --git a/src/Lucene.Net.Spatial/Query/SpatialArgsParser.cs b/src/Lucene.Net.Spatial/Query/SpatialArgsParser.cs
index 5ea9ce5..42e16c7 100644
--- a/src/Lucene.Net.Spatial/Query/SpatialArgsParser.cs
+++ b/src/Lucene.Net.Spatial/Query/SpatialArgsParser.cs
@@ -1,7 +1,7 @@
using J2N.Text;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Exceptions;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Exceptions;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -29,7 +29,7 @@ namespace Lucene.Net.Spatial.Queries
/// <summary>
/// Parses a string that usually looks like "OPERATION(SHAPE)" into a <see cref="SpatialArgs"/>
/// object. The set of operations supported are defined in <see cref="SpatialOperation"/>, such
- /// as "Intersects" being a common one. The shape portion is defined by WKT <see cref="Spatial4n.Core.IO.WktShapeParser"/>,
+ /// as "Intersects" being a common one. The shape portion is defined by WKT <see cref="Spatial4n.IO.WktShapeParser"/>,
/// but it can be overridden/customized via <see cref="ParseShape(string, SpatialContext)"/>.
/// There are some optional name-value pair parameters that follow the closing parenthesis. Example:
/// <code>
@@ -39,7 +39,7 @@ namespace Lucene.Net.Spatial.Queries
/// In the future it would be good to support something at least semi-standardized like a
/// variant of <a href="http://docs.geoserver.org/latest/en/user/filter/ecql_reference.html#spatial-predicate">
/// [E]CQL</a>.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class SpatialArgsParser
@@ -52,6 +52,10 @@ namespace Lucene.Net.Spatial.Queries
/// </summary>
public static string WriteSpatialArgs(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
var str = new StringBuilder();
str.Append(args.Operation.Name);
str.Append('(');
@@ -70,17 +74,24 @@ namespace Lucene.Net.Spatial.Queries
/// <param name="v">The string to parse. Mandatory.</param>
/// <param name="ctx">The spatial context. Mandatory.</param>
/// <returns>Not null.</returns>
- /// <exception cref="ArgumentException">if the parameters don't make sense or an add-on parameter is unknown</exception>
- /// <exception cref="Spatial4n.Core.Exceptions.ParseException">If there is a problem parsing the string</exception>
- /// <exception cref="InvalidShapeException">When the coordinates are invalid for the shape</exception>
+ /// <exception cref="ArgumentException">if the parameters don't make sense or an add-on parameter is unknown.</exception>
+ /// <exception cref="Spatial4n.Exceptions.ParseException">If there is a problem parsing the string.</exception>
+ /// <exception cref="InvalidShapeException">When the coordinates are invalid for the shape.</exception>
+ /// <exception cref="ArgumentNullException"><paramref name="v"/> or <paramref name="ctx"/> is <c>null</c>.</exception>
public virtual SpatialArgs Parse(string v, SpatialContext ctx)
{
+ // LUCENENET specific - added guard clauses
+ if (v is null)
+ throw new ArgumentNullException(nameof(v));
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
+
int idx = v.IndexOf('(');
int edx = v.LastIndexOf(')');
if (idx < 0 || idx > edx)
{
- throw new Spatial4n.Core.Exceptions.ParseException("missing parens: " + v, -1);
+ throw new Spatial4n.Exceptions.ParseException("missing parens: " + v, -1);
}
SpatialOperation op = SpatialOperation.Get(v.Substring(0, idx - 0).Trim());
@@ -90,7 +101,7 @@ namespace Lucene.Net.Spatial.Queries
string body = v.Substring(idx + 1, edx - (idx + 1)).Trim();
if (body.Length < 1)
{
- throw new Spatial4n.Core.Exceptions.ParseException("missing body : " + v, idx + 1);
+ throw new Spatial4n.Exceptions.ParseException("missing body : " + v, idx + 1);
}
var shape = ParseShape(body, ctx);
@@ -118,28 +129,42 @@ namespace Lucene.Net.Spatial.Queries
return new SpatialArgs(op, shape);
}
+ /// <exception cref="ArgumentNullException"><paramref name="args"/> or <paramref name="nameValPairs"/> is <c>null</c>.</exception>
protected virtual void ReadNameValuePairs(SpatialArgs args, IDictionary<string, string> nameValPairs)
{
- nameValPairs.TryGetValue(DIST_ERR_PCT, out string distErrPctStr);
- nameValPairs.TryGetValue(DIST_ERR, out string distErrStr);
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+ if (nameValPairs is null)
+ throw new ArgumentNullException(nameof(nameValPairs));
+
+ nameValPairs.TryGetValue(DIST_ERR_PCT, out string? distErrPctStr);
+ nameValPairs.TryGetValue(DIST_ERR, out string? distErrStr);
args.DistErrPct = ReadDouble(distErrPctStr);
nameValPairs.Remove(DIST_ERR_PCT);
args.DistErr = ReadDouble(distErrStr);
nameValPairs.Remove(DIST_ERR);
}
+ /// <exception cref="ArgumentNullException"><paramref name="str"/> or <paramref name="ctx"/> is <c>null</c>.</exception>
protected virtual IShape ParseShape(string str, SpatialContext ctx)
{
+ // LUCENENET specific - added guard clauses
+ if (str is null)
+ throw new ArgumentNullException(nameof(str));
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
+
//return ctx.readShape(str);//still in Spatial4n 0.4 but will be deleted
return ctx.ReadShapeFromWkt(str);
}
- protected static double? ReadDouble(string v)
+ protected static double? ReadDouble(string? v)
{
return double.TryParse(v, NumberStyles.Float, CultureInfo.InvariantCulture, out double val) ? val : (double?)null;
}
- protected static bool ReadBool(string v, bool defaultValue)
+ protected static bool ReadBool(string? v, bool defaultValue)
{
return bool.TryParse(v, out bool ret) ? ret : defaultValue;
}
@@ -148,8 +173,13 @@ namespace Lucene.Net.Spatial.Queries
/// Parses "a=b c=d f" (whitespace separated) into name-value pairs. If there
/// is no '=' as in 'f' above then it's short for f=f.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="body"/> is <c>null</c>.</exception>
protected static IDictionary<string, string> ParseMap(string body)
{
+ // LUCENENET specific - added guard clause
+ if (body is null)
+ throw new ArgumentNullException(nameof(body));
+
var map = new Dictionary<string, string>();
StringTokenizer st = new StringTokenizer(body, " \n\t");
diff --git a/src/Lucene.Net.Spatial/Query/SpatialOperation.cs b/src/Lucene.Net.Spatial/Query/SpatialOperation.cs
index c2bcf84..8072e76 100644
--- a/src/Lucene.Net.Spatial/Query/SpatialOperation.cs
+++ b/src/Lucene.Net.Spatial/Query/SpatialOperation.cs
@@ -1,4 +1,4 @@
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -54,6 +54,12 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
return indexedShape.BoundingBox.Relate(queryShape).Intersects();
}
}
@@ -71,8 +77,14 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
IRectangle bbox = indexedShape.BoundingBox;
- return bbox.Relate(queryShape) == SpatialRelation.WITHIN || bbox.Equals(queryShape);
+ return bbox.Relate(queryShape) == SpatialRelation.Within || bbox.Equals(queryShape);
}
}
@@ -86,7 +98,13 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
- return indexedShape.HasArea && indexedShape.Relate(queryShape) == SpatialRelation.CONTAINS || indexedShape.Equals(queryShape);
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
+ return indexedShape.HasArea && indexedShape.Relate(queryShape) == SpatialRelation.Contains || indexedShape.Equals(queryShape);
}
}
@@ -100,6 +118,12 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
return indexedShape.Relate(queryShape).Intersects();
}
}
@@ -114,6 +138,12 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
return indexedShape.Equals(queryShape);
}
}
@@ -128,6 +158,12 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
return !indexedShape.Relate(queryShape).Intersects();
}
}
@@ -142,7 +178,13 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
- return queryShape.HasArea && (indexedShape.Relate(queryShape) == SpatialRelation.WITHIN || indexedShape.Equals(queryShape));
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
+ return queryShape.HasArea && (indexedShape.Relate(queryShape) == SpatialRelation.Within || indexedShape.Equals(queryShape));
}
}
@@ -156,6 +198,12 @@ namespace Lucene.Net.Spatial.Queries
public override bool Evaluate(IShape indexedShape, IShape queryShape)
{
+ // LUCENENET specific - added guard clauses
+ if (indexedShape is null)
+ throw new ArgumentNullException(nameof(indexedShape));
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
return queryShape.HasArea && indexedShape.Relate(queryShape).Intersects();
}
}
@@ -180,7 +228,7 @@ namespace Lucene.Net.Spatial.Queries
public static SpatialOperation Get(string v)
{
- if (!registry.TryGetValue(v, out SpatialOperation op) || op is null)
+ if (!registry.TryGetValue(v, out SpatialOperation? op) || op is null)
{
if (!registry.TryGetValue(CultureInfo.InvariantCulture.TextInfo.ToUpper(v), out op) || op is null)
throw new ArgumentException($"Unknown Operation: {v}", nameof(v));
@@ -204,6 +252,7 @@ namespace Lucene.Net.Spatial.Queries
/// Returns whether the relationship between <paramref name="indexedShape"/> and <paramref name="queryShape"/> is
/// satisfied by this operation.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="indexedShape"/> or <paramref name="queryShape"/> is <c>null</c>.</exception>
public abstract bool Evaluate(IShape indexedShape, IShape queryShape);
// ================================================= Getters / Setters =============================================
diff --git a/src/Lucene.Net.Spatial/Query/UnsupportedSpatialOperation.cs b/src/Lucene.Net.Spatial/Query/UnsupportedSpatialOperation.cs
index d3952b1..9e1c57d 100644
--- a/src/Lucene.Net.Spatial/Query/UnsupportedSpatialOperation.cs
+++ b/src/Lucene.Net.Spatial/Query/UnsupportedSpatialOperation.cs
@@ -24,7 +24,7 @@ namespace Lucene.Net.Spatial.Queries
/// <summary>
/// Exception thrown when the <see cref="SpatialStrategy"/> cannot implement the requested operation.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
// LUCENENET: It is no longer good practice to use binary serialization.
@@ -32,15 +32,15 @@ namespace Lucene.Net.Spatial.Queries
#if FEATURE_SERIALIZABLE_EXCEPTIONS
[Serializable]
#endif
- public class UnsupportedSpatialOperation : NotSupportedException
+ public class UnsupportedSpatialOperationException : NotSupportedException
{
- public UnsupportedSpatialOperation(SpatialOperation op)
- : base(op.Name)
+ public UnsupportedSpatialOperationException(SpatialOperation? op)
+ : base(op?.Name)
{
}
// For testing
- internal UnsupportedSpatialOperation(string message)
+ internal UnsupportedSpatialOperationException(string? message)
: base(message)
{
}
@@ -51,7 +51,7 @@ namespace Lucene.Net.Spatial.Queries
/// </summary>
/// <param name="info">The <see cref="SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="StreamingContext"/> that contains contextual information about the source or destination.</param>
- protected UnsupportedSpatialOperation(SerializationInfo info, StreamingContext context)
+ protected UnsupportedSpatialOperationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
diff --git a/src/Lucene.Net.Spatial/Serialized/SerializedDVStrategy.cs b/src/Lucene.Net.Spatial/Serialized/SerializedDVStrategy.cs
index 551ce9a..df3960a 100644
--- a/src/Lucene.Net.Spatial/Serialized/SerializedDVStrategy.cs
+++ b/src/Lucene.Net.Spatial/Serialized/SerializedDVStrategy.cs
@@ -5,9 +5,9 @@ using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Spatial.Util;
using Lucene.Net.Util;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.IO;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.IO;
+using Spatial4n.Shapes;
using System;
using System.Collections;
using System.IO;
@@ -52,6 +52,7 @@ namespace Lucene.Net.Spatial.Serialized
/// <summary>
/// Constructs the spatial strategy with its mandatory arguments.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> or <paramref name="fieldName"/> is <c>null</c> or <paramref name="fieldName"/> is empty.</exception>
public SerializedDVStrategy(SpatialContext ctx, string fieldName)
: base(ctx, fieldName)
{
@@ -59,6 +60,10 @@ namespace Lucene.Net.Spatial.Serialized
public override Field[] CreateIndexableFields(IShape shape)
{
+ // LUCENENET specific - added guard clause
+ if (shape is null)
+ throw new ArgumentNullException(nameof(shape));
+
int bufSize = Math.Max(128, (int)(this.indexLastBufSize * 1.5));//50% headroom over last
MemoryStream byteStream = new MemoryStream(bufSize);
BytesRef bytesRef = new BytesRef();//receiver of byteStream's bytes
@@ -83,7 +88,8 @@ namespace Lucene.Net.Spatial.Serialized
public OutputStreamAnonymousClass(BytesRef bytesRef)
{
- this.bytesRef = bytesRef;
+ // LUCENENET specific - added guard clause
+ this.bytesRef = bytesRef ?? throw new ArgumentNullException(nameof(bytesRef));
}
public override void Write(byte[] buffer, int index, int count)
@@ -113,6 +119,10 @@ namespace Lucene.Net.Spatial.Serialized
/// </summary>
public override Filter MakeFilter(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
ValueSource shapeValueSource = MakeShapeValueSource();
ShapePredicateValueSource predicateValueSource = new ShapePredicateValueSource(
shapeValueSource, args.Operation, args.Shape);
@@ -139,10 +149,11 @@ namespace Lucene.Net.Spatial.Serialized
public PredicateValueSourceFilter(ValueSource predicateValueSource)
{
- this.predicateValueSource = predicateValueSource;
+ // LUCENENET specific - added guard clause
+ this.predicateValueSource = predicateValueSource ?? throw new ArgumentNullException(nameof(predicateValueSource));
}
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits? acceptDocs)
{
return new DocIdSetAnonymousClass(this, context, acceptDocs);
}
@@ -151,12 +162,13 @@ namespace Lucene.Net.Spatial.Serialized
{
private readonly PredicateValueSourceFilter outerInstance;
private readonly AtomicReaderContext context;
- private readonly IBits acceptDocs;
+ private readonly IBits? acceptDocs;
- public DocIdSetAnonymousClass(PredicateValueSourceFilter outerInstance, AtomicReaderContext context, IBits acceptDocs)
+ public DocIdSetAnonymousClass(PredicateValueSourceFilter outerInstance, AtomicReaderContext context, IBits? acceptDocs)
{
- this.outerInstance = outerInstance;
- this.context = context;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ this.context = context ?? throw new ArgumentNullException(nameof(context));
this.acceptDocs = acceptDocs;
}
@@ -182,12 +194,13 @@ namespace Lucene.Net.Spatial.Serialized
{
private readonly FunctionValues predFuncValues;
private readonly AtomicReaderContext context;
- private readonly IBits acceptDocs;
+ private readonly IBits? acceptDocs;
- public BitsAnonymousClass(FunctionValues predFuncValues, AtomicReaderContext context, IBits acceptDocs)
+ public BitsAnonymousClass(FunctionValues predFuncValues, AtomicReaderContext context, IBits? acceptDocs)
{
- this.predFuncValues = predFuncValues;
- this.context = context;
+ // LUCENENET specific - added guard clauses
+ this.predFuncValues = predFuncValues ?? throw new ArgumentNullException(nameof(predFuncValues));
+ this.context = context ?? throw new ArgumentNullException(nameof(context));
this.acceptDocs = acceptDocs;
}
@@ -202,7 +215,7 @@ namespace Lucene.Net.Spatial.Serialized
}
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
@@ -232,12 +245,17 @@ namespace Lucene.Net.Spatial.Serialized
internal ShapeDocValueSource(string fieldName, BinaryCodec binaryCodec)
{
- this.fieldName = fieldName;
- this.binaryCodec = binaryCodec;
+ // LUCENENET specific - added guard clauses
+ this.fieldName = fieldName ?? throw new ArgumentNullException(nameof(fieldName));
+ this.binaryCodec = binaryCodec ?? throw new ArgumentNullException(nameof(binaryCodec));
}
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
+ // LUCENENET specific - added guard clause
+ if (readerContext is null)
+ throw new ArgumentNullException(nameof(readerContext));
+
BinaryDocValues docValues = readerContext.AtomicReader.GetBinaryDocValues(fieldName);
return new FuctionValuesAnonymousClass(this, docValues);
@@ -250,8 +268,9 @@ namespace Lucene.Net.Spatial.Serialized
public FuctionValuesAnonymousClass(ShapeDocValueSource outerInstance, BinaryDocValues docValues)
{
- this.outerInstance = outerInstance;
- this.docValues = docValues;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ this.docValues = docValues ?? throw new ArgumentNullException(nameof(docValues));
}
private int bytesRefDoc = -1;
@@ -274,6 +293,10 @@ namespace Lucene.Net.Spatial.Serialized
public override bool BytesVal(int doc, BytesRef target)
{
+ // LUCENENET specific - added guard clause
+ if (target is null)
+ throw new ArgumentNullException(nameof(target));
+
if (FillBytes(doc))
{
target.Bytes = bytesRef.Bytes;
@@ -288,7 +311,7 @@ namespace Lucene.Net.Spatial.Serialized
}
}
- public override object ObjectVal(int docId)
+ public override object? ObjectVal(int docId)
{
if (!FillBytes(docId))
return null;
@@ -315,7 +338,7 @@ namespace Lucene.Net.Spatial.Serialized
}
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
diff --git a/src/Lucene.Net.Spatial/SpatialStrategy.cs b/src/Lucene.Net.Spatial/SpatialStrategy.cs
index f0f6e38..fe3783c 100644
--- a/src/Lucene.Net.Spatial/SpatialStrategy.cs
+++ b/src/Lucene.Net.Spatial/SpatialStrategy.cs
@@ -3,8 +3,8 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Queries.Function.ValueSources;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial
@@ -46,7 +46,7 @@ namespace Lucene.Net.Spatial
/// immaterial to indexing and search.
/// <para/>
/// Thread-safe.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public abstract class SpatialStrategy
@@ -57,6 +57,7 @@ namespace Lucene.Net.Spatial
/// <summary>
/// Constructs the spatial strategy with its mandatory arguments.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="ctx"/> or <paramref name="fieldName"/> is <c>null</c> or <paramref name="fieldName"/> is empty.</exception>
protected SpatialStrategy(SpatialContext ctx, string fieldName)
{
this.m_ctx = ctx ?? throw new ArgumentNullException(nameof(ctx), "ctx is required");// LUCENENET specific - changed from IllegalArgumentException to ArgumentNullException (.NET convention)
@@ -116,7 +117,7 @@ namespace Lucene.Net.Spatial
/// <code>return new ConstantScoreQuery(MakeFilter(args));</code>
/// </summary>
/// <exception cref="NotSupportedException">If the strategy does not support the shape in <paramref name="args"/>.</exception>
- /// <exception cref="UnsupportedSpatialOperation">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
+ /// <exception cref="UnsupportedSpatialOperationException">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
public virtual ConstantScoreQuery MakeQuery(SpatialArgs args)
{
return new ConstantScoreQuery(MakeFilter(args));
@@ -132,7 +133,7 @@ namespace Lucene.Net.Spatial
/// <code>return new QueryWrapperFilter(MakeQuery(args).Query);</code>
/// </summary>
/// <exception cref="NotSupportedException">If the strategy does not support the shape in <paramref name="args"/>.</exception>
- /// <exception cref="UnsupportedSpatialOperation">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
+ /// <exception cref="UnsupportedSpatialOperationException">If the strategy does not support the <see cref="SpatialOperation"/> in <paramref name="args"/>.</exception>
public abstract Filter MakeFilter(SpatialArgs args);
/// <summary>
@@ -145,8 +146,12 @@ namespace Lucene.Net.Spatial
/// </summary>
public ValueSource MakeRecipDistanceValueSource(IShape queryShape)
{
+ // LUCENENET specific - added guard clause
+ if (queryShape is null)
+ throw new ArgumentNullException(nameof(queryShape));
+
IRectangle bbox = queryShape.BoundingBox;
- double diagonalDist = m_ctx.DistCalc.Distance(
+ double diagonalDist = m_ctx.DistanceCalculator.Distance(
m_ctx.MakePoint(bbox.MinX, bbox.MinY), bbox.MaxX, bbox.MaxY);
double distToEdge = diagonalDist * 0.5;
float c = (float)distToEdge * 0.1f; //one tenth
diff --git a/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs b/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
index 015db2f..db3a0fa 100644
--- a/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
@@ -1,5 +1,6 @@
using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
+using System;
using System.Collections;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -24,8 +25,9 @@ namespace Lucene.Net.Spatial.Util
*/
/// <summary>
- /// Caches the doubleVal of another value source in a HashMap
+ /// Caches the doubleVal of another value source in a <see cref="Dictionary{TKey, TValue}"/>
/// so that it is computed only once.
+ /// <para/>
/// @lucene.internal
/// </summary>
public class CachingDoubleValueSource : ValueSource
@@ -35,7 +37,8 @@ namespace Lucene.Net.Spatial.Util
public CachingDoubleValueSource(ValueSource source)
{
- this.m_source = source;
+ // LUCENENET specific - added guard clause
+ this.m_source = source ?? throw new ArgumentNullException(nameof(source));
m_cache = new JCG.Dictionary<int, double>();
}
@@ -46,6 +49,10 @@ namespace Lucene.Net.Spatial.Util
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
+ // LUCENENET specific - added guard clause
+ if (readerContext is null)
+ throw new ArgumentNullException(nameof(readerContext));
+
int @base = readerContext.DocBase;
FunctionValues vals = m_source.GetValues(context, readerContext);
return new CachingDoubleFunctionValue(@base, vals, m_cache);
@@ -61,9 +68,10 @@ namespace Lucene.Net.Spatial.Util
public CachingDoubleFunctionValue(int docBase, FunctionValues vals, IDictionary<int, double> cache)
{
+ // LUCENENET specific - added guard clauses
this.docBase = docBase;
- values = vals;
- this.cache = cache;
+ values = vals ?? throw new ArgumentNullException(nameof(vals));
+ this.cache = cache ?? throw new ArgumentNullException(nameof(cache));
}
public override double DoubleVal(int doc)
@@ -93,12 +101,10 @@ namespace Lucene.Net.Spatial.Util
#endregion
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
-
-
- if (!(o is CachingDoubleValueSource that)) return false;
+ if (o is null || !(o is CachingDoubleValueSource that)) return false;
if (m_source != null ? !m_source.Equals(that.m_source) : that.m_source != null) return false;
return true;
diff --git a/src/Lucene.Net.Spatial/Util/DistanceToShapeValueSource.cs b/src/Lucene.Net.Spatial/Util/DistanceToShapeValueSource.cs
index 53a7d0e..500ef10 100644
--- a/src/Lucene.Net.Spatial/Util/DistanceToShapeValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/DistanceToShapeValueSource.cs
@@ -3,9 +3,10 @@ using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
using Lucene.Net.Queries.Function.DocValues;
using Lucene.Net.Search;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
+using System;
using System.Collections;
namespace Lucene.Net.Spatial.Util
@@ -47,10 +48,14 @@ namespace Lucene.Net.Spatial.Util
public DistanceToShapeValueSource(ValueSource shapeValueSource, IPoint queryPoint,
double multiplier, SpatialContext ctx)
{
- this.shapeValueSource = shapeValueSource;
- this.queryPoint = queryPoint;
+ // LUCENENET specific - added guard clauses
+ this.shapeValueSource = shapeValueSource ?? throw new ArgumentNullException(nameof(shapeValueSource));
+ this.queryPoint = queryPoint ?? throw new ArgumentNullException(nameof(shapeValueSource));
+ if (ctx is null)
+ throw new ArgumentNullException(nameof(ctx));
+
this.multiplier = multiplier;
- this.distCalc = ctx.DistCalc;
+ this.distCalc = ctx.DistanceCalculator;
this.nullValue =
(ctx.IsGeo ? 180 * multiplier : double.MaxValue);
}
@@ -67,6 +72,10 @@ namespace Lucene.Net.Spatial.Util
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
+ // LUCENENET specific - added guard clause
+ if (readerContext is null)
+ throw new ArgumentNullException(nameof(readerContext));
+
FunctionValues shapeValues = shapeValueSource.GetValues(context, readerContext);
return new DoubleDocValuesAnonymousClass(this, shapeValues);
@@ -80,8 +89,9 @@ namespace Lucene.Net.Spatial.Util
public DoubleDocValuesAnonymousClass(DistanceToShapeValueSource outerInstance, FunctionValues shapeValues)
: base(outerInstance)
{
- this.outerInstance = outerInstance;
- this.shapeValues = shapeValues;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ this.shapeValues = shapeValues ?? throw new ArgumentNullException(nameof(shapeValues));
}
public override double DoubleVal(int doc)
@@ -101,7 +111,7 @@ namespace Lucene.Net.Spatial.Util
}
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
index 076ac03..2dd173e 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
@@ -1,4 +1,5 @@
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -38,12 +39,22 @@ namespace Lucene.Net.Spatial.Util
public ShapeFieldCache(int length, int defaultLength)
{
+ // LUCENENET specific - added guard clause
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), $"{nameof(length)} must be greater than or equal to 0.");
+
cache = new IList<T>[length];
this.DefaultLength = defaultLength;
}
public virtual void Add(int docid, T s)
{
+ // LUCENENET specific - added guard clauses
+ if (s is null)
+ throw new ArgumentNullException(nameof(s));
+ if (docid < 0 || docid >= cache.Length)
+ throw new ArgumentOutOfRangeException(nameof(docid), $"{nameof(docid)} must be positive and less than {Math.Max(cache.Length - 1, 0)}.");
+
IList<T> list = cache[docid];
if (list is null)
{
@@ -54,6 +65,10 @@ namespace Lucene.Net.Spatial.Util
public virtual IList<T> GetShapes(int docid)
{
+ // LUCENENET specific - added guard clause
+ if (docid < 0 || docid >= cache.Length)
+ throw new ArgumentOutOfRangeException(nameof(docid), $"{nameof(docid)} must be positive and less than {Math.Max(cache.Length - 1, 0)}.");
+
return cache[docid];
}
}
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
index d334c23..bfed357 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
@@ -1,8 +1,8 @@
using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
using System;
using System.Collections;
@@ -43,9 +43,10 @@ namespace Lucene.Net.Spatial.Util
public ShapeFieldCacheDistanceValueSource(SpatialContext ctx,
ShapeFieldCacheProvider<IPoint> provider, IPoint from, double multiplier)
{
- this.ctx = ctx;
- this.from = from;
- this.provider = provider;
+ // LUCENENET specific - added guard clauses
+ this.ctx = ctx ?? throw new ArgumentNullException(nameof(ctx));
+ this.from = from ?? throw new ArgumentNullException(nameof(from));
+ this.provider = provider ?? throw new ArgumentNullException(nameof(provider));
this.multiplier = multiplier;
}
@@ -56,25 +57,31 @@ namespace Lucene.Net.Spatial.Util
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
- return new CachedDistanceFunctionValue(readerContext.AtomicReader, this);
+ // LUCENENET specific - added guard clause
+ if (readerContext is null)
+ throw new ArgumentNullException(nameof(readerContext));
+
+ return new CachedDistanceFunctionValue(this, readerContext.AtomicReader);
}
internal class CachedDistanceFunctionValue : FunctionValues
{
- private readonly ShapeFieldCacheDistanceValueSource enclosingInstance;
+ private readonly ShapeFieldCacheDistanceValueSource outerInstance;
private readonly ShapeFieldCache<IPoint> cache;
private readonly IPoint from;
private readonly IDistanceCalculator calculator;
private readonly double nullValue;
- public CachedDistanceFunctionValue(AtomicReader reader, ShapeFieldCacheDistanceValueSource enclosingInstance)
+ public CachedDistanceFunctionValue(ShapeFieldCacheDistanceValueSource outerInstance, AtomicReader reader)
{
- cache = enclosingInstance.provider.GetCache(reader);
- this.enclosingInstance = enclosingInstance;
-
- from = enclosingInstance.from;
- calculator = enclosingInstance.ctx.DistCalc;
- nullValue = (enclosingInstance.ctx.IsGeo ? 180 * enclosingInstance.multiplier : double.MaxValue);
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ if (reader is null)
+ throw new ArgumentNullException(nameof(reader));
+ cache = outerInstance.provider.GetCache(reader);
+ from = outerInstance.from;
+ calculator = outerInstance.ctx.DistanceCalculator;
+ nullValue = (outerInstance.ctx.IsGeo ? 180 * outerInstance.multiplier : double.MaxValue);
}
/// <summary>
@@ -95,23 +102,22 @@ namespace Lucene.Net.Spatial.Util
{
v = Math.Min(v, calculator.Distance(from, vals[i]));
}
- return v * enclosingInstance.multiplier;
+ return v * outerInstance.multiplier;
}
return nullValue;
}
public override string ToString(int doc)
{
- return enclosingInstance.GetDescription() + "=" + SingleVal(doc);
+ return outerInstance.GetDescription() + "=" + SingleVal(doc);
}
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
-
if (!(o is ShapeFieldCacheDistanceValueSource that)) return false;
if (!ctx.Equals(that.ctx)) return false;
if (!from.Equals(that.from)) return false;
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
index 117b809..31a4b92 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
@@ -1,8 +1,9 @@
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.Util;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Lucene.Net.Spatial.Util
@@ -25,16 +26,15 @@ namespace Lucene.Net.Spatial.Util
*/
/// <summary>
- /// Provides access to a
- /// <see cref="ShapeFieldCache{T}">ShapeFieldCache<T></see>
- /// for a given
- /// <see cref="Lucene.Net.Index.AtomicReader">Lucene.Net.Index.AtomicReader</see>.
- ///
- /// If a Cache does not exist for the TextReader, then it is built by iterating over
+ /// Provides access to a <see cref="ShapeFieldCache{T}" />
+ /// for a given <see cref="AtomicReader" />.
+ /// <para/>
+ /// If a Cache does not exist for the Reader, then it is built by iterating over
/// the all terms for a given field, reconstructing the Shape from them, and adding
/// them to the Cache.
- /// </summary>
+ /// <para/>
/// @lucene.internal
+ /// </summary>
public abstract class ShapeFieldCacheProvider<T>
where T : IShape
{
@@ -45,17 +45,18 @@ namespace Lucene.Net.Spatial.Util
private readonly ConditionalWeakTable<IndexReader, Lazy<ShapeFieldCache<T>>> sidx =
new ConditionalWeakTable<IndexReader, Lazy<ShapeFieldCache<T>>>();
- protected internal readonly int m_defaultSize;
- protected internal readonly string m_shapeField;
+ protected readonly int m_defaultSize;
+ protected readonly string m_shapeField;
protected ShapeFieldCacheProvider(string shapeField, int defaultSize) // LUCENENET: CA1012: Abstract types should not have constructors (marked protected)
{
// it may be a List<T> or T
- this.m_shapeField = shapeField;
+ this.m_shapeField = shapeField ?? throw new ArgumentNullException(nameof(shapeField)); // LUCENENET specific - added guard clause
this.m_defaultSize = defaultSize;
}
- protected internal abstract T ReadShape(BytesRef term);
+ [return: MaybeNull]
+ protected abstract T ReadShape(BytesRef term);
public virtual ShapeFieldCache<T> GetCache(AtomicReader reader)
{
@@ -67,15 +68,15 @@ namespace Lucene.Net.Spatial.Util
log.Fine("Building Cache [" + reader.MaxDoc() + "]");*/
ShapeFieldCache<T> idx = new ShapeFieldCache<T>(key.MaxDoc, m_defaultSize);
int count = 0;
- DocsEnum docs = null;
+ DocsEnum? docs = null;
Terms terms = ((AtomicReader)key).GetTerms(m_shapeField);
- TermsEnum te = null;
+ TermsEnum? te = null;
if (terms != null)
{
te = terms.GetEnumerator(te);
while (te.MoveNext())
{
- T shape = ReadShape(te.Term);
+ T? shape = ReadShape(te.Term);
if (shape != null)
{
docs = te.Docs(null, docs, DocsFlags.NONE);
diff --git a/src/Lucene.Net.Spatial/Util/ShapePredicateValueSource.cs b/src/Lucene.Net.Spatial/Util/ShapePredicateValueSource.cs
index 383a4a6..c2cb55b 100644
--- a/src/Lucene.Net.Spatial/Util/ShapePredicateValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapePredicateValueSource.cs
@@ -3,7 +3,8 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Queries.Function.DocValues;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Shapes;
+using System;
using System.Collections;
namespace Lucene.Net.Spatial.Util
@@ -26,48 +27,49 @@ namespace Lucene.Net.Spatial.Util
*/
/// <summary>
- /// A boolean <see cref="ValueSource"/> that compares a shape from a provided <see cref="ValueSource"/> with a given <see cref="IShape">Shape</see> and sees
- /// if it matches a given <see cref="SpatialOperation"/> (the predicate).
- ///
+ /// A boolean <see cref="ValueSource" /> that compares a shape from a provided <see cref="ValueSource" /> with a given <see cref="IShape" /> and sees
+ /// if it matches a given <see cref="SpatialOperation" /> (the predicate).
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class ShapePredicateValueSource : ValueSource
{
- private readonly ValueSource shapeValuesource;//the left hand side
+ private readonly ValueSource shapeValueSource;//the left hand side
private readonly SpatialOperation op;
private readonly IShape queryShape;//the right hand side (constant)
/// <summary>
///
/// </summary>
- /// <param name="shapeValuesource">
+ /// <param name="shapeValueSource">
/// Must yield <see cref="IShape"/> instances from it's ObjectVal(doc). If null
/// then the result is false. This is the left-hand (indexed) side.
/// </param>
/// <param name="op">the predicate</param>
/// <param name="queryShape">The shape on the right-hand (query) side.</param>
- public ShapePredicateValueSource(ValueSource shapeValuesource, SpatialOperation op, IShape queryShape)
+ public ShapePredicateValueSource(ValueSource shapeValueSource, SpatialOperation op, IShape queryShape)
{
- this.shapeValuesource = shapeValuesource;
- this.op = op;
- this.queryShape = queryShape;
+ // LUCENENET specific - added guard clauses
+ this.shapeValueSource = shapeValueSource ?? throw new ArgumentNullException(nameof(shapeValueSource));
+ this.op = op ?? throw new ArgumentNullException(nameof(op));
+ this.queryShape = queryShape ?? throw new ArgumentNullException(nameof(queryShape));
}
public override string GetDescription()
{
- return shapeValuesource + " " + op + " " + queryShape;
+ return shapeValueSource + " " + op + " " + queryShape;
}
public override void CreateWeight(IDictionary context, IndexSearcher searcher)
{
- shapeValuesource.CreateWeight(context, searcher);
+ shapeValueSource.CreateWeight(context, searcher);
}
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
- FunctionValues shapeValues = shapeValuesource.GetValues(context, readerContext);
+ FunctionValues shapeValues = shapeValueSource.GetValues(context, readerContext);
return new BoolDocValuesAnonymousClass(this, shapeValues);
}
@@ -80,8 +82,9 @@ namespace Lucene.Net.Spatial.Util
public BoolDocValuesAnonymousClass(ShapePredicateValueSource outerInstance, FunctionValues shapeValues)
: base(outerInstance)
{
- this.outerInstance = outerInstance;
- this.shapeValues = shapeValues;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ this.shapeValues = shapeValues ?? throw new ArgumentNullException(nameof(shapeValues));
}
public override bool BoolVal(int doc)
@@ -100,14 +103,14 @@ namespace Lucene.Net.Spatial.Util
}
}
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
ShapePredicateValueSource that = (ShapePredicateValueSource)o;
- if (!shapeValuesource.Equals(that.shapeValuesource)) return false;
+ if (!shapeValueSource.Equals(that.shapeValueSource)) return false;
if (!op.Equals(that.op)) return false;
if (!queryShape.Equals(that.queryShape)) return false;
@@ -116,7 +119,7 @@ namespace Lucene.Net.Spatial.Util
public override int GetHashCode()
{
- int result = shapeValuesource.GetHashCode();
+ int result = shapeValueSource.GetHashCode();
result = 31 * result + op.GetHashCode();
result = 31 * result + queryShape.GetHashCode();
return result;
diff --git a/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs b/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
index c3c3bb7..8f6caf2 100644
--- a/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
+++ b/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
@@ -25,7 +25,8 @@ namespace Lucene.Net.Spatial.Util
/// <summary>
/// <see cref="Filter"/> that matches all documents where a <see cref="ValueSource"/> is
- /// in between a range of <c>min</c> and <c>max</c> inclusive.
+ /// in between a range of <see cref="Min"/> and <see cref="Max"/> inclusive.
+ /// <para/>
/// @lucene.internal
/// </summary>
public class ValueSourceFilter : Filter
@@ -45,12 +46,12 @@ namespace Lucene.Net.Spatial.Util
// LUCENENET specific - changed from IllegalArgumentException to ArgumentNullException (.NET convention)
this.startingFilter = startingFilter ?? throw new ArgumentNullException(nameof(startingFilter),
"Please provide a non-null startingFilter; you can use QueryWrapperFilter(MatchAllDocsQuery) as a no-op filter");
- this.source = source;
+ this.source = source ?? throw new ArgumentNullException(nameof(source)); // LUCENENET specific - added guard clause
this.min = min;
this.max = max;
}
- public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
+ public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits? acceptDocs)
{
var values = source.GetValues(null, context);
return new ValueSourceFilteredDocIdSet(this, startingFilter.GetDocIdSet(context, acceptDocs), values);
@@ -61,11 +62,12 @@ namespace Lucene.Net.Spatial.Util
private readonly ValueSourceFilter outerInstance;
private readonly FunctionValues values;
- public ValueSourceFilteredDocIdSet(ValueSourceFilter outerInstance, DocIdSet innerSet, FunctionValues values)
+ public ValueSourceFilteredDocIdSet(ValueSourceFilter outerInstance, DocIdSet? innerSet, FunctionValues values)
: base(innerSet)
{
- this.outerInstance = outerInstance;
- this.values = values;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ this.values = values ?? throw new ArgumentNullException(nameof(values));
}
protected override bool Match(int doc)
diff --git a/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs b/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
index 7d69c10..cdd96f9 100644
--- a/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
+++ b/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
@@ -3,10 +3,10 @@ using Lucene.Net.Index;
using Lucene.Net.Queries.Function;
using Lucene.Net.Search;
using Lucene.Net.Util;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
+using System;
using System.Collections;
-using System.Diagnostics;
namespace Lucene.Net.Spatial.Vector
{
@@ -30,7 +30,7 @@ namespace Lucene.Net.Spatial.Vector
/// <summary>
/// An implementation of the Lucene <see cref="ValueSource"/> model that returns the distance
/// for a <see cref="PointVectorStrategy"/>.
- ///
+ /// <para/>
/// @lucene.internal
/// </summary>
public class DistanceValueSource : ValueSource
@@ -42,10 +42,12 @@ namespace Lucene.Net.Spatial.Vector
/// <summary>
/// Constructor.
/// </summary>
+ /// <exception cref="ArgumentNullException"><paramref name="strategy"/> or <paramref name="from"/> is <c>null</c>.</exception>
public DistanceValueSource(PointVectorStrategy strategy, IPoint from, double multiplier)
{
- this.strategy = strategy;
- this.from = from;
+ // LUCENENET specific - added guard clauses
+ this.strategy = strategy ?? throw new ArgumentNullException(nameof(strategy));
+ this.from = from ?? throw new ArgumentNullException(nameof(from));
this.multiplier = multiplier;
}
@@ -62,6 +64,10 @@ namespace Lucene.Net.Spatial.Vector
/// </summary>
public override FunctionValues GetValues(IDictionary context, AtomicReaderContext readerContext)
{
+ // LUCENENET specific - added guard clause
+ if (readerContext is null)
+ throw new ArgumentNullException(nameof(readerContext));
+
return new DistanceFunctionValue(this, readerContext.AtomicReader);
}
@@ -79,7 +85,10 @@ namespace Lucene.Net.Spatial.Vector
public DistanceFunctionValue(DistanceValueSource outerInstance, AtomicReader reader)
{
- this.outerInstance = outerInstance;
+ // LUCENENET specific - added guard clauses
+ this.outerInstance = outerInstance ?? throw new ArgumentNullException(nameof(outerInstance));
+ if (reader is null)
+ throw new ArgumentNullException(nameof(reader));
ptX = FieldCache.DEFAULT.GetDoubles(reader, outerInstance.strategy.FieldNameX, true);
ptY = FieldCache.DEFAULT.GetDoubles(reader, outerInstance.strategy.FieldNameY, true);
@@ -87,7 +96,7 @@ namespace Lucene.Net.Spatial.Vector
validY = FieldCache.DEFAULT.GetDocsWithField(reader, outerInstance.strategy.FieldNameY);
//from = outerInstance.from; // LUCENENET: Never read
- calculator = outerInstance.strategy.SpatialContext.DistCalc;
+ calculator = outerInstance.strategy.SpatialContext.DistanceCalculator;
nullValue = (outerInstance.strategy.SpatialContext.IsGeo ? 180 * outerInstance.multiplier : double.MaxValue);
}
@@ -118,7 +127,7 @@ namespace Lucene.Net.Spatial.Vector
#endregion
- public override bool Equals(object o)
+ public override bool Equals(object? o)
{
if (this == o) return true;
if (o is null || GetType() != o.GetType()) return false;
diff --git a/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs b/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
index 02bc60a..8a72100 100644
--- a/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
+++ b/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
@@ -3,8 +3,8 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Spatial.Util;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial.Vector
@@ -48,13 +48,13 @@ namespace Lucene.Net.Spatial.Vector
/// both a search using a Circle and sort will result in calculations for the
/// spatial distance being done twice -- once for the filter and second for the
/// sort.
- ///
+ /// <para/>
/// @lucene.experimental
/// </summary>
public class PointVectorStrategy : SpatialStrategy
{
- public static string SUFFIX_X = "__x";
- public static string SUFFIX_Y = "__y";
+ public const string SUFFIX_X = "__x";
+ public const string SUFFIX_Y = "__y";
private readonly string fieldNameX;
private readonly string fieldNameY;
@@ -85,6 +85,10 @@ namespace Lucene.Net.Spatial.Vector
public override Field[] CreateIndexableFields(IShape shape)
{
+ // LUCENENET specific - added guard clause
+ if (shape is null)
+ throw new ArgumentNullException(nameof(shape));
+
if (shape is IPoint point)
return CreateIndexableFields(point);
@@ -96,6 +100,10 @@ namespace Lucene.Net.Spatial.Vector
/// </summary>
public virtual Field[] CreateIndexableFields(IPoint point)
{
+ // LUCENENET specific - added guard clause
+ if (point is null)
+ throw new ArgumentNullException(nameof(point));
+
FieldType doubleFieldType = new FieldType(DoubleField.TYPE_NOT_STORED)
{
NumericPrecisionStep = precisionStep
@@ -115,6 +123,10 @@ namespace Lucene.Net.Spatial.Vector
public override Filter MakeFilter(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
//unwrap the CSQ from makeQuery
ConstantScoreQuery csq = MakeQuery(args);
Filter filter = csq.Filter;
@@ -126,11 +138,15 @@ namespace Lucene.Net.Spatial.Vector
public override ConstantScoreQuery MakeQuery(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
if (!SpatialOperation.Is(args.Operation,
SpatialOperation.Intersects,
SpatialOperation.IsWithin))
{
- throw new UnsupportedSpatialOperation(args.Operation);
+ throw new UnsupportedSpatialOperationException(args.Operation);
}
IShape shape = args.Shape;
@@ -157,6 +173,10 @@ namespace Lucene.Net.Spatial.Vector
//TODO this is basically old code that hasn't been verified well and should probably be removed
public virtual Query MakeQueryDistanceScore(SpatialArgs args)
{
+ // LUCENENET specific - added guard clause
+ if (args is null)
+ throw new ArgumentNullException(nameof(args));
+
// For starters, just limit the bbox
var shape = args.Shape;
if (!(shape is IRectangle || shape is ICircle))
@@ -169,9 +189,9 @@ namespace Lucene.Net.Spatial.Vector
throw UnsupportedOperationException.Create("Crossing dateline not yet supported");
}
- ValueSource valueSource = null;
+ ValueSource? valueSource = null;
- Query spatial = null;
+ Query? spatial = null;
SpatialOperation op = args.Operation;
if (SpatialOperation.Is(op,
@@ -203,7 +223,7 @@ namespace Lucene.Net.Spatial.Vector
if (spatial is null)
{
- throw new UnsupportedSpatialOperation(args.Operation);
+ throw new UnsupportedSpatialOperationException(args.Operation);
}
if (valueSource != null)
@@ -227,6 +247,10 @@ namespace Lucene.Net.Spatial.Vector
/// </summary>
private Query MakeWithin(IRectangle bbox)
{
+ // LUCENENET specific - added guard clause
+ if (bbox is null)
+ throw new ArgumentNullException(nameof(bbox));
+
var bq = new BooleanQuery();
const Occur MUST = Occur.MUST;
if (bbox.CrossesDateLine)
@@ -260,6 +284,10 @@ namespace Lucene.Net.Spatial.Vector
/// </summary>
private Query MakeDisjoint(IRectangle bbox)
{
+ // LUCENENET specific - added guard clause
+ if (bbox is null)
+ throw new ArgumentNullException(nameof(bbox));
+
if (bbox.CrossesDateLine)
throw UnsupportedOperationException.Create("MakeDisjoint doesn't handle dateline cross");
Query qX = RangeQuery(fieldNameX, bbox.MinX, bbox.MaxX);
diff --git a/src/Lucene.Net.Tests.AllProjects/Support/ExceptionHandling/ExceptionScanningTestCase.cs b/src/Lucene.Net.Tests.AllProjects/Support/ExceptionHandling/ExceptionScanningTestCase.cs
index d352559..9c51aae 100644
--- a/src/Lucene.Net.Tests.AllProjects/Support/ExceptionHandling/ExceptionScanningTestCase.cs
+++ b/src/Lucene.Net.Tests.AllProjects/Support/ExceptionHandling/ExceptionScanningTestCase.cs
@@ -318,7 +318,7 @@ namespace Lucene.Net.Support.ExceptionHandling
typeof(J2N.IO.BufferUnderflowException),
typeof(J2N.IO.BufferOverflowException),
typeof(J2N.IO.InvalidMarkException),
- typeof(Lucene.Net.Spatial.Queries.UnsupportedSpatialOperation), // Subclasses NotSupportedException
+ typeof(Lucene.Net.Spatial.Queries.UnsupportedSpatialOperationException), // Subclasses NotSupportedException
//typeof(NUnit.Framework.Internal.InvalidPlatformException),
diff --git a/src/Lucene.Net.Tests.Spatial/DistanceStrategyTest.cs b/src/Lucene.Net.Tests.Spatial/DistanceStrategyTest.cs
index 0427f38..9da233f 100644
--- a/src/Lucene.Net.Tests.Spatial/DistanceStrategyTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/DistanceStrategyTest.cs
@@ -5,8 +5,8 @@ using Lucene.Net.Spatial.Vector;
using Lucene.Net.Support;
using NUnit.Framework;
using RandomizedTesting.Generators;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -37,7 +37,7 @@ namespace Lucene.Net.Spatial
{
IList<Object[]> ctorArgs = new JCG.List<object[]>();
- SpatialContext ctx = SpatialContext.GEO;
+ SpatialContext ctx = SpatialContext.Geo;
SpatialPrefixTree grid;
SpatialStrategy strategy;
@@ -126,7 +126,7 @@ namespace Lucene.Net.Spatial
DeleteDoc("999");
Commit();
- double dist = ctx.DistCalc.Distance(p100, p101);
+ double dist = ctx.DistanceCalculator.Distance(p100, p101);
IShape queryShape = ctx.MakeCircle(2.01, 0.99, dist);
CheckValueSource(strategy.MakeRecipDistanceValueSource(queryShape),
new float[] { 1.00f, 0.10f, 0f }, 0.09f);
diff --git a/src/Lucene.Net.Tests.Spatial/Lucene.Net.Tests.Spatial.csproj b/src/Lucene.Net.Tests.Spatial/Lucene.Net.Tests.Spatial.csproj
index adc1701..e4dd17c 100644
--- a/src/Lucene.Net.Tests.Spatial/Lucene.Net.Tests.Spatial.csproj
+++ b/src/Lucene.Net.Tests.Spatial/Lucene.Net.Tests.Spatial.csproj
@@ -55,8 +55,7 @@
<Import Project="$(SolutionDir).build/TestReferences.Common.targets" />
<ItemGroup>
- <PackageReference Include="Spatial4n.Core" Version="$(Spatial4nCorePackageVersion)" />
- <PackageReference Include="Spatial4n.Core.NTS" Version="$(Spatial4nCoreNTSPackageVersion)" />
+ <PackageReference Include="Spatial4n" Version="$(Spatial4nPackageVersion)" />
</ItemGroup>
</Project>
diff --git a/src/Lucene.Net.Tests.Spatial/PortedSolr3Test.cs b/src/Lucene.Net.Tests.Spatial/PortedSolr3Test.cs
index 5706bc5..d2c847f 100644
--- a/src/Lucene.Net.Tests.Spatial/PortedSolr3Test.cs
+++ b/src/Lucene.Net.Tests.Spatial/PortedSolr3Test.cs
@@ -5,9 +5,9 @@ using Lucene.Net.Spatial.Queries;
using Lucene.Net.Spatial.Vector;
using NUnit.Framework;
using RandomizedTesting.Generators;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -42,7 +42,7 @@ namespace Lucene.Net.Spatial
{
IList<Object[]> ctorArgs = new JCG.List<object[]>();
- SpatialContext ctx = SpatialContext.GEO;
+ SpatialContext ctx = SpatialContext.Geo;
SpatialPrefixTree grid;
SpatialStrategy strategy;
@@ -167,7 +167,7 @@ namespace Lucene.Net.Spatial
private void _CheckHits(bool bbox, IPoint pt, double distKM, int assertNumFound, params int[] assertIds)
{
SpatialOperation op = SpatialOperation.Intersects;
- double distDEG = DistanceUtils.Dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+ double distDEG = DistanceUtils.Dist2Degrees(distKM, DistanceUtils.EarthMeanRadiusKilometers);
IShape shape = ctx.MakeCircle(pt, distDEG);
if (bbox)
shape = shape.BoundingBox;
diff --git a/src/Lucene.Net.Tests.Spatial/Prefix/NtsPolygonTest.cs b/src/Lucene.Net.Tests.Spatial/Prefix/NtsPolygonTest.cs
index 63c39c0..884d4c2 100644
--- a/src/Lucene.Net.Tests.Spatial/Prefix/NtsPolygonTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/Prefix/NtsPolygonTest.cs
@@ -4,8 +4,9 @@ using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Support;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Context.Nts;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using Console = Lucene.Net.Util.SystemConsole;
@@ -37,14 +38,15 @@ namespace Lucene.Net.Spatial.Prefix
{
try
{
- IDictionary<string, string> args = new Dictionary<string, string>();
- args.Put("spatialContextFactory",
- typeof(Spatial4n.Core.Context.Nts.NtsSpatialContextFactory).AssemblyQualifiedName);
- ctx = SpatialContextFactory.MakeSpatialContext(args /*, getClass().getClassLoader()*/);
+ IDictionary<string, string> args = new Dictionary<string, string>
+ {
+ ["SpatialContextFactory"] = typeof(NtsSpatialContextFactory).FullName
+ };
+ ctx = SpatialContextFactory.MakeSpatialContext(args, GetType().Assembly);
}
catch (Exception e) when (e.IsNoClassDefFoundError())
{
- AssumeTrue("This test requires Spatial4n.Core.NTS: " + e, false);
+ AssumeTrue("This test requires Spatial4n: " + e, false);
}
GeohashPrefixTree grid = new GeohashPrefixTree(ctx, 11);//< 1 meter == 11 maxLevels
diff --git a/src/Lucene.Net.Tests.Spatial/Prefix/SpatialOpRecursivePrefixTreeTest.cs b/src/Lucene.Net.Tests.Spatial/Prefix/SpatialOpRecursivePrefixTreeTest.cs
index 84afa25..926b274 100644
--- a/src/Lucene.Net.Tests.Spatial/Prefix/SpatialOpRecursivePrefixTreeTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/Prefix/SpatialOpRecursivePrefixTreeTest.cs
@@ -4,9 +4,8 @@ using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Support;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
-using Spatial4n.Core.Shapes.Impl;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -63,20 +62,24 @@ namespace Lucene.Net.Spatial.Prefix
if (!ctx.IsGeo)
ctx2D = ctx;
//A non-geo version of ctx.
- FakeSpatialContextFactory ctxFactory = new FakeSpatialContextFactory();
- ctxFactory.geo = false;
- ctxFactory.worldBounds = ctx.WorldBounds;
- ctx2D = ctxFactory.NewSpatialContext();
+ SpatialContextFactory ctxFactory = new SpatialContextFactory
+ {
+ IsGeo = false,
+ WorldBounds = ctx.WorldBounds
+ };
+ ctx2D = ctxFactory.CreateSpatialContext();
}
private void SetupQuadGrid(int maxLevels)
{
//non-geospatial makes this test a little easier (in gridSnap), and using boundary values 2^X raises
// the prospect of edge conditions we want to test, plus makes for simpler numbers (no decimals).
- FakeSpatialContextFactory factory = new FakeSpatialContextFactory();
- factory.geo = false;
- factory.worldBounds = new Rectangle(0, 256, -128, 128, null);
- this.ctx = factory.NewSpatialContext();
+ SpatialContextFactory factory = new SpatialContextFactory
+ {
+ IsGeo = false,
+ WorldBounds = new Rectangle(0, 256, -128, 128, null)
+ };
+ this.ctx = factory.CreateSpatialContext();
//A fairly shallow grid, and default 2.5% distErrPct
if (maxLevels == -1)
maxLevels = randomIntBetween(1, 8);//max 64k cells (4^8), also 256*256
@@ -84,22 +87,9 @@ namespace Lucene.Net.Spatial.Prefix
this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
}
- /// <summary>
- /// LUCENENET specific class used to gain access to protected internal
- /// member NewSpatialContext(), since we are not strong-named and
- /// InternalsVisibleTo is not an option from a strong-named class.
- /// </summary>
- private class FakeSpatialContextFactory : SpatialContextFactory
- {
- new public SpatialContext NewSpatialContext()
- {
- return base.NewSpatialContext();
- }
- }
-
public virtual void SetupGeohashGrid(int maxLevels)
{
- this.ctx = SpatialContext.GEO;
+ this.ctx = SpatialContext.Geo;
//A fairly shallow grid, and default 2.5% distErrPct
if (maxLevels == -1)
maxLevels = randomIntBetween(1, 3);//max 16k cells (32^3)
@@ -190,12 +180,12 @@ namespace Lucene.Net.Spatial.Prefix
[Test]
public void TestShapePair()
{
- ctx = SpatialContext.GEO;
+ ctx = SpatialContext.Geo;
SetupCtx2D(ctx);
IShape leftShape = new ShapePair(ctx.MakeRectangle(-74, -56, -8, 1), ctx.MakeRectangle(-180, 134, -90, 90), true, ctx, ctx2D);
IShape queryShape = ctx.MakeRectangle(-180, 180, -90, 90);
- assertEquals(SpatialRelation.WITHIN, leftShape.Relate(queryShape));
+ assertEquals(SpatialRelation.Within, leftShape.Relate(queryShape));
}
//Override so we can index parts of a pair separately, resulting in the detailLevel
@@ -500,11 +490,11 @@ namespace Lucene.Net.Spatial.Prefix
public override SpatialRelation Relate(IShape other)
{
SpatialRelation r = RelateApprox(other);
- if (r == SpatialRelation.DISJOINT)
+ if (r == SpatialRelation.Disjoint)
return r;
- if (r == SpatialRelation.CONTAINS)
+ if (r == SpatialRelation.Contains)
return r;
- if (r == SpatialRelation.WITHIN && !biasContainsThenWithin)
+ if (r == SpatialRelation.Within && !biasContainsThenWithin)
return r;
//See if the correct answer is actually Contains, when the indexed shapes are adjacent,
@@ -522,7 +512,7 @@ namespace Lucene.Net.Spatial.Prefix
&& CornerContainsNonGeo(oRect.MinX, oRect.MaxY)
&& CornerContainsNonGeo(oRect.MaxX, oRect.MinY)
&& CornerContainsNonGeo(oRect.MaxX, oRect.MaxY))
- return SpatialRelation.CONTAINS;
+ return SpatialRelation.Contains;
return r;
}
@@ -536,23 +526,23 @@ namespace Lucene.Net.Spatial.Prefix
{
if (biasContainsThenWithin)
{
- if (shape1.Relate(other) == SpatialRelation.CONTAINS || shape1.equals(other)
- || shape2.Relate(other) == SpatialRelation.CONTAINS || shape2.equals(other)) return SpatialRelation.CONTAINS;
+ if (shape1.Relate(other) == SpatialRelation.Contains || shape1.equals(other)
+ || shape2.Relate(other) == SpatialRelation.Contains || shape2.equals(other)) return SpatialRelation.Contains;
- if (shape1.Relate(other) == SpatialRelation.WITHIN && shape2.Relate(other) == SpatialRelation.WITHIN) return SpatialRelation.WITHIN;
+ if (shape1.Relate(other) == SpatialRelation.Within && shape2.Relate(other) == SpatialRelation.Within) return SpatialRelation.Within;
}
else
{
- if ((shape1.Relate(other) == SpatialRelation.WITHIN || shape1.equals(other))
- && (shape2.Relate(other) == SpatialRelation.WITHIN || shape2.equals(other))) return SpatialRelation.WITHIN;
+ if ((shape1.Relate(other) == SpatialRelation.Within || shape1.equals(other))
+ && (shape2.Relate(other) == SpatialRelation.Within || shape2.equals(other))) return SpatialRelation.Within;
- if (shape1.Relate(other) == SpatialRelation.CONTAINS || shape2.Relate(other) == SpatialRelation.CONTAINS) return SpatialRelation.CONTAINS;
+ if (shape1.Relate(other) == SpatialRelation.Contains || shape2.Relate(other) == SpatialRelation.Contains) return SpatialRelation.Contains;
}
if (shape1.Relate(other).Intersects() || shape2.Relate(other).Intersects())
- return SpatialRelation.INTERSECTS;//might actually be 'CONTAINS' if the pair are adjacent but we handle that later
- return SpatialRelation.DISJOINT;
+ return SpatialRelation.Intersects;//might actually be 'CONTAINS' if the pair are adjacent but we handle that later
+ return SpatialRelation.Disjoint;
}
public override String ToString()
diff --git a/src/Lucene.Net.Tests.Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs b/src/Lucene.Net.Tests.Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs
index 2db1688..8e21915 100644
--- a/src/Lucene.Net.Tests.Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs
+++ b/src/Lucene.Net.Tests.Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs
@@ -1,9 +1,9 @@
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
using System.Collections.Generic;
using System.Globalization;
using JCG = J2N.Collections.Generic;
@@ -35,7 +35,7 @@ namespace Lucene.Net.Spatial.Prefix
private void init(int maxLength)
{
this.maxLength = maxLength;
- this.ctx = SpatialContext.GEO;
+ this.ctx = SpatialContext.Geo;
GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
}
@@ -60,7 +60,7 @@ namespace Lucene.Net.Spatial.Prefix
init(GeohashPrefixTree.MaxLevelsPossible);
GeohashPrefixTree grid = (GeohashPrefixTree)((RecursivePrefixTreeStrategy)strategy).Grid;
//DWS: I know this to be true. 11 is needed for one meter
- double degrees = DistanceUtils.Dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+ double degrees = DistanceUtils.Dist2Degrees(0.001, DistanceUtils.EarthMeanRadiusKilometers);
assertEquals(11, grid.GetLevelForDistance(degrees));
}
@@ -69,17 +69,17 @@ namespace Lucene.Net.Spatial.Prefix
{
init(GeohashPrefixTree.MaxLevelsPossible);
- Spatial4n.Core.Shapes.IPoint iPt = ctx.MakePoint(2.8028712999999925, 48.3708044);//lon, lat
+ IPoint iPt = ctx.MakePoint(2.8028712999999925, 48.3708044);//lon, lat
AddDocument(newDoc("iPt", iPt));
Commit();
- Spatial4n.Core.Shapes.IPoint qPt = ctx.MakePoint(2.4632387000000335, 48.6003516);
+ IPoint qPt = ctx.MakePoint(2.4632387000000335, 48.6003516);
- double KM2DEG = DistanceUtils.Dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+ double KM2DEG = DistanceUtils.Dist2Degrees(1, DistanceUtils.EarthMeanRadiusKilometers);
double DEG2KM = 1 / KM2DEG;
double DIST = 35.75;//35.7499...
- assertEquals(DIST, ctx.DistCalc.Distance(iPt, qPt) * DEG2KM, 0.001);
+ assertEquals(DIST, ctx.DistanceCalculator.Distance(iPt, qPt) * DEG2KM, 0.001);
//distErrPct will affect the query shape precision. The indexed precision
// was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
@@ -99,7 +99,7 @@ namespace Lucene.Net.Spatial.Prefix
checkHits(q(qPt, 34 * KM2DEG, distErrPct), 0, null);
}
- private SpatialArgs q(Spatial4n.Core.Shapes.IPoint pt, double distDEG, double distErrPct)
+ private SpatialArgs q(IPoint pt, double distDEG, double distErrPct)
{
IShape shape = ctx.MakeCircle(pt, distDEG);
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape);
diff --git a/src/Lucene.Net.Tests.Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs b/src/Lucene.Net.Tests.Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs
index 38ef37e..b6a74f4 100644
--- a/src/Lucene.Net.Tests.Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs
+++ b/src/Lucene.Net.Tests.Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs
@@ -3,7 +3,8 @@ using Lucene.Net.Index;
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
-using Spatial4n.Core.Context;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
namespace Lucene.Net.Spatial.Prefix
{
@@ -29,10 +30,10 @@ namespace Lucene.Net.Spatial.Prefix
[Test]
public virtual void TestNGramPrefixGridLosAngeles()
{
- SpatialContext ctx = SpatialContext.GEO;
+ SpatialContext ctx = SpatialContext.Geo;
TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");
-
- Spatial4n.Core.Shapes.IShape point = ctx.MakePoint(-118.243680, 34.052230);
+
+ IShape point = ctx.MakePoint(-118.243680, 34.052230);
Document losAngeles = new Document();
losAngeles.Add(new StringField("name", "Los Angeles", Field.Store.YES));
@@ -40,7 +41,7 @@ namespace Lucene.Net.Spatial.Prefix
{
losAngeles.Add(field);
}
- losAngeles.Add(new StoredField(prefixGridStrategy.FieldName, point.toString()));//just for diagnostics
+ losAngeles.Add(new StoredField(prefixGridStrategy.FieldName, point.ToString()));//just for diagnostics
addDocumentsAndCommit(new Document[] { losAngeles });
diff --git a/src/Lucene.Net.Tests.Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs b/src/Lucene.Net.Tests.Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs
index 0d31ac7..870d3a2 100644
--- a/src/Lucene.Net.Tests.Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs
@@ -2,8 +2,8 @@
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using Console = Lucene.Net.Util.SystemConsole;
@@ -35,7 +35,7 @@ namespace Lucene.Net.Spatial.Prefix.Tree
public override void SetUp()
{
base.SetUp();
- ctx = SpatialContext.GEO;
+ ctx = SpatialContext.Geo;
}
[Test]
diff --git a/src/Lucene.Net.Tests.Spatial/Query/SpatialArgsParserTest.cs b/src/Lucene.Net.Tests.Spatial/Query/SpatialArgsParserTest.cs
index 478fffb..0088970 100644
--- a/src/Lucene.Net.Tests.Spatial/Query/SpatialArgsParserTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/Query/SpatialArgsParserTest.cs
@@ -1,7 +1,7 @@
using Lucene.Net.Util;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial.Queries
@@ -25,7 +25,7 @@ namespace Lucene.Net.Spatial.Queries
public class SpatialArgsParserTest : LuceneTestCase
{
- private SpatialContext ctx = SpatialContext.GEO;
+ private SpatialContext ctx = SpatialContext.Geo;
//The args parser is only dependent on the ctx for IO so I don't care to test
// with other implementations.
diff --git a/src/Lucene.Net.Tests.Spatial/QueryEqualsHashCodeTest.cs b/src/Lucene.Net.Tests.Spatial/QueryEqualsHashCodeTest.cs
index 9d23290..ee3d53b 100644
--- a/src/Lucene.Net.Tests.Spatial/QueryEqualsHashCodeTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/QueryEqualsHashCodeTest.cs
@@ -5,8 +5,8 @@ using Lucene.Net.Spatial.Serialized;
using Lucene.Net.Spatial.Vector;
using Lucene.Net.Util;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using JCG = J2N.Collections.Generic;
@@ -32,7 +32,7 @@ namespace Lucene.Net.Spatial
public class QueryEqualsHashCodeTest : LuceneTestCase
{
- private readonly SpatialContext ctx = SpatialContext.GEO;
+ private readonly SpatialContext ctx = SpatialContext.Geo;
[Test]
public virtual void TestEqualsHashCode()
diff --git a/src/Lucene.Net.Tests.Spatial/Serialized/SerializedStrategyTest.cs b/src/Lucene.Net.Tests.Spatial/Serialized/SerializedStrategyTest.cs
index b4d00a6..fe90896 100644
--- a/src/Lucene.Net.Tests.Spatial/Serialized/SerializedStrategyTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/Serialized/SerializedStrategyTest.cs
@@ -1,6 +1,6 @@
using Lucene.Net.Search;
using NUnit.Framework;
-using Spatial4n.Core.Context;
+using Spatial4n.Context;
namespace Lucene.Net.Spatial.Serialized
{
@@ -26,7 +26,7 @@ namespace Lucene.Net.Spatial.Serialized
public override void SetUp()
{
base.SetUp();
- this.ctx = SpatialContext.GEO;
+ this.ctx = SpatialContext.Geo;
this.strategy = new SerializedDVStrategy(ctx, "serialized");
}
diff --git a/src/Lucene.Net.Tests.Spatial/SpatialArgsTest.cs b/src/Lucene.Net.Tests.Spatial/SpatialArgsTest.cs
index 8dd70f4..9ba5c5e 100644
--- a/src/Lucene.Net.Tests.Spatial/SpatialArgsTest.cs
+++ b/src/Lucene.Net.Tests.Spatial/SpatialArgsTest.cs
@@ -1,8 +1,8 @@
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial
@@ -29,7 +29,7 @@ namespace Lucene.Net.Spatial
[Test]
public void CalcDistanceFromErrPct()
{
- SpatialContext ctx = SpatialContext.GEO;
+ SpatialContext ctx = SpatialContext.Geo;
double DEP = 0.5;//distErrPct
//the result is the diagonal distance from the center to the closest corner,
diff --git a/src/Lucene.Net.Tests.Spatial/SpatialExample.cs b/src/Lucene.Net.Tests.Spatial/SpatialExample.cs
index c6f7c45..7df28c3 100644
--- a/src/Lucene.Net.Tests.Spatial/SpatialExample.cs
+++ b/src/Lucene.Net.Tests.Spatial/SpatialExample.cs
@@ -8,9 +8,9 @@ using Lucene.Net.Spatial.Queries;
using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Distance;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Distance;
+using Spatial4n.Shapes;
using System;
using System.Globalization;
@@ -79,7 +79,7 @@ namespace Lucene.Net.Spatial
{
//Typical geospatial context
// These can also be constructed from SpatialContextFactory
- this.ctx = SpatialContext.GEO;
+ this.ctx = SpatialContext.Geo;
int maxLevels = 11;//results in sub-meter precision for geohash
//TODO demo lookup by detail distance
@@ -125,7 +125,7 @@ namespace Lucene.Net.Spatial
//store it too; the format is up to you
// (assume point in this example)
IPoint pt = (IPoint)shape;
- doc.Add(new StoredField(strategy.FieldName, pt.X.ToString(CultureInfo.InvariantCulture) + " " + pt.Y.ToString(CultureInfo.InvariantCulture)));
+ doc.Add(new StoredField(strategy.FieldName, J2N.Numerics.Double.ToString(pt.X, CultureInfo.InvariantCulture) + " " + J2N.Numerics.Double.ToString(pt.Y, CultureInfo.InvariantCulture)));
}
return doc;
@@ -142,7 +142,7 @@ namespace Lucene.Net.Spatial
//Search with circle
//note: SpatialArgs can be parsed from a string
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
- ctx.MakeCircle(-80.0, 33.0, DistanceUtils.Dist2Degrees(200, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
+ ctx.MakeCircle(-80.0, 33.0, DistanceUtils.Dist2Degrees(200, DistanceUtils.EarthMeanRadiusKilometers)));
Filter filter = strategy.MakeFilter(args);
TopDocs docs = indexSearcher.Search(new MatchAllDocsQuery(), filter, 10, idSort);
AssertDocMatchedIds(indexSearcher, docs, 2);
@@ -155,14 +155,14 @@ namespace Lucene.Net.Spatial
double x = double.Parse(doc1Str.Substring(0, spaceIdx - 0), CultureInfo.InvariantCulture);
double y = double.Parse(doc1Str.Substring(spaceIdx + 1), CultureInfo.InvariantCulture);
double doc1DistDEG = ctx.CalcDistance(args.Shape.Center, x, y);
- assertEquals(121.6d, DistanceUtils.Degrees2Dist(doc1DistDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM), 0.1);
+ assertEquals(121.6d, DistanceUtils.Degrees2Dist(doc1DistDEG, DistanceUtils.EarthMeanRadiusKilometers), 0.1);
//or more simply:
- assertEquals(121.6d, doc1DistDEG * DistanceUtils.DEG_TO_KM, 0.1);
+ assertEquals(121.6d, doc1DistDEG * DistanceUtils.DegreesToKilometers, 0.1);
}
//--Match all, order by distance ascending
{
IPoint pt = ctx.MakePoint(60, -50);
- ValueSource valueSource = strategy.MakeDistanceValueSource(pt, DistanceUtils.DEG_TO_KM);//the distance (in km)
+ ValueSource valueSource = strategy.MakeDistanceValueSource(pt, DistanceUtils.DegreesToKilometers);//the distance (in km)
Sort distSort = new Sort(valueSource.GetSortField(false)).Rewrite(indexSearcher);//false=asc dist
TopDocs docs = indexSearcher.Search(new MatchAllDocsQuery(), 10, distSort);
AssertDocMatchedIds(indexSearcher, docs, 4, 20, 2);
diff --git a/src/Lucene.Net.Tests.Spatial/SpatialTestCase.cs b/src/Lucene.Net.Tests.Spatial/SpatialTestCase.cs
index 383e6d5..5145d45 100644
--- a/src/Lucene.Net.Tests.Spatial/SpatialTestCase.cs
+++ b/src/Lucene.Net.Tests.Spatial/SpatialTestCase.cs
@@ -6,8 +6,8 @@ using Lucene.Net.Index;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Search;
using Lucene.Net.Util;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.Text;
@@ -128,7 +128,7 @@ namespace Lucene.Net.Spatial
}
}
- protected virtual Spatial4n.Core.Shapes.IPoint randomPoint()
+ protected virtual IPoint randomPoint()
{
IRectangle WB = ctx.WorldBounds;
return ctx.MakePoint(
diff --git a/src/Lucene.Net.Tests.Spatial/SpatialTestData.cs b/src/Lucene.Net.Tests.Spatial/SpatialTestData.cs
index 671ac72..96551b6 100644
--- a/src/Lucene.Net.Tests.Spatial/SpatialTestData.cs
+++ b/src/Lucene.Net.Tests.Spatial/SpatialTestData.cs
@@ -1,6 +1,6 @@
using J2N.Text;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
@@ -62,7 +62,7 @@ namespace Lucene.Net.Spatial
{
data.shape = ctx.ReadShapeFromWkt(vals[2]);
}
- catch (Spatial4n.Core.Exceptions.ParseException e) // LUCENENET: Spatial4n has its own ParseException that is different than the one in Support
+ catch (Spatial4n.Exceptions.ParseException e) // LUCENENET: Spatial4n has its own ParseException that is different than the one in Support
{
throw RuntimeException.Create(e);
}
diff --git a/src/Lucene.Net.Tests.Spatial/SpatialTestQuery.cs b/src/Lucene.Net.Tests.Spatial/SpatialTestQuery.cs
index 8a33fba..fc29fad 100644
--- a/src/Lucene.Net.Tests.Spatial/SpatialTestQuery.cs
+++ b/src/Lucene.Net.Tests.Spatial/SpatialTestQuery.cs
@@ -1,6 +1,6 @@
using J2N.Text;
using Lucene.Net.Spatial.Queries;
-using Spatial4n.Core.Context;
+using Spatial4n.Context;
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/src/Lucene.Net.Tests.Spatial/StrategyTestCase.cs b/src/Lucene.Net.Tests.Spatial/StrategyTestCase.cs
index a0eebfd..6d3152d 100644
--- a/src/Lucene.Net.Tests.Spatial/StrategyTestCase.cs
+++ b/src/Lucene.Net.Tests.Spatial/StrategyTestCase.cs
@@ -4,8 +4,8 @@ using Lucene.Net.Queries.Function;
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/src/Lucene.Net.Tests.Spatial/TestTestFramework.cs b/src/Lucene.Net.Tests.Spatial/TestTestFramework.cs
index 9c4c290..c8abb3d 100644
--- a/src/Lucene.Net.Tests.Spatial/TestTestFramework.cs
+++ b/src/Lucene.Net.Tests.Spatial/TestTestFramework.cs
@@ -1,8 +1,8 @@
using Lucene.Net.Spatial.Queries;
using Lucene.Net.Util;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
using System.Collections.Generic;
using System.IO;
@@ -35,7 +35,7 @@ namespace Lucene.Net.Spatial
String name = StrategyTestCase.RESOURCE_PATH + StrategyTestCase.QTEST_Cities_Intersects_BBox;
Stream @in = GetType().getResourceAsStream(name);
- SpatialContext ctx = SpatialContext.GEO;
+ SpatialContext ctx = SpatialContext.Geo;
IEnumerator<SpatialTestQuery> iter = SpatialTestQuery.GetTestQueries(
new SpatialArgsParser(), ctx, name, @in);//closes the InputStream
IList<SpatialTestQuery> tests = new JCG.List<SpatialTestQuery>();
diff --git a/src/Lucene.Net.Tests.Spatial/Vector/TestPointVectorStrategy.cs b/src/Lucene.Net.Tests.Spatial/Vector/TestPointVectorStrategy.cs
index a43faf0..53a78a8 100644
--- a/src/Lucene.Net.Tests.Spatial/Vector/TestPointVectorStrategy.cs
+++ b/src/Lucene.Net.Tests.Spatial/Vector/TestPointVectorStrategy.cs
@@ -1,8 +1,8 @@
using Lucene.Net.Search;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
-using Spatial4n.Core.Context;
-using Spatial4n.Core.Shapes;
+using Spatial4n.Context;
+using Spatial4n.Shapes;
using System;
namespace Lucene.Net.Spatial.Vector
@@ -29,7 +29,7 @@ namespace Lucene.Net.Spatial.Vector
public override void SetUp()
{
base.SetUp();
- this.ctx = SpatialContext.GEO;
+ this.ctx = SpatialContext.Geo;
this.strategy = new PointVectorStrategy(ctx, GetType().Name);
}