lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From synhers...@apache.org
Subject [1/3] lucenenet git commit: Some code fixes to Spatial, merging in before re-porting from 4.8.0
Date Sun, 08 Mar 2015 21:51:41 GMT
Repository: lucenenet
Updated Branches:
  refs/heads/master 8223d5498 -> dc71f60de


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
index e4e73c6..1702e29 100644
--- a/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
+++ b/src/Lucene.Net.Spatial/Prefix/Tree/SpatialPrefixTreeFactory.cs
@@ -1,20 +1,19 @@
-/*
+/* 
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 using System;
 using System.Collections.Generic;
 using Spatial4n.Core.Context;
@@ -23,80 +22,112 @@ using Spatial4n.Core.Distance;
 namespace Lucene.Net.Spatial.Prefix.Tree
 {
     /// <summary>
-    /// Abstract Factory for creating {@link SpatialPrefixTree} instances with useful
+    /// Abstract Factory for creating
+    /// <see cref="SpatialPrefixTree">SpatialPrefixTree</see>
+    /// instances with useful
     /// defaults and passed on configurations defined in a Map.
     /// </summary>
+    /// <lucene.experimental></lucene.experimental>
     public abstract class SpatialPrefixTreeFactory
     {
-        private const double DEFAULT_GEO_MAX_DETAIL_KM = 0.001; //1m
-        public static readonly String PREFIX_TREE = "prefixTree";
-        public static readonly String MAX_LEVELS = "maxLevels";
-        public static readonly String MAX_DIST_ERR = "maxDistErr";
+        private const double DefaultGeoMaxDetailKm = 0.001;
 
-        protected Dictionary<String, String> args;
-        protected SpatialContext ctx;
-        protected int? maxLevels;
+        public const string PrefixTree = "prefixTree";
 
-        /// <summary>
+        public const string MaxLevels = "maxLevels";
+
+        public const string MaxDistErr = "maxDistErr";
+
+        protected internal IDictionary<string, string> args;
+
+        protected internal SpatialContext ctx;
+
+        protected internal int? maxLevels;
+
+        //1m
+        /// <summary>The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
+        /// 	</summary>
+        /// <remarks>
         /// The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
         /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
-        /// </summary>
-        /// <param name="args"></param>
-        /// <param name="ctx"></param>
-        /// <returns></returns>
-        public static SpatialPrefixTree MakeSPT(Dictionary<String, String> args, SpatialContext ctx)
+        /// </remarks>
+        public static SpatialPrefixTree MakeSPT(IDictionary<string, string> args, SpatialContext ctx)
         {
             SpatialPrefixTreeFactory instance;
-            String cname;
-            if (!args.TryGetValue(PREFIX_TREE, out cname) || cname == null)
+            string cname = args[PrefixTree];
+            if (cname == null)
+            {
                 cname = ctx.IsGeo() ? "geohash" : "quad";
-            if ("geohash".Equals(cname, StringComparison.InvariantCultureIgnoreCase))
+            }
+            if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase))
+            {
                 instance = new GeohashPrefixTree.Factory();
-            else if ("quad".Equals(cname, StringComparison.InvariantCultureIgnoreCase))
-                instance = new QuadPrefixTree.Factory();
+            }
             else
             {
-                Type t = Type.GetType(cname);
-                instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(t);
+                if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase))
+                {
+                    instance = new QuadPrefixTree.Factory();
+                }
+                else
+                {
+                    try
+                    {
+                        Type c = Type.GetType(cname);
+                        instance = (SpatialPrefixTreeFactory)System.Activator.CreateInstance(c);
+                    }
+                    catch (Exception e)
+                    {
+                        throw new Exception(string.Empty, e);
+                    }
+                }
             }
             instance.Init(args, ctx);
             return instance.NewSPT();
         }
 
-        protected void Init(Dictionary<String, String> args, SpatialContext ctx)
+        protected internal virtual void Init(IDictionary<string, string> args, SpatialContext
+             ctx)
         {
             this.args = args;
             this.ctx = ctx;
             InitMaxLevels();
         }
 
-        protected void InitMaxLevels()
+        protected internal virtual void InitMaxLevels()
         {
-            String mlStr;
-            if (args.TryGetValue(MAX_LEVELS, out mlStr) && mlStr != null)
+            string mlStr = args[MaxLevels];
+            if (mlStr != null)
             {
                 maxLevels = int.Parse(mlStr);
                 return;
             }
-
             double degrees;
-            if (!args.TryGetValue(MAX_DIST_ERR, out mlStr) || mlStr == null)
+            string maxDetailDistStr = args[MaxDistErr];
+            if (maxDetailDistStr == null)
             {
                 if (!ctx.IsGeo())
-                    return; //let default to max
-                degrees = DistanceUtils.Dist2Degrees(DEFAULT_GEO_MAX_DETAIL_KM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+                {
+                    return;
+                }
+                //let default to max
+                degrees = DistanceUtils.Dist2Degrees(DefaultGeoMaxDetailKm, DistanceUtils.EARTH_MEAN_RADIUS_KM);
             }
             else
             {
-                degrees = Double.Parse(mlStr);
+                degrees = double.Parse(maxDetailDistStr);
             }
             maxLevels = GetLevelForDistance(degrees);
         }
 
-        /* Calls {@link SpatialPrefixTree#getLevelForDistance(double)}. */
-        protected abstract int GetLevelForDistance(double degrees);
-
-        protected abstract SpatialPrefixTree NewSPT();
+        /// <summary>
+        /// Calls
+        /// <see cref="SpatialPrefixTree.GetLevelForDistance(double)">SpatialPrefixTree.GetLevelForDistance(double)
+        /// 	</see>
+        /// .
+        /// </summary>
+        protected internal abstract int GetLevelForDistance(double degrees);
 
+        protected internal abstract SpatialPrefixTree NewSPT();
     }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs b/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
new file mode 100644
index 0000000..032554a
--- /dev/null
+++ b/src/Lucene.Net.Spatial/Prefix/WithinPrefixTreeFilter.cs
@@ -0,0 +1,297 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Spatial.Prefix.Tree;
+using Lucene.Net.Spatial.Queries;
+using Lucene.Net.Util;
+using Spatial4n.Core.Context;
+using Spatial4n.Core.Distance;
+using Spatial4n.Core.Shapes;
+
+namespace Lucene.Net.Spatial.Prefix
+{
+    /// <summary>
+    /// Finds docs where its indexed shape is
+    /// <see cref="SpatialOperation.IsWithin">WITHIN</see>
+    /// the query shape.  It works by looking at cells outside of the query
+    /// shape to ensure documents there are excluded. By default, it will
+    /// examine all cells, and it's fairly slow.  If you know that the indexed shapes
+    /// are never comprised of multiple disjoint parts (which also means it is not multi-valued),
+    /// then you can pass
+    /// <code>SpatialPrefixTree.getDistanceForLevel(maxLevels)</code>
+    /// as
+    /// the
+    /// <code>queryBuffer</code>
+    /// constructor parameter to minimally look this distance
+    /// 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.
+    /// </summary>
+    /// <lucene.experimental></lucene.experimental>
+    public class WithinPrefixTreeFilter : AbstractVisitingPrefixTreeFilter
+    {
+        private readonly Shape bufferedQueryShape;
+
+        /// <summary>
+        /// See
+        /// <see cref="AbstractVisitingPrefixTreeFilter">AbstractVisitingPrefixTreeFilter.AbstractVisitingPrefixTreeFilter(Shape, string, Lucene.Net.Spatial.Prefix.Tree.SpatialPrefixTree, int, int)
+        /// 	</see>
+        /// .
+        /// <code>queryBuffer</code>
+        /// 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).
+        /// </summary>
+        public WithinPrefixTreeFilter(Shape queryShape, string fieldName
+                                      , SpatialPrefixTree grid, int detailLevel, int prefixGridScanLevel,
+                                      double queryBuffer
+            )
+            : base(queryShape, fieldName, grid, detailLevel, prefixGridScanLevel)
+        {
+            //TODO LUCENE-4869: implement faster algorithm based on filtering out false-positives of a
+            //  minimal query buffer by looking in a DocValues cache holding a representative
+            //  point of each disjoint component of a document's shape(s).
+            //if null then the whole world
+            if (queryBuffer == -1)
+            {
+                bufferedQueryShape = null;
+            }
+            else
+            {
+                bufferedQueryShape = BufferShape(queryShape, queryBuffer);
+            }
+        }
+
+        /// <summary>Returns a new shape that is larger than shape by at distErr.</summary>
+        /// <remarks>Returns a new shape that is larger than shape by at distErr.</remarks>
+        protected internal virtual Shape BufferShape(Shape
+                                                         shape, double distErr)
+        {
+            //TODO move this generic code elsewhere?  Spatial4j?
+            if (distErr <= 0)
+            {
+                throw new ArgumentException("distErr must be > 0");
+            }
+            SpatialContext ctx = grid.SpatialContext;
+            if (shape is Point)
+            {
+                return ctx.MakeCircle((Point)shape, distErr);
+            }
+            else
+            {
+                if (shape is Circle)
+                {
+                    var circle = (Circle)shape;
+                    double newDist = circle.GetRadius() + distErr;
+                    if (ctx.IsGeo() && newDist > 180)
+                    {
+                        newDist = 180;
+                    }
+                    return ctx.MakeCircle(circle.GetCenter(), newDist);
+                }
+                else
+                {
+                    Rectangle bbox = shape.GetBoundingBox();
+                    double newMinX = bbox.GetMinX() - distErr;
+                    double newMaxX = bbox.GetMaxX() + distErr;
+                    double newMinY = bbox.GetMinY() - distErr;
+                    double newMaxY = bbox.GetMaxY() + distErr;
+                    if (ctx.IsGeo())
+                    {
+                        if (newMinY < -90)
+                        {
+                            newMinY = -90;
+                        }
+                        if (newMaxY > 90)
+                        {
+                            newMaxY = 90;
+                        }
+                        if (newMinY == -90 || newMaxY == 90 || bbox.GetWidth() + 2 * distErr > 360)
+                        {
+                            newMinX = -180;
+                            newMaxX = 180;
+                        }
+                        else
+                        {
+                            newMinX = DistanceUtils.NormLonDEG(newMinX);
+                            newMaxX = DistanceUtils.NormLonDEG(newMaxX);
+                        }
+                    }
+                    else
+                    {
+                        //restrict to world bounds
+                        newMinX = Math.Max(newMinX, ctx.GetWorldBounds().GetMinX());
+                        newMaxX = Math.Min(newMaxX, ctx.GetWorldBounds().GetMaxX());
+                        newMinY = Math.Max(newMinY, ctx.GetWorldBounds().GetMinY());
+                        newMaxY = Math.Min(newMaxY, ctx.GetWorldBounds().GetMaxY());
+                    }
+                    return ctx.MakeRectangle(newMinX, newMaxX, newMinY, newMaxY);
+                }
+            }
+        }
+
+        /// <exception cref="System.IO.IOException"></exception>
+        public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs
+            )
+        {
+            return new _VisitorTemplate_121(this, context, acceptDocs, true).GetDocIdSet();
+        }
+
+        #region Nested type: _VisitorTemplate_121
+
+        private sealed class _VisitorTemplate_121 : VisitorTemplate
+        {
+            private readonly WithinPrefixTreeFilter _enclosing;
+            private FixedBitSet inside;
+
+            private FixedBitSet outside;
+
+            private SpatialRelation visitRelation;
+
+            public _VisitorTemplate_121(WithinPrefixTreeFilter _enclosing, AtomicReaderContext
+                                                                               baseArg1, IBits baseArg2, bool baseArg3)
+                : base(_enclosing, baseArg1, baseArg2, baseArg3)
+            {
+                this._enclosing = _enclosing;
+            }
+
+            protected internal override void Start()
+            {
+                inside = new FixedBitSet(maxDoc);
+                outside = new FixedBitSet(maxDoc);
+            }
+
+            protected internal override DocIdSet Finish()
+            {
+                inside.AndNot(outside);
+                return inside;
+            }
+
+            protected internal override IEnumerator<Cell> FindSubCellsToVisit(Cell cell)
+            {
+                //use buffered query shape instead of orig.  Works with null too.
+                return cell.GetSubCells(_enclosing.bufferedQueryShape).GetEnumerator();
+            }
+
+            /// <exception cref="System.IO.IOException"></exception>
+            protected internal override bool Visit(Cell cell)
+            {
+                //cell.relate is based on the bufferedQueryShape; we need to examine what
+                // the relation is against the queryShape
+                visitRelation = cell.GetShape().Relate(_enclosing.queryShape);
+                if (visitRelation == SpatialRelation.WITHIN)
+                {
+                    CollectDocs(inside);
+                    return false;
+                }
+                else
+                {
+                    if (visitRelation == SpatialRelation.DISJOINT)
+                    {
+                        CollectDocs(outside);
+                        return false;
+                    }
+                    else
+                    {
+                        if (cell.Level == _enclosing.detailLevel)
+                        {
+                            CollectDocs(inside);
+                            return false;
+                        }
+                    }
+                }
+                return true;
+            }
+
+            /// <exception cref="System.IO.IOException"></exception>
+            protected internal override void VisitLeaf(Cell cell)
+            {
+                //visitRelation is declared as a field, populated by visit() so we don't recompute it
+                Debug.Assert(_enclosing.detailLevel != cell.Level);
+                Debug.Assert(visitRelation == cell.GetShape().Relate(_enclosing.queryShape));
+                if (AllCellsIntersectQuery(cell, visitRelation))
+                {
+                    CollectDocs(inside);
+                }
+                else
+                {
+                    CollectDocs(outside);
+                }
+            }
+
+            /// <summary>
+            /// Returns true if the provided cell, and all its sub-cells down to
+            /// detailLevel all intersect the queryShape.
+            /// </summary>
+            /// <remarks>
+            /// Returns true if the provided cell, and all its sub-cells down to
+            /// detailLevel all intersect the queryShape.
+            /// </remarks>
+            private bool AllCellsIntersectQuery(Cell cell, SpatialRelation relate)
+            {
+                if (relate == SpatialRelation.NULL_VALUE)
+                {
+                    relate = cell.GetShape().Relate(_enclosing.queryShape);
+                }
+                if (cell.Level == _enclosing.detailLevel)
+                {
+                    return relate.Intersects();
+                }
+                if (relate == SpatialRelation.WITHIN)
+                {
+                    return true;
+                }
+                if (relate == SpatialRelation.DISJOINT)
+                {
+                    return false;
+                }
+                // Note: Generating all these cells just to determine intersection is not ideal.
+                // It was easy to implement but could be optimized. For example if the docs
+                // in question are already marked in the 'outside' bitset then it can be avoided.
+                ICollection<Cell> subCells = cell.GetSubCells(null);
+                foreach (Cell subCell in subCells)
+                {
+                    if (!AllCellsIntersectQuery(subCell, SpatialRelation.NULL_VALUE))
+                    {
+                        //recursion
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            /// <exception cref="System.IO.IOException"></exception>
+            protected internal override void VisitScanned(Cell cell)
+            {
+                if (AllCellsIntersectQuery(cell, SpatialRelation.NULL_VALUE))
+                {
+                    CollectDocs(inside);
+                }
+                else
+                {
+                    CollectDocs(outside);
+                }
+            }
+        }
+
+        #endregion
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Queries/SpatialArgs.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Queries/SpatialArgs.cs b/src/Lucene.Net.Spatial/Queries/SpatialArgs.cs
index 9af4c7f..0383508 100644
--- a/src/Lucene.Net.Spatial/Queries/SpatialArgs.cs
+++ b/src/Lucene.Net.Spatial/Queries/SpatialArgs.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -73,7 +73,7 @@ namespace Lucene.Net.Spatial.Queries
             // and this is the longest distance that might be occurring within the shape.
             double diagonalDist = ctx.GetDistCalc().Distance(
                 ctx.MakePoint(bbox.GetMinX(), bbox.GetMinY()), bbox.GetMaxX(), bbox.GetMaxY());
-            return diagonalDist*0.5*distErrPct;
+            return diagonalDist * 0.5 * distErrPct;
         }
 
         /// <summary>

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Queries/SpatialArgsParser.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Queries/SpatialArgsParser.cs b/src/Lucene.Net.Spatial/Queries/SpatialArgsParser.cs
index 6335780..b6faa9f 100644
--- a/src/Lucene.Net.Spatial/Queries/SpatialArgsParser.cs
+++ b/src/Lucene.Net.Spatial/Queries/SpatialArgsParser.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -37,11 +37,11 @@ namespace Lucene.Net.Spatial.Queries
         public static String WriteSpatialArgs(SpatialArgs args)
         {
             var str = new StringBuilder();
-            str.Append(args.Operation.GetName());
+            str.Append(args.Operation.Name);
             str.Append('(');
             str.Append(args.Shape);
             if (args.DistErrPct != null)
-                str.Append(" distErrPct=").Append(String.Format("{0:0.00}%", args.DistErrPct*100d));
+                str.Append(" distErrPct=").Append(String.Format("{0:0.00}%", args.DistErrPct * 100d));
             if (args.DistErr != null)
                 str.Append(" distErr=").Append(args.DistErr);
             str.Append(')');
@@ -117,7 +117,7 @@ namespace Lucene.Net.Spatial.Queries
         {
             var map = new Dictionary<String, String>();
             int tokenPos = 0;
-            var st = body.Split(new[] {' ', '\n', '\t'}, StringSplitOptions.RemoveEmptyEntries);
+            var st = body.Split(new[] { ' ', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries);
             while (tokenPos < st.Length)
             {
                 String a = st[tokenPos++];

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Queries/SpatialOperation.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Queries/SpatialOperation.cs b/src/Lucene.Net.Spatial/Queries/SpatialOperation.cs
index af82b7d..26f57d3 100644
--- a/src/Lucene.Net.Spatial/Queries/SpatialOperation.cs
+++ b/src/Lucene.Net.Spatial/Queries/SpatialOperation.cs
@@ -1,4 +1,4 @@
-/* See the NOTICE file distributed with
+/* See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * Esri Inc. licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
@@ -33,7 +33,7 @@ namespace Lucene.Net.Spatial.Queries
         /// Bounding box of the *indexed* shape.
         /// </summary>
         public static readonly SpatialOperation BBoxIntersects = new SpatialOperation("BBoxIntersects", true, false, false);
-        
+
         /// <summary>
         /// Bounding box of the *indexed* shape.
         /// </summary>
@@ -102,9 +102,9 @@ namespace Lucene.Net.Spatial.Queries
             return targetNeedsArea;
         }
 
-        public String GetName()
+        public String Name
         {
-            return name;
+            get { return name; }
         }
 
         public override String ToString()

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Queries/UnsupportedSpatialOperation.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Queries/UnsupportedSpatialOperation.cs b/src/Lucene.Net.Spatial/Queries/UnsupportedSpatialOperation.cs
index ad93734..35949bc 100644
--- a/src/Lucene.Net.Spatial/Queries/UnsupportedSpatialOperation.cs
+++ b/src/Lucene.Net.Spatial/Queries/UnsupportedSpatialOperation.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -22,7 +22,8 @@ namespace Lucene.Net.Spatial.Queries
     [Serializable]
     public class UnsupportedSpatialOperation : InvalidOperationException
     {
-        public UnsupportedSpatialOperation(SpatialOperation op) : base(op.GetName())
+        public UnsupportedSpatialOperation(SpatialOperation op)
+            : base(op.Name)
         {
         }
     }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/SpatialStrategy.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/SpatialStrategy.cs b/src/Lucene.Net.Spatial/SpatialStrategy.cs
index f47deca..0b283c5 100644
--- a/src/Lucene.Net.Spatial/SpatialStrategy.cs
+++ b/src/Lucene.Net.Spatial/SpatialStrategy.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -19,6 +19,7 @@ using System;
 using Lucene.Net.Documents;
 using Lucene.Net.Search;
 using Lucene.Net.Search.Function;
+using Lucene.Net.Search.Function.ValueSources;
 using Lucene.Net.Spatial.Queries;
 using Lucene.Net.Spatial.Util;
 using Spatial4n.Core.Context;
@@ -54,9 +55,9 @@ namespace Lucene.Net.Spatial
             this.fieldName = fieldName;
         }
 
-        public SpatialContext GetSpatialContext()
+        public SpatialContext SpatialContext
         {
-            return ctx;
+            get { return ctx; }
         }
 
         /// <summary>
@@ -64,9 +65,9 @@ namespace Lucene.Net.Spatial
         /// fields needed internally.
         /// </summary>
         /// <returns></returns>
-        public String GetFieldName()
+        public String FieldName
         {
-            return fieldName;
+            get { return fieldName; }
         }
 
         /// <summary>
@@ -82,11 +83,11 @@ namespace Lucene.Net.Spatial
         /// </summary>
         /// <param name="shape"></param>
         /// <returns>Not null nor will it have null elements.</returns>
-        public abstract AbstractField[] CreateIndexableFields(Shape shape);
+        public abstract Field[] CreateIndexableFields(Shape shape);
 
-        public AbstractField CreateStoredField(Shape shape)
+        public Field CreateStoredField(Shape shape)
         {
-            return new Field(GetFieldName(), ctx.ToString(shape), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO);
+            return new Field(FieldName, ctx.ToString(shape), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO);
         }
 
         /// <summary>
@@ -137,8 +138,8 @@ namespace Lucene.Net.Spatial
             Rectangle bbox = queryShape.GetBoundingBox();
             double diagonalDist = ctx.GetDistCalc().Distance(
                 ctx.MakePoint(bbox.GetMinX(), bbox.GetMinY()), bbox.GetMaxX(), bbox.GetMaxY());
-            double distToEdge = diagonalDist*0.5;
-            float c = (float) distToEdge*0.1f; //one tenth
+            double distToEdge = diagonalDist * 0.5;
+            float c = (float)distToEdge * 0.1f; //one tenth
             return new ReciprocalFloatFunction(MakeDistanceValueSource(queryShape.GetCenter()), 1f, c, c);
         }
 

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs b/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
index ef7a174..b6f9c17 100644
--- a/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/CachingDoubleValueSource.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -23,8 +23,8 @@ namespace Lucene.Net.Spatial.Util
 {
     public class CachingDoubleValueSource : ValueSource
     {
-        protected readonly ValueSource source;
         protected readonly Dictionary<int, double> cache;
+        protected readonly ValueSource source;
 
         public CachingDoubleValueSource(ValueSource source)
         {
@@ -32,22 +32,53 @@ namespace Lucene.Net.Spatial.Util
             cache = new Dictionary<int, double>();
         }
 
-        public class CachingDoubleDocValue : DocValues
+        public override string Description
+        {
+            get { return "Cached[" + source.Description + "]"; }
+        }
+
+        public override FunctionValues GetValues(IDictionary<object, object> context, AtomicReaderContext readerContext)
+        {
+            int @base = readerContext.docBase;
+            FunctionValues vals = source.GetValues(context, readerContext);
+            return new CachingDoubleFunctionValue(@base, vals, cache);
+        }
+
+        public override bool Equals(object o)
+        {
+            if (this == o) return true;
+
+            var that = o as CachingDoubleValueSource;
+
+            if (that == null) return false;
+            if (source != null ? !source.Equals(that.source) : that.source != null) return false;
+
+            return true;
+        }
+
+        public override int GetHashCode()
+        {
+            return source != null ? source.GetHashCode() : 0;
+        }
+
+        #region Nested type: CachingDoubleFunctionValue
+
+        public class CachingDoubleFunctionValue : FunctionValues
         {
-            private readonly int docBase;
-            private readonly DocValues values;
             private readonly Dictionary<int, double> cache;
+            private readonly int docBase;
+            private readonly FunctionValues values;
 
-            public CachingDoubleDocValue(int docBase, DocValues vals, Dictionary<int, double> cache)
+            public CachingDoubleFunctionValue(int docBase, FunctionValues vals, Dictionary<int, double> cache)
             {
                 this.docBase = docBase;
-                this.values = vals;
+                values = vals;
                 this.cache = cache;
             }
 
             public override double DoubleVal(int doc)
             {
-                var key = docBase + doc;
+                int key = docBase + doc;
                 double v;
                 if (!cache.TryGetValue(key, out v))
                 {
@@ -68,34 +99,6 @@ namespace Lucene.Net.Spatial.Util
             }
         }
 
-        public override DocValues GetValues(IndexReader reader)
-        {
-            var @base = 0; //reader.DocBase;
-            var vals = source.GetValues(reader);
-            return new CachingDoubleDocValue(@base, vals, cache);
-
-        }
-
-        public override string Description()
-        {
-            return "Cached[" + source.Description() + "]";
-        }
-
-        public override bool Equals(object o)
-        {
-            if (this == o) return true;
-
-            var that = o as CachingDoubleValueSource;
-
-            if (that == null) return false;
-            if (source != null ? !source.Equals(that.source) : that.source != null) return false;
-
-            return true;
-        }
-
-        public override int GetHashCode()
-        {
-            return source != null ? source.GetHashCode() : 0;
-        }
+        #endregion
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/CompatibilityExtensions.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/CompatibilityExtensions.cs b/src/Lucene.Net.Spatial/Util/CompatibilityExtensions.cs
index 26a1462..be9b185 100644
--- a/src/Lucene.Net.Spatial/Util/CompatibilityExtensions.cs
+++ b/src/Lucene.Net.Spatial/Util/CompatibilityExtensions.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -21,36 +21,18 @@ using Lucene.Net.Support.Compatibility;
 #else
 using System.Collections.Concurrent;
 #endif
-using System.Collections.Generic;
 using System.Diagnostics;
+using System.Linq;
 using Lucene.Net.Analysis.Tokenattributes;
 using Lucene.Net.Index;
 using Lucene.Net.Search;
+using Lucene.Net.Util;
 
 namespace Lucene.Net.Spatial.Util
 {
     public static class CompatibilityExtensions
     {
-        public static void Append(this ITermAttribute termAtt, string str)
-        {
-            termAtt.SetTermBuffer(termAtt.Term + str); // TODO: Not optimal, but works
-        }
-
-        public static void Append(this ITermAttribute termAtt, char ch)
-        {
-            termAtt.SetTermBuffer(termAtt.Term + new string(new[] {ch})); // TODO: Not optimal, but works
-        }
-
-        private static readonly ConcurrentDictionary<Key<string, IndexReader>, IBits> _docsWithFieldCache =
-            new ConcurrentDictionary<Key<string, IndexReader>, IBits>();
-
-        internal static IBits GetDocsWithField(this FieldCache fc, IndexReader reader, String field)
-        {
-            return _docsWithFieldCache.GetOrAdd(new Key<string, IndexReader>(field, reader),
-                                                key =>
-                                                DocsWithFieldCacheEntry_CreateValue(key.Item2,
-                                                                                    new Entry(key.Item1, null), false));
-        }
+        private static readonly ConcurrentDictionary<string, IBits> _docsWithFieldCache = new ConcurrentDictionary<string, IBits>();
 
         /// <summary> <p/>
         /// EXPERT: Instructs the FieldCache to forcibly expunge all entries 
@@ -67,63 +49,15 @@ namespace Lucene.Net.Spatial.Util
         /// of Lucene.
         /// <p/>
         /// </summary>
-        public static void PurgeSpatialCaches(this FieldCache fc)
+        public static void PurgeSpatialCaches(this IFieldCache fc)
         {
             _docsWithFieldCache.Clear();
         }
 
-        private static IBits DocsWithFieldCacheEntry_CreateValue(IndexReader reader, Entry entryKey,
-                                                                 bool setDocsWithField /* ignored */)
-        {
-            var field = entryKey.field;
-            FixedBitSet res = null;
-            var terms = new TermsEnumCompatibility(reader, field);
-            var maxDoc = reader.MaxDoc;
-
-            var term = terms.Next();
-            if (term != null)
-            {
-                int termsDocCount = terms.GetDocCount();
-                Debug.Assert(termsDocCount <= maxDoc);
-                if (termsDocCount == maxDoc)
-                {
-                    // Fast case: all docs have this field:
-                    return new MatchAllBits(maxDoc);
-                }
-
-                while (true)
-                {
-                    if (res == null)
-                    {
-                        // lazy init
-                        res = new FixedBitSet(maxDoc);
-                    }
-
-                    var termDocs = reader.TermDocs(term);
-                    while (termDocs.Next())
-                    {
-                        res.Set(termDocs.Doc);
-                    }
 
-                    term = terms.Next();
-                    if (term == null)
-                    {
-                        break;
-                    }
-                }
-            }
-            if (res == null)
-            {
-                return new MatchNoBits(maxDoc);
-            }
-            int numSet = res.Cardinality();
-            if (numSet >= maxDoc)
-            {
-                // The cardinality of the BitSet is maxDoc if all documents have a value.
-                Debug.Assert(numSet == maxDoc);
-                return new MatchAllBits(maxDoc);
-            }
-            return res;
+        public static byte[] ToByteArray(this sbyte[] sbytes)
+        {
+            return sbytes.Select(Convert.ToByte).ToArray();
         }
 
         /* table of number of leading zeros in a byte */
@@ -142,6 +76,10 @@ namespace Lucene.Net.Spatial.Util
                 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
             };
+        public static sbyte[] ToSByteArray(this byte[] bytes)
+        {
+            return bytes.Select(Convert.ToSByte).ToArray();
+        }
 
         /// <summary>
         /// Returns the number of leading zero bits.
@@ -152,23 +90,11 @@ namespace Lucene.Net.Spatial.Util
         {
             int n = 0;
             // do the first step as a long
-            var y = (int) ((ulong) x >> 32);
-            if (y == 0)
-            {
-                n += 32;
-                y = (int) (x);
-            }
-            if ((y & 0xFFFF0000) == 0)
-            {
-                n += 16;
-                y <<= 16;
-            }
-            if ((y & 0xFF000000) == 0)
-            {
-                n += 8;
-                y <<= 8;
-            }
-            return n + nlzTable[(uint) y >> 24];
+            var y = (int)((ulong)x >> 32);
+            if (y == 0) { n += 32; y = (int)(x); }
+            if ((y & 0xFFFF0000) == 0) { n += 16; y <<= 16; }
+            if ((y & 0xFF000000) == 0) { n += 8; y <<= 8; }
+            return n + nlzTable[(uint)y >> 24];
             /* implementation without table:
               if ((y & 0xF0000000) == 0) { n+=4; y<<=4; }
               if ((y & 0xC0000000) == 0) { n+=2; y<<=2; }
@@ -207,11 +133,10 @@ namespace Lucene.Net.Spatial.Util
     /// </summary>
     internal class Entry
     {
-        internal readonly String field; // which Fieldable
-        internal readonly Object custom; // which custom comparator or parser
+        internal readonly String field;        // which Fieldable
+        internal readonly Object custom;       // which custom comparator or parser
 
         /* Creates one of these objects for a custom comparator/parser. */
-
         public Entry(String field, Object custom)
         {
             this.field = field;
@@ -219,7 +144,6 @@ namespace Lucene.Net.Spatial.Util
         }
 
         /* Two of these are equal iff they reference the same field and type. */
-
         public override bool Equals(Object o)
         {
             var other = o as Entry;
@@ -241,56 +165,9 @@ namespace Lucene.Net.Spatial.Util
         }
 
         /* Composes a hashcode based on the field and type. */
-
         public override int GetHashCode()
         {
             return field.GetHashCode() ^ (custom == null ? 0 : custom.GetHashCode());
         }
     }
-
-    internal struct Key<T1, T2> : IEquatable<Key<T1, T2>>
-    {
-        public bool Equals(Key<T1, T2> other)
-        {
-            return EqualityComparer<T1>.Default.Equals(Item1, other.Item1) &&
-                   EqualityComparer<T2>.Default.Equals(Item2, other.Item2);
-        }
-
-        public override bool Equals(object obj)
-        {
-            if (ReferenceEquals(null, obj))
-            {
-                return false;
-            }
-            return obj is Key<T1, T2> && Equals((Key<T1, T2>) obj);
-        }
-
-        public override int GetHashCode()
-        {
-            unchecked
-            {
-                return (EqualityComparer<T1>.Default.GetHashCode(Item1)*397) ^
-                       EqualityComparer<T2>.Default.GetHashCode(Item2);
-            }
-        }
-
-        public static bool operator ==(Key<T1, T2> left, Key<T1, T2> right)
-        {
-            return left.Equals(right);
-        }
-
-        public static bool operator !=(Key<T1, T2> left, Key<T1, T2> right)
-        {
-            return !left.Equals(right);
-        }
-
-        public readonly T1 Item1;
-        public readonly T2 Item2;
-
-        public Key(T1 item1, T2 item2)
-        {
-            Item1 = item1;
-            Item2 = item2;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/FunctionQuery.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/FunctionQuery.cs b/src/Lucene.Net.Spatial/Util/FunctionQuery.cs
index 64eda65..8d5d1c7 100644
--- a/src/Lucene.Net.Spatial/Util/FunctionQuery.cs
+++ b/src/Lucene.Net.Spatial/Util/FunctionQuery.cs
@@ -209,7 +209,7 @@ namespace Lucene.Net.Spatial.Util
 
         public override int GetHashCode()
         {
-            return (int) (func.GetHashCode() * 31 + BitConverter.DoubleToInt64Bits(Boost));
+            return (int)(func.GetHashCode() * 31 + BitConverter.DoubleToInt64Bits(Boost));
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/ReciprocalFloatFunction.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/ReciprocalFloatFunction.cs b/src/Lucene.Net.Spatial/Util/ReciprocalFloatFunction.cs
index 5789df4..010f628 100644
--- a/src/Lucene.Net.Spatial/Util/ReciprocalFloatFunction.cs
+++ b/src/Lucene.Net.Spatial/Util/ReciprocalFloatFunction.cs
@@ -92,9 +92,9 @@ namespace Lucene.Net.Spatial.Util
 
         public override int GetHashCode()
         {
-            int h = (int) BitConverter.DoubleToInt64Bits(a) + (int) BitConverter.DoubleToInt64Bits(m);
+            int h = (int)BitConverter.DoubleToInt64Bits(a) + (int)BitConverter.DoubleToInt64Bits(m);
             h ^= (h << 13) | (int)((uint)h >> 20);
-            return h + ((int) BitConverter.DoubleToInt64Bits(b)) + source.GetHashCode();
+            return h + ((int)BitConverter.DoubleToInt64Bits(b)) + source.GetHashCode();
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
index 59db379..6c27c54 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCache.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
index d806767..b487d0c 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheDistanceValueSource.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -16,6 +16,7 @@
  */
 
 using System;
+using System.Collections.Generic;
 using Lucene.Net.Index;
 using Lucene.Net.Search.Function;
 using Spatial4n.Core.Context;
@@ -40,7 +41,7 @@ namespace Lucene.Net.Spatial.Util
             this.provider = provider;
         }
 
-        public class CachedDistanceDocValues : DocValues
+        public class CachedDistanceFunctionValue : FunctionValues
         {
             private readonly ShapeFieldCacheDistanceValueSource enclosingInstance;
             private readonly ShapeFieldCache<Point> cache;
@@ -48,11 +49,11 @@ namespace Lucene.Net.Spatial.Util
             private readonly DistanceCalculator calculator;
             private readonly double nullValue;
 
-            public CachedDistanceDocValues(IndexReader reader, ShapeFieldCacheDistanceValueSource enclosingInstance)
+            public CachedDistanceFunctionValue(AtomicReader reader, ShapeFieldCacheDistanceValueSource enclosingInstance)
             {
                 cache = enclosingInstance.provider.GetCache(reader);
                 this.enclosingInstance = enclosingInstance;
-                
+
                 from = enclosingInstance.from;
                 calculator = enclosingInstance.ctx.GetDistCalc();
                 nullValue = (enclosingInstance.ctx.IsGeo() ? 180 : double.MaxValue);
@@ -80,18 +81,21 @@ namespace Lucene.Net.Spatial.Util
 
             public override string ToString(int doc)
             {
-                return enclosingInstance.Description() + "=" + FloatVal(doc);
+                return enclosingInstance.Description + "=" + FloatVal(doc);
             }
         }
 
-        public override DocValues GetValues(IndexReader reader)
+        public override string Description
         {
-            return new CachedDistanceDocValues(reader, this);
+            get
+            {
+                return GetType().Name + "(" + provider + ", " + from + ")";
+            }
         }
 
-        public override string Description()
+        public override FunctionValues GetValues(IDictionary<object, object> context, AtomicReaderContext readerContext)
         {
-            return GetType().Name + "(" + provider + ", " + from + ")";
+            return new CachedDistanceFunctionValue(readerContext.AtomicReader, this);
         }
 
         public override bool Equals(object o)

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
index 782ebc9..51827c3 100644
--- a/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
+++ b/src/Lucene.Net.Spatial/Util/ShapeFieldCacheProvider.cs
@@ -1,23 +1,24 @@
-/*
+/* 
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 using System;
 using System.Runtime.CompilerServices;
 using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
 using Spatial4n.Core.Shapes;
 #if NET35
 using Lucene.Net.Support;
@@ -26,41 +27,47 @@ using Lucene.Net.Support;
 namespace Lucene.Net.Spatial.Util
 {
     /// <summary>
-    /// Provides access to a {@link ShapeFieldCache} for a given {@link AtomicReader}.
-    /// 
+    /// Provides access to a
+    /// <see cref="ShapeFieldCache{T}">ShapeFieldCache&lt;T&gt;</see>
+    /// for a given
+    /// <see cref="Lucene.Net.Index.AtomicReader">Lucene.Net.Index.AtomicReader
+    /// 	</see>
+    /// .
     /// 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>
-    /// <typeparam name="T"></typeparam>
-    public abstract class ShapeFieldCacheProvider<T> where T : Shape
+    /// <lucene.internal></lucene.internal>
+    public abstract class ShapeFieldCacheProvider<T>
+        where T : Shape
     {
-        //private Logger log = Logger.getLogger(getClass().getName());
+        //private Logger log = Logger.GetLogger(GetType().FullName);
 
-        // it may be a List<T> or T
 #if !NET35
         private readonly ConditionalWeakTable<IndexReader, ShapeFieldCache<T>> sidx =
             new ConditionalWeakTable<IndexReader, ShapeFieldCache<T>>(); // WeakHashMap
 #else
-        private readonly WeakDictionary<IndexReader, ShapeFieldCache<T>> sidx =
-            new WeakDictionary<IndexReader, ShapeFieldCache<T>>();
+	    private readonly WeakDictionary<IndexReader, ShapeFieldCache<T>> sidx =
+	        new WeakDictionary<IndexReader, ShapeFieldCache<T>>();
 #endif
 
+        protected internal readonly int defaultSize;
 
-        protected readonly int defaultSize;
-        protected readonly String shapeField;
+        protected internal readonly string shapeField;
 
-        protected ShapeFieldCacheProvider(String shapeField, int defaultSize)
+        public ShapeFieldCacheProvider(string shapeField, int defaultSize)
         {
+            // it may be a List<T> or T
             this.shapeField = shapeField;
             this.defaultSize = defaultSize;
         }
 
-        protected abstract T ReadShape(/*BytesRef*/ Term term);
+        protected internal abstract T ReadShape(BytesRef term);
 
         private readonly object locker = new object();
 
-        public ShapeFieldCache<T> GetCache(IndexReader reader)
+        /// <exception cref="System.IO.IOException"></exception>
+        public virtual ShapeFieldCache<T> GetCache(AtomicReader reader)
         {
             lock (locker)
             {
@@ -69,35 +76,37 @@ namespace Lucene.Net.Spatial.Util
                 {
                     return idx;
                 }
-
-                //long startTime = System.CurrentTimeMillis();
-                //log.fine("Building Cache [" + reader.MaxDoc() + "]");
-
+                /*long startTime = Runtime.CurrentTimeMillis();
+				log.Fine("Building Cache [" + reader.MaxDoc() + "]");*/
                 idx = new ShapeFieldCache<T>(reader.MaxDoc, defaultSize);
-                var count = 0;
-                var tec = new TermsEnumCompatibility(reader, shapeField);
-
-                var term = tec.Next();
-                while (term != null)
+                int count = 0;
+                DocsEnum docs = null;
+                Terms terms = reader.Terms(shapeField);
+                TermsEnum te = null;
+                if (terms != null)
                 {
-                    var shape = ReadShape(term);
-                    if (shape != null)
+                    te = terms.Iterator(te);
+                    BytesRef term = te.Next();
+                    while (term != null)
                     {
-                        var docs = reader.TermDocs(new Term(shapeField, tec.Term().Text));
-                        while (docs.Next())
+                        T shape = ReadShape(term);
+                        if (shape != null)
                         {
-                            idx.Add(docs.Doc, shape);
-                            count++;
+                            docs = te.Docs(null, docs, DocsEnum.FLAG_NONE);
+                            int docid = docs.NextDoc();
+                            while (docid != DocIdSetIterator.NO_MORE_DOCS)
+                            {
+                                idx.Add(docid, shape);
+                                docid = docs.NextDoc();
+                                count++;
+                            }
                         }
+                        term = te.Next();
                     }
-                    term = tec.Next();
                 }
-
                 sidx.Add(reader, idx);
-                tec.Close();
-
-                //long elapsed = System.CurrentTimeMillis() - startTime;
-                //log.fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);
+                /*long elapsed = Runtime.CurrentTimeMillis() - startTime;
+                log.Fine("Cached: [" + count + " in " + elapsed + "ms] " + idx);*/
                 return idx;
             }
         }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs b/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
index e92c120..6bba8c7 100644
--- a/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
+++ b/src/Lucene.Net.Spatial/Util/ValueSourceFilter.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -16,8 +16,10 @@
  */
 
 using System;
+using Lucene.Net.Index;
 using Lucene.Net.Search;
 using Lucene.Net.Search.Function;
+using Lucene.Net.Util;
 
 namespace Lucene.Net.Spatial.Util
 {
@@ -44,18 +46,18 @@ namespace Lucene.Net.Spatial.Util
             this.max = max;
         }
 
-        public override DocIdSet GetDocIdSet(Index.IndexReader reader)
+        public override DocIdSet GetDocIdSet(AtomicReaderContext context, IBits acceptDocs)
         {
-            var values = source.GetValues(reader);
-            return new ValueSourceFilteredDocIdSet(startingFilter.GetDocIdSet(reader), values, this);
+            var values = source.GetValues(null, context);
+            return new ValueSourceFilteredDocIdSet(startingFilter.GetDocIdSet(context, acceptDocs), values, this);
         }
 
         public class ValueSourceFilteredDocIdSet : FilteredDocIdSet
         {
             private readonly ValueSourceFilter enclosingFilter;
-            private readonly DocValues values;
+            private readonly FunctionValues values;
 
-            public ValueSourceFilteredDocIdSet(DocIdSet innerSet, DocValues values, ValueSourceFilter caller)
+            public ValueSourceFilteredDocIdSet(DocIdSet innerSet, FunctionValues values, ValueSourceFilter caller)
                 : base(innerSet)
             {
                 this.enclosingFilter = caller;
@@ -68,5 +70,6 @@ namespace Lucene.Net.Spatial.Util
                 return val >= enclosingFilter.min && val <= enclosingFilter.max;
             }
         }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs b/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
index 19e2ea0..509146a 100644
--- a/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
+++ b/src/Lucene.Net.Spatial/Vector/DistanceValueSource.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -15,14 +15,14 @@
  * limitations under the License.
  */
 
+using System.Collections.Generic;
 using System.Diagnostics;
 using Lucene.Net.Index;
 using Lucene.Net.Search;
 using Lucene.Net.Search.Function;
-using Lucene.Net.Spatial.Util;
+using Lucene.Net.Util;
 using Spatial4n.Core.Distance;
 using Spatial4n.Core.Shapes;
-using Spatial4n.Core.Shapes.Impl;
 
 namespace Lucene.Net.Spatial.Vector
 {
@@ -31,8 +31,8 @@ namespace Lucene.Net.Spatial.Vector
     /// </summary>
     public class DistanceValueSource : ValueSource
     {
-        private readonly PointVectorStrategy strategy;
         private readonly Point from;
+        private readonly PointVectorStrategy strategy;
 
         public DistanceValueSource(PointVectorStrategy strategy, Point from)
         {
@@ -40,29 +40,58 @@ namespace Lucene.Net.Spatial.Vector
             this.from = from;
         }
 
-        public class DistanceDocValues : DocValues
+        public override string Description
         {
-            private readonly DistanceValueSource enclosingInstance;
+            get { return "DistanceValueSource(" + strategy + ", " + from + ")"; }
+        }
 
-            private readonly double[] ptX, ptY;
-            private readonly IBits validX, validY;
+        public override FunctionValues GetValues(IDictionary<object, object> context, AtomicReaderContext readerContext)
+        {
+            return new DistanceFunctionValue(this, readerContext.AtomicReader);
+        }
 
-            private readonly Point from;
+        public override bool Equals(object o)
+        {
+            if (this == o) return true;
+
+            var that = o as DistanceValueSource;
+            if (that == null) return false;
+
+            if (!from.Equals(that.from)) return false;
+            if (!strategy.Equals(that.strategy)) return false;
+
+            return true;
+        }
+
+        public override int GetHashCode()
+        {
+            return from.GetHashCode();
+        }
+
+        #region Nested type: DistanceFunctionValues
+
+        public class DistanceFunctionValue : FunctionValues
+        {
             private readonly DistanceCalculator calculator;
+            private readonly DistanceValueSource enclosingInstance;
+            private readonly Point from;
             private readonly double nullValue;
 
-            public DistanceDocValues(DistanceValueSource enclosingInstance, IndexReader reader)
+            private readonly FieldCache.Doubles ptX, ptY;
+            private readonly IBits validX, validY;
+
+            public DistanceFunctionValue(DistanceValueSource enclosingInstance, AtomicReader reader)
             {
                 this.enclosingInstance = enclosingInstance;
 
-                ptX = FieldCache_Fields.DEFAULT.GetDoubles(reader, enclosingInstance.strategy.GetFieldNameX()/*, true*/);
-                ptY = FieldCache_Fields.DEFAULT.GetDoubles(reader, enclosingInstance.strategy.GetFieldNameY()/*, true*/);
-                validX = FieldCache_Fields.DEFAULT.GetDocsWithField(reader, enclosingInstance.strategy.GetFieldNameX());
-                validY = FieldCache_Fields.DEFAULT.GetDocsWithField(reader, enclosingInstance.strategy.GetFieldNameY());
+                ptX = FieldCache.DEFAULT.GetDoubles(reader, enclosingInstance.strategy.FieldNameX, true);
+                ptY = FieldCache.DEFAULT.GetDoubles(reader, enclosingInstance.strategy.FieldNameY, true);
+                validX = FieldCache.DEFAULT.GetDocsWithField(reader, enclosingInstance.strategy.FieldNameX);
+                validY = FieldCache.DEFAULT.GetDocsWithField(reader, enclosingInstance.strategy.FieldNameY);
 
                 from = enclosingInstance.from;
-                calculator = enclosingInstance.strategy.GetSpatialContext().GetDistCalc();
-                nullValue = (enclosingInstance.strategy.GetSpatialContext().IsGeo() ? 180 : double.MaxValue);
+                calculator = enclosingInstance.strategy.SpatialContext.GetDistCalc();
+                nullValue = (enclosingInstance.strategy.SpatialContext.IsGeo() ? 180 : double.MaxValue);
             }
 
             public override float FloatVal(int doc)
@@ -73,46 +102,20 @@ namespace Lucene.Net.Spatial.Vector
             public override double DoubleVal(int doc)
             {
                 // make sure it has minX and area
-                if (validX.Get(doc))
+                if (validX[doc])
                 {
-                    Debug.Assert(validY.Get(doc));
-                    return calculator.Distance(from, ptX[doc], ptY[doc]);
+                    Debug.Assert(validY[doc]);
+                    return calculator.Distance(from, ptX.Get(doc), ptY.Get(doc));
                 }
                 return nullValue;
             }
 
             public override string ToString(int doc)
             {
-                return enclosingInstance.Description() + "=" + FloatVal(doc);
+                return enclosingInstance.Description + "=" + FloatVal(doc);
             }
         }
 
-        public override DocValues GetValues(IndexReader reader)
-        {
-            return new DistanceDocValues(this, reader);
-        }
-
-        public override string Description()
-        {
-            return "DistanceValueSource(" + strategy + ", " + from + ")";
-        }
-
-        public override bool Equals(object o)
-        {
-            if (this == o) return true;
-
-            var that = o as DistanceValueSource;
-            if (that == null) return false;
-
-            if (!from.Equals(that.from)) return false;
-            if (!strategy.Equals(that.strategy)) return false;
-
-            return true;
-        }
-
-        public override int GetHashCode()
-        {
-            return from.GetHashCode();
-        }
+        #endregion
     }
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/dc71f60d/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs b/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
index f3ef815..0f1238f 100644
--- a/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
+++ b/src/Lucene.Net.Spatial/Vector/PointVectorStrategy.cs
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -53,24 +53,27 @@ namespace Lucene.Net.Spatial.Vector
             this.fieldNameY = fieldNamePrefix + SUFFIX_Y;
         }
 
-        public void SetPrecisionStep(int p)
+        public int PrecisionStep
         {
-            precisionStep = p;
-            if (precisionStep <= 0 || precisionStep >= 64)
-                precisionStep = int.MaxValue;
+            set
+            {
+                precisionStep = value;
+                if (precisionStep <= 0 || precisionStep >= 64)
+                    precisionStep = int.MaxValue;
+            }
         }
 
-        public string GetFieldNameX()
+        public string FieldNameX
         {
-            return fieldNameX;
+            get { return fieldNameX; }
         }
 
-        public string GetFieldNameY()
+        public string FieldNameY
         {
-            return fieldNameY;
+            get { return fieldNameY; }
         }
 
-        public override AbstractField[] CreateIndexableFields(Shape shape)
+        public override Field[] CreateIndexableFields(Shape shape)
         {
             var point = shape as Point;
             if (point != null)
@@ -79,21 +82,18 @@ namespace Lucene.Net.Spatial.Vector
             throw new InvalidOperationException("Can only index Point, not " + shape);
         }
 
-        public AbstractField[] CreateIndexableFields(Point point)
+        public Field[] CreateIndexableFields(Point point)
         {
-                var f = new AbstractField[2];
-
-                var f0 = new NumericField(fieldNameX, precisionStep, Field.Store.NO, true)
-                             {OmitNorms = true, OmitTermFreqAndPositions = true};
-                f0.SetDoubleValue(point.GetX());
-                f[0] = f0;
-
-                var f1 = new NumericField(fieldNameY, precisionStep, Field.Store.NO, true)
-                             {OmitNorms = true, OmitTermFreqAndPositions = true};
-                f1.SetDoubleValue(point.GetY());
-                f[1] = f1;
-
-                return f;
+            FieldType doubleFieldType = new FieldType(DoubleField.TYPE_NOT_STORED)
+                                            {
+                                                NumericPrecisionStep = precisionStep
+                                            };
+            var f = new Field[]
+                        {
+                            new DoubleField(fieldNameX, point.GetX(), doubleFieldType),
+                            new DoubleField(fieldNameY, point.GetY(), doubleFieldType)
+                        };
+            return f;
         }
 
         public override ValueSource MakeDistanceValueSource(Point queryPoint)
@@ -124,7 +124,7 @@ namespace Lucene.Net.Spatial.Vector
                     circle.GetRadius());
                 return new ConstantScoreQuery(vsf);
             }
-            
+
             throw new InvalidOperationException("Only Rectangles and Circles are currently supported, " +
                                             "found [" + shape.GetType().Name + "]"); //TODO
         }
@@ -253,7 +253,7 @@ namespace Lucene.Net.Spatial.Vector
                 throw new InvalidOperationException("MakeDisjoint doesn't handle dateline cross");
             Query qX = RangeQuery(fieldNameX, bbox.GetMinX(), bbox.GetMaxX());
             Query qY = RangeQuery(fieldNameY, bbox.GetMinY(), bbox.GetMaxY());
-            var bq = new BooleanQuery {{qX, Occur.MUST_NOT}, {qY, Occur.MUST_NOT}};
+            var bq = new BooleanQuery { { qX, Occur.MUST_NOT }, { qY, Occur.MUST_NOT } };
             return bq;
         }
     }


Mime
View raw message