[ 
https://issues.apache.org/jira/browse/LUCENE-7270?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15268819#comment-15268819
 ] 

Karl Wright commented on LUCENE-7270:
-------------------------------------

For reference, here's my entire tree implementation.

{code}
  private static abstract class Tree {
    private final Node rootNode;
    
    protected static final Edge[] EMPTY_ARRAY = new Edge[0];
    
    /** Constructor.
     * @param allEdges is the list of all edges for the tree.
     */
    public Tree(final List<Edge> allEdges) {
      // Dump edges into an array and then sort it
      final Node[] edges = new Node[allEdges.size()];
      int i = 0;
      for (final Edge edge : allEdges) {
        edges[i++] = new Node(edge, getMinimum(edge), getMaximum(edge));
      }
      Arrays.sort(edges, (left, right) -> {
        int ret = Double.compare(left.low, right.low);
        if (ret == 0) {
          ret = Double.compare(left.max, right.max);
        }
        return ret;
      });
      rootNode = createTree(edges, 0, edges.length - 1);
    }
    
    private static Node createTree(final Node[] edges, final int low, final int 
high) {
      if (low > high) {
        return null;
      }
      // add midpoint
      int mid = (low + high) >>> 1;
      final Node newNode = edges[mid];
      // add children
      newNode.left = createTree(edges, low, mid - 1);
      newNode.right = createTree(edges, mid + 1, high);
      // pull up max values to this node
      if (newNode.left != null) {
        newNode.max = Math.max(newNode.max, newNode.left.max);
      }
      if (newNode.right != null) {
        newNode.max = Math.max(newNode.max, newNode.right.max);
      }
      return newNode;
    }

    /** Get the minimum value from the edge.
     * @param edge is the edge.
     * @return the minimum value.
     */
    protected abstract double getMinimum(final Edge edge);
    
    /** Get the maximum value from the edge.
     * @param edge is the edge.
     * @return the maximum value.
     */
    protected abstract double getMaximum(final Edge edge);
    
    /** Traverse the tree, finding all edges that intersect the provided value.
     * @param edgeIterator provides the method to call for any encountered 
matching edge.
     * @param value is the value to match.
     * @return false if the traversal was aborted before completion.
     */
    public boolean traverse(final EdgeIterator edgeIterator, final double 
value) {
      return traverse(edgeIterator, value, value);
    }
    
    /** Traverse the tree, finding all edges that intersect the provided value 
range.
     * @param edgeIterator provides the method to call for any encountered 
matching edge.
     *   Edges will not be invoked more than once.
     * @param minValue is the minimum value.
     * @param maxValue is the maximum value.
     * @return false if the traversal was aborted before completion.
     */
    public boolean traverse(final EdgeIterator edgeIterator, final double 
minValue, final double maxValue) {
      return traverse(rootNode, edgeIterator, minValue, maxValue);
    }
    
    private static boolean traverse(final Node node, final EdgeIterator 
edgeIterator, final double minValue, final double maxValue) {
      if (node == null) {
        return true;
      }
      if (minValue <= node.max) {
        
        // Does this node overlap?
        if (minValue <= node.high && maxValue >= node.low) {
          if (edgeIterator.matches(node.edge) == false) {
            return false;
          }
        }
        
        if (traverse(node.left, edgeIterator, minValue, maxValue) == false) {
          return false;
        }
        if (traverse(node.right, edgeIterator, minValue, maxValue) == false) {
          return false;
        }
      }
      return true;
    }

  }
{code}


> Use better balanced trees for Geo3d complex polygons
> ----------------------------------------------------
>
>                 Key: LUCENE-7270
>                 URL: https://issues.apache.org/jira/browse/LUCENE-7270
>             Project: Lucene - Core
>          Issue Type: Improvement
>          Components: modules/spatial3d
>            Reporter: Karl Wright
>            Assignee: Karl Wright
>
> The current tree data structure in GeoComplexPolygon has a lot of weaknesses. 
>  A better algorithm maybe can be taken from Polygon2D, which basically does 
> the following:
> Each node has:
> - low value (which is for that edge alone)
> - max value (which is for that edge and all children)
> Balanced tree building:
> - sort by low value (which is for the individual edge), and use max value as 
> tie breaker (which is max for edge and all children)
> - build tree after sorting, picking midpoint and recursively building lesser 
> and greater children that way
> Balanced tree traversal (looking for range minValue -> maxValue):
> - Descend the entire tree until the node fails this test:
>       if (minValue <= max) { ... }
>   So if the minimum value being sought is greater than the max for this edge 
> and all children, we stop and don't look at children.
>   (Q: does this represent a good split and a targeted range?  Maybe...  We 
> can certainly try it.)



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to