Ejemplo n.º 1
0
 def condition(node: RTreeNode):
     return node.get_bounding_rect().intersects(Rect(4, 1, 8, 3))
Ejemplo n.º 2
0
 def condition(node: RTreeNode):
     return node.get_bounding_rect() == Rect(8, 7, 10, 9)
Ejemplo n.º 3
0
 def condition(node: RTreeNode):
     return node.get_bounding_rect() == Rect(0, 0, 11, 10)
Ejemplo n.º 4
0
 def node_condition(node: RTreeNode):
     return node.get_bounding_rect().intersects(Rect(0, 0, 1, 1))
Ejemplo n.º 5
0
 def condition(node: RTreeNode):
     return node.get_bounding_rect().min_x == 0
Ejemplo n.º 6
0
 def fn(node: RTreeNode, lvl: int):
     yield (lvl, node.get_bounding_rect())
Ejemplo n.º 7
0
 def condition(n: RTreeNode, lvl: int):
     mbr = n.get_bounding_rect()
     max_x = mbr.max_x
     max_y = mbr.max_y
     return lvl == 0 or max_x == 10 or max_y == 5
Ejemplo n.º 8
0
 def condition(node: RTreeNode):
     return node.is_root or node.get_bounding_rect().max_x <= 10
Ejemplo n.º 9
0
    def test_rstar_overflow_reinsert_with_split(self):
        """
        Tests R* overflow scenario that results in forced reinsert of some entries into a different node which is
        already at capacity, causing it to overflow. In this scenario, the second overflow at the same level should
        result in a regular split, not another forced reinsert.
        """
        # Arrange
        t = RStarTree(max_entries=3)
        r1 = Rect(0, 0, 1, 1)
        r2 = Rect(0, 1, 1, 2)
        r3 = Rect(9, 0, 10, 1)
        r4 = Rect(0, 2, 1, 3)
        r5 = Rect(9, 6, 10, 7)
        r6 = Rect(3, 2, 10, 5)
        t.root = RTreeNode(t, is_leaf=False)
        entry_a = RTreeEntry(r1, data='a')
        entry_b = RTreeEntry(r2, data='b')
        entry_c = RTreeEntry(r3, data='c')
        entry_d = RTreeEntry(r4, data='d')
        entry_e = RTreeEntry(r5, data='e')
        entry_f = RTreeEntry(r6, data='f')
        n1 = RTreeNode(t,
                       is_leaf=True,
                       parent=t.root,
                       entries=[entry_a, entry_b, entry_d])
        n2 = RTreeNode(t,
                       is_leaf=True,
                       parent=t.root,
                       entries=[entry_c, entry_e, entry_f])
        e1 = RTreeEntry(Rect(0, 0, 1, 3), child=n1)
        e2 = RTreeEntry(Rect(3, 0, 10, 7), child=n2)
        t.root.entries = [e1, e2]
        # Arrange entry being inserted
        r7 = Rect(2, 1, 3, 2)
        entry_g = RTreeEntry(r7, data='g')
        # Manually insert the new entry into node n2, causing it to be overfull.
        n2.entries.append(entry_g)
        # Ensure preconditions:
        # At this point, the root node entries will still have their old covering rectangles.
        self.assertEqual(Rect(0, 0, 1, 3), e1.rect)
        self.assertEqual(Rect(3, 0, 10, 7), e2.rect)
        # At this point, the root node will only have 2 entries for e1 and e2
        self.assertEqual([e1, e2], t.root.entries)

        # Act
        rstar_overflow(t, n2)

        # Assert
        # Root node should now have 3 entries (split should have occurred)
        self.assertEqual(3, len(t.root.entries))
        # There should still be 2 levels in the tree (root node should not have split)
        levels = t.get_levels()
        self.assertEqual(2, len(levels))
        # There should be 3 nodes at the leaf level
        leaf_nodes = levels[1]
        self.assertEqual(3, len(leaf_nodes))
        # One of the nodes should have entries [a, b] and with the correct bounding rectangle
        n1 = next((n for n in leaf_nodes
                   if set(_get_leaf_node_data(n)) == {'a', 'b'}))
        self.assertEqual(Rect(0, 0, 1, 2), n1.get_bounding_rect())
        self.assertEqual(Rect(0, 0, 1, 2), n1.parent_entry.rect)
        # Another node should have entries [c, e, f] and with the correct bounding rectangle
        n2 = next((n for n in leaf_nodes
                   if set(_get_leaf_node_data(n)) == {'c', 'e', 'f'}))
        self.assertEqual(Rect(3, 0, 10, 7), n2.get_bounding_rect())
        self.assertEqual(Rect(3, 0, 10, 7), n2.parent_entry.rect)
        # Last node should have entries [d, g] and with the correct bounding rectangle
        n3 = next((n for n in leaf_nodes
                   if set(_get_leaf_node_data(n)) == {'d', 'g'}))
        self.assertEqual(Rect(0, 1, 3, 3), n3.get_bounding_rect())
        self.assertEqual(Rect(0, 1, 3, 3), n3.parent_entry.rect)
Ejemplo n.º 10
0
    def test_rstar_overflow_reinsert_without_split(self, rstar_split_mock):
        """
        Tests R* overflow scenario that results in forced reinsert of some entries into a different node, but without
        any additional overflows/splits occurring.
        """
        # Arrange
        t = RStarTree(max_entries=3)
        r1 = Rect(0, 0, 1, 1)
        r2 = Rect(9, 0, 10, 1)
        r3 = Rect(0, 1, 1, 2)
        r4 = Rect(9, 5, 10, 6)
        r5 = Rect(3, 2, 10, 4)
        t.root = RTreeNode(t, is_leaf=False)
        entry_a = RTreeEntry(r1, data='a')
        entry_b = RTreeEntry(r2, data='b')
        entry_c = RTreeEntry(r3, data='c')
        entry_d = RTreeEntry(r4, data='d')
        entry_e = RTreeEntry(r5, data='e')
        n1 = RTreeNode(t,
                       is_leaf=True,
                       parent=t.root,
                       entries=[entry_a, entry_c])
        n2 = RTreeNode(t,
                       is_leaf=True,
                       parent=t.root,
                       entries=[entry_b, entry_d, entry_e])
        e1 = RTreeEntry(Rect(0, 0, 1, 2), child=n1)
        e2 = RTreeEntry(Rect(3, 0, 10, 6), child=n2)
        t.root.entries = [e1, e2]
        # Arrange entry being inserted
        r6 = Rect(2, 1, 3, 2)
        entry_f = RTreeEntry(r6, data='f')
        # Manually insert the new entry into node n2, causing it to be overfull.
        n2.entries.append(entry_f)
        # Ensure preconditions:
        # At this point, the root node entries will still have their old covering rectangles.
        self.assertEqual(Rect(0, 0, 1, 2), e1.rect)
        self.assertEqual(Rect(3, 0, 10, 6), e2.rect)
        # At this point, the root node will only have 2 entries for e1 and e2
        self.assertEqual([e1, e2], t.root.entries)

        # Act
        rstar_overflow(t, n2)

        # Assert
        # Ensure rstar_split was not invoked. In this scenario, it should do a forced reinsert instead (and the reinsert
        # should not result in any additional splits).
        rstar_split_mock.assert_not_called()
        # Ensure the root node still has only 2 entries, and their children are still the nodes n1 and n2.
        self.assertEqual([e1, e2], t.root.entries)
        self.assertEqual(n1, e1.child)
        self.assertEqual(n2, e2.child)
        # Forced insert should have resulted in entry f getting reinserted into node n1 (was previously in n2).
        # Ensure node n1 now has entries [a, c, f].
        self.assertCountEqual([entry_a, entry_c, entry_f], n1.entries)
        # Ensure node n1 bounding box accommodates entries [a, c, f]
        self.assertEqual(Rect(0, 0, 3, 2), n1.get_bounding_rect())
        # Remaining entries [b, d, e] should be in node n2.
        self.assertCountEqual([entry_b, entry_d, entry_e], n2.entries)
        self.assertEqual(Rect(3, 0, 10, 6), n2.get_bounding_rect())
        # Ensure nodes n1 and n2 are leaf nodes, and there are no additional levels in the tree.
        self.assertTrue(n1.is_leaf)
        self.assertTrue(n2.is_leaf)
        self.assertEqual(2, len(t.get_levels()))