libssrckdtree 1.0.8 C++ Unit Test Coverage
Current view: top level - ssrc/spatial - kd_tree.h (source / functions) Hit Total Coverage
Test: libssrckdtree 1.0.8 C++ Unit Tests Lines: 252 256 98.4 %
Date: 2011-06-03 Functions: 120 123 97.6 %
Branches: 487 616 79.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright 2003-2005 Daniel F. Savarese
       3                 :            :  * Copyright 2006-2009 Savarese Software Research Corporation
       4                 :            :  *
       5                 :            :  * Licensed under the Apache License, Version 2.0 (the "License");
       6                 :            :  * you may not use this file except in compliance with the License.
       7                 :            :  * You may obtain a copy of the License at
       8                 :            :  *
       9                 :            :  *     https://www.savarese.com/software/ApacheLicense-2.0
      10                 :            :  *
      11                 :            :  * Unless required by applicable law or agreed to in writing, software
      12                 :            :  * distributed under the License is distributed on an "AS IS" BASIS,
      13                 :            :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14                 :            :  * See the License for the specific language governing permissions and
      15                 :            :  * limitations under the License.
      16                 :            :  */
      17                 :            : 
      18                 :            : /**
      19                 :            :  * @file
      20                 :            :  * This header defines the kd_tree class and its support classes.
      21                 :            :  */
      22                 :            : 
      23                 :            : #ifndef __SSRC_SPATIAL_KDTREE_H
      24                 :            : #define __SSRC_SPATIAL_KDTREE_H
      25                 :            : 
      26                 :            : #include <ssrc/spatial/detail/kd_tree_range_search_iterator.h>
      27                 :            : #include <ssrc/spatial/detail/kd_tree_node.h>
      28                 :            : #include <ssrc/spatial/detail/kd_tree_nearest_neighbor.h>
      29                 :            : 
      30                 :            : #ifdef LIBSSRCKDTREE_HAVE_BOOST
      31                 :            : #include <ssrc/spatial/detail/kd_tree_nearest_neighbors.h>
      32                 :            : #endif
      33                 :            : 
      34                 :            : #include <ssrc/spatial/rectangle_region.h>
      35                 :            : 
      36                 :            : #include <algorithm>
      37                 :            : #include <utility>
      38                 :            : #include <vector>
      39                 :            : 
      40                 :            : __BEGIN_NS_SSRC_SPATIAL
      41                 :            : 
      42                 :            : /**
      43                 :            :  * kd_tree_traits stores metadata about kd_tree instances.
      44                 :            :  */
      45                 :            : template<typename Tree>
      46                 :            : struct kd_tree_traits {
      47                 :            :   typedef typename Tree::key_type key_type;
      48                 :            :   typedef typename Tree::mapped_type mapped_type;
      49                 :            :   typedef typename Tree::value_type value_type;
      50                 :            :   typedef typename Tree::pointer pointer;
      51                 :            :   typedef typename Tree::const_pointer const_pointer;
      52                 :            :   typedef typename Tree::reference reference;
      53                 :            :   typedef typename Tree::const_reference const_reference;
      54                 :            :   typedef typename Tree::discriminator_type discriminator_type;
      55                 :            :   typedef typename Tree::node_type node_type;
      56                 :            :   typedef typename Tree::iterator iterator;
      57                 :            :   typedef typename Tree::const_iterator const_iterator;
      58                 :            :   typedef typename Tree::size_type size_type;
      59                 :            :   typedef typename key_type::value_type coordinate_type;
      60                 :            :   typedef Tree tree_type;
      61                 :            : 
      62                 :            :   /**
      63                 :            :    * Returns the maximum value a coordinate may assume.
      64                 :            :    *
      65                 :            :    * @return The maximum value a coordinate may assume.
      66                 :            :    */
      67                 :          3 :   static const coordinate_type max_coordinate() {
      68                 :          3 :     return detail::coordinate_limits<coordinate_type>::highest();
      69                 :            :   }
      70                 :            : 
      71                 :            :   /**
      72                 :            :    * Returns the minimum value a coordinate may assume.
      73                 :            :    *
      74                 :            :    * @return The minimum value a coordinate may assume.
      75                 :            :    */
      76                 :          3 :   static const coordinate_type min_coordinate() {
      77                 :          3 :     return detail::coordinate_limits<coordinate_type>::lowest();
      78                 :            :   }
      79                 :            : 
      80                 :            :   /** The highest possible key value. */
      81                 :            :   static const key_type upper_bound;
      82                 :            : 
      83                 :            :   /** The lowest possible key value. */
      84                 :            :   static const key_type lower_bound;
      85                 :            : 
      86                 :            :   /** The number of dimensions of a key. */
      87                 :            :   static const unsigned int dimensions = NS_TR1::tuple_size<key_type>::value;
      88                 :            : 
      89                 :            : private:
      90                 :          6 :   static key_type init_point(const coordinate_type & value) {
      91                 :            :     key_type point;
      92 [ +  + ][ +  + ]:         18 :     for(unsigned int i=0; i < dimensions; ++i)
                 [ +  + ]
      93                 :         12 :       point[i] = value;
      94                 :          6 :     return point;
      95                 :            :   }
      96                 :            : 
      97                 :          3 :   static const key_type _upper_bound() {
      98                 :          3 :     return init_point(max_coordinate());
      99                 :            :   }
     100                 :            : 
     101                 :          3 :   static const key_type _lower_bound() {
     102                 :          3 :     return init_point(min_coordinate());
     103                 :            :   }
     104                 :            : };
     105                 :            : 
     106                 :            : template<class Tree>
     107                 :            : typename kd_tree_traits<Tree>::key_type const
     108 [ +  - ][ +  - ]:          3 : kd_tree_traits<Tree>::upper_bound(kd_tree_traits<Tree>::_upper_bound());
                 [ +  - ]
     109                 :            : 
     110                 :            : template<class Tree>
     111                 :            : typename kd_tree_traits<Tree>::key_type const
     112 [ +  - ][ +  - ]:          3 : kd_tree_traits<Tree>::lower_bound(kd_tree_traits<Tree>::_lower_bound());
         [ +  - ][ -  + ]
                 [ #  # ]
     113                 :            : 
     114                 :            : /**
     115                 :            :  * kd_tree_const_traits stores metadata about const kd_tree instances.
     116                 :            :  */
     117                 :            : template<typename Tree>
     118                 :            : struct kd_tree_const_traits : public kd_tree_traits<Tree> {
     119                 :            :   typedef typename Tree::const_pointer pointer;
     120                 :            :   typedef typename Tree::const_reference reference;
     121                 :            : };
     122                 :            : 
     123                 :            : 
     124                 :            : // Note: we store the discriminator in each node to avoid modulo division,
     125                 :            : // trading space for time.
     126                 :            : /**
     127                 :            :  * A k-d tree divides a k-dimensional space relative to the points it
     128                 :            :  * contains by storing them in a binary tree, discriminating by a
     129                 :            :  * different dimension at each level of the tree.  It allows efficient
     130                 :            :  * point data retrieval (<em>O(lg(n))</em>) and range searching.
     131                 :            :  *
     132                 :            :  * <p>kd_tree tries to conform to the map interface from the STL where
     133                 :            :  * it makes sense.  Therefore, you will find it can be used with some
     134                 :            :  * STL algorithms.</p>
     135                 :            :  */
     136                 :            : template<typename Point,
     137                 :            :          typename Value,
     138                 :            :          typename Discriminator = unsigned char,
     139                 :            :          typename Size = unsigned int>
     140                 :            : class kd_tree {
     141                 :            : public:
     142                 :            : 
     143                 :            :   typedef kd_tree_traits<kd_tree> traits;
     144                 :            :   typedef kd_tree_const_traits<kd_tree> const_traits;
     145                 :            :   typedef Point key_type;
     146                 :            :   typedef Value mapped_type;
     147                 :            :   typedef std::pair<const key_type, mapped_type> value_type;
     148                 :            :   typedef value_type* pointer;
     149                 :            :   typedef pointer const const_pointer;
     150                 :            :   typedef value_type& reference;
     151                 :            :   typedef const reference const_reference;
     152                 :            :   typedef Discriminator discriminator_type;
     153                 :            :   typedef rectangle_region<key_type> default_region_type;
     154                 :            :   // Is this really what we want--two distinct types as
     155                 :            :   // opposed to iterator and const iterator?
     156                 :            :   typedef
     157                 :            :   detail::kd_tree_range_search_iterator<traits, default_region_type> iterator;
     158                 :            :   typedef
     159                 :            :   detail::kd_tree_range_search_iterator<const_traits, default_region_type>
     160                 :            :   const_iterator;
     161                 :            : 
     162                 :            :   typedef Size size_type;
     163                 :            : 
     164                 :            :   typedef detail::kd_tree_node<traits> node_type;
     165                 :            : 
     166                 :            : private:
     167                 :            : 
     168                 :            :   struct node_comparator {
     169                 :            :     mutable discriminator_type discriminator;
     170                 :            : 
     171                 :         21 :     explicit node_comparator() : discriminator(0) { }
     172                 :            : 
     173                 :   33267969 :     bool operator()(const node_type* const & n1,
     174                 :            :                     const node_type* const & n2) const
     175                 :            :     {
     176                 :   33267969 :       return (n1->point()[discriminator] < n2->point()[discriminator]);
     177                 :            :     }
     178                 :            :   };
     179                 :            : 
     180                 :            :   node_type *_root;
     181                 :            :   size_type _size;
     182                 :            :   iterator _end_iterator;
     183                 :            :   const_iterator _const_end_iterator;
     184                 :            : 
     185                 :            :   node_type *
     186                 :    1917110 :   get_node(const key_type & point, node_type ** const parent = 0) const {
     187                 :            :     discriminator_type discriminator;
     188                 :    1917110 :     node_type *node = _root, *last = 0;
     189                 :            : 
     190 [ +  + ][ +  + ]:   32481499 :     while(node != 0) {
                 [ +  + ]
     191                 :   31301806 :       discriminator = node->discriminator;
     192                 :            : 
     193 [ +  + ][ +  + ]:   31301806 :       if(point[discriminator] > node->point()[discriminator]) {
                 [ +  + ]
     194                 :   14953399 :         last = node;
     195                 :   14953399 :         node = node->child_high;
     196 [ +  + ][ +  + ]:   16348407 :       } else if(point[discriminator] < node->point()[discriminator]) {
                 [ +  + ]
     197                 :   15596289 :         last = node;
     198                 :   15596289 :         node = node->child_low;
     199 [ +  + ][ +  + ]:     752118 :       } else if(node->point() == point) {
                 [ +  + ]
     200 [ +  + ][ +  + ]:     737417 :         if(parent != 0)
                 [ +  + ]
     201                 :     393350 :           *parent = last;
     202                 :     737417 :         return node;
     203                 :            :       } else {
     204                 :      14701 :         last = node;
     205                 :      14701 :         node = node->child_high;
     206                 :            :       }
     207                 :            :     }
     208                 :            : 
     209 [ +  + ][ +  + ]:    1179693 :     if(parent != 0)
                 [ +  + ]
     210                 :    1179687 :       *parent = last;
     211                 :            : 
     212                 :    1917110 :     return 0;
     213                 :            :   }
     214                 :            : 
     215                 :    5798157 :   node_type * get_minimum_node(node_type * const node, node_type * const p,
     216                 :            :                                const discriminator_type discriminator,
     217                 :            :                                node_type ** const parent)
     218                 :            :   {
     219                 :            :     node_type *result;
     220                 :            : 
     221 [ +  + ][ +  + ]:    5798157 :     if(discriminator == node->discriminator) {
                 [ +  + ]
     222 [ +  + ][ +  + ]:    3442717 :       if(node->child_low != 0)
                 [ +  + ]
     223                 :            :         return
     224                 :            :           get_minimum_node(node->child_low, node,
     225                 :    1634435 :                            discriminator, parent);
     226                 :            :       else
     227                 :    1808282 :         result = node;
     228                 :            :     } else {
     229                 :    2355440 :       node_type *nlow = 0, *nhigh = 0;
     230                 :            :       node_type *plow, *phigh;
     231                 :            : 
     232 [ +  + ][ +  + ]:    2355440 :       if(node->child_low != 0)
                 [ +  + ]
     233                 :    1679175 :         nlow = get_minimum_node(node->child_low, node,
     234                 :            :                                 discriminator, &plow);
     235                 :            : 
     236 [ +  + ][ +  + ]:    2355440 :       if(node->child_high != 0)
                 [ +  + ]
     237                 :    1763542 :         nhigh = get_minimum_node(node->child_high, node,
     238                 :            :                                  discriminator, &phigh);
     239                 :            : 
     240 [ +  + ][ +  + ]:    2355440 :       if(nlow != 0 && nhigh != 0) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     241 [ +  + ][ +  + ]:    3038174 :         if(nlow->point()[discriminator] < nhigh->point()[discriminator]) {
                 [ +  + ]
     242                 :     772614 :           result  = nlow;
     243                 :     772614 :           *parent = plow;
     244                 :            :         } else {
     245                 :     746473 :           result  = nhigh;
     246                 :     746473 :           *parent = phigh;
     247                 :            :         }
     248 [ +  + ][ +  + ]:     836353 :       } else if(nlow != 0) {
                 [ +  + ]
     249                 :     160088 :         result  = nlow;
     250                 :     160088 :         *parent = plow;
     251 [ +  + ][ +  + ]:     676265 :       } else if(nhigh != 0) {
                 [ +  + ]
     252                 :     244455 :         result  = nhigh;
     253                 :     244455 :         *parent = phigh;
     254                 :            :       } else
     255                 :     431810 :         result  = node;
     256                 :            :     }
     257                 :            : 
     258 [ +  + ][ +  + ]:    4163722 :     if(result == node)
                 [ +  + ]
     259                 :    2240092 :       *parent = p;
     260 [ +  + ][ +  + ]:    1923630 :     else if(node->point()[discriminator] < result->point()[discriminator]) {
                 [ +  + ]
     261                 :     229153 :       result  = node;
     262                 :     229153 :       *parent = p;
     263                 :            :     }
     264                 :            : 
     265                 :    5798157 :     return result;
     266                 :            :   }
     267                 :            : 
     268                 :    1065197 :   node_type * recursive_remove_node(node_type * const node) {
     269                 :            :     discriminator_type discriminator;
     270                 :            :     node_type *new_root, *parent;
     271                 :            : 
     272 [ +  + ][ +  + ]:    1065197 :     if(node->child_low == 0 &&
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     273                 :            :        node->child_high == 0)
     274                 :     344192 :       return 0;
     275                 :            :     else
     276                 :     721005 :       discriminator = node->discriminator;
     277                 :            : 
     278 [ +  + ][ +  + ]:     721005 :     if(node->child_high == 0) {
                 [ +  + ]
     279                 :      55049 :       node->child_high = node->child_low;
     280                 :      55049 :       node->child_low  = 0;
     281                 :            :     }
     282                 :            : 
     283                 :     721005 :     new_root = get_minimum_node(node->child_high, node,
     284                 :            :                                 discriminator, &parent);
     285                 :            : 
     286   [ +  +  +  +  :     721005 :     if(parent->child_low == new_root)
                   +  + ]
     287                 :     297204 :       parent->child_low = recursive_remove_node(new_root);
     288                 :            :     else
     289                 :     423801 :       parent->child_high = recursive_remove_node(new_root);
     290                 :            : 
     291                 :     721005 :     new_root->child_low  = node->child_low;
     292                 :     721005 :     new_root->child_high = node->child_high;
     293                 :     721005 :     new_root->discriminator = node->discriminator;
     294                 :            : 
     295                 :    1065197 :     return new_root;
     296                 :            :   }
     297                 :            : 
     298                 :            :   // Splitting up remove in this way allows us to implement
     299                 :            :   // iterator erase(iterator) properly.
     300                 :     344192 :   bool remove(node_type * const node, node_type * const parent) {
     301                 :     344192 :     node_type * const new_root = recursive_remove_node(node);
     302                 :            : 
     303   [ +  +  +  +  :     344192 :     if(parent == 0)
                   +  + ]
     304                 :      98426 :       _root = new_root;
     305 [ +  + ][ +  + ]:     245766 :     else if(node == parent->child_low)
                 [ +  + ]
     306                 :     118186 :       parent->child_low = new_root;
     307                 :            :     else
     308                 :     127580 :       parent->child_high = new_root;
     309                 :            : 
     310                 :            :     // Must zero children so they are not deleted by ~node_type()
     311                 :     344192 :     node->child_low  = 0; 
     312                 :     344192 :     node->child_high = 0;
     313                 :            : 
     314                 :     344192 :     --_size;
     315 [ +  - ][ +  - ]:     344192 :     delete node;
                 [ +  - ]
     316                 :            : 
     317                 :     344192 :     return true;
     318                 :            :   }
     319                 :            : 
     320                 :    1179687 :   bool add(const key_type & point, const mapped_type & value,
     321                 :            :             node_type ** const node, node_type *parent,
     322                 :            :             mapped_type * const replaced = 0)
     323                 :            :   {
     324 [ +  + ][ +  + ]:    1179687 :     if(parent == 0) {
                 [ +  + ]
     325 [ -  + ][ -  + ]:         83 :       if(_root != 0)
                 [ -  + ]
     326                 :          0 :         *node = _root;
     327                 :            :       else {
     328                 :         83 :         _root = *node = new node_type(0, point, value);
     329                 :         83 :         ++_size;
     330                 :         83 :         return false;
     331                 :            :       }
     332 [ +  + ][ +  + ]:    1179604 :     } else if(*node == 0) {
                 [ +  + ]
     333                 :    1179598 :       discriminator_type discriminator = parent->discriminator;
     334                 :            :       node_type* & child =
     335                 :            :         (point[discriminator] >= parent->point()[discriminator] ?
     336 [ +  + ][ +  + ]:    1179598 :          parent->child_high : parent->child_low);
                 [ +  + ]
     337                 :            : 
     338 [ +  + ][ +  + ]:    1179598 :       if(++discriminator >= traits::dimensions)
                 [ +  + ]
     339                 :     588685 :         discriminator = 0;
     340                 :            : 
     341                 :    1179598 :       child = *node = new node_type(discriminator, point, value);
     342                 :            : 
     343                 :    1179598 :       ++_size;
     344                 :    1179598 :       return false;
     345                 :            :     }
     346                 :            : 
     347 [ +  - ][ +  - ]:          6 :     if(replaced != 0)
                 [ +  - ]
     348                 :          6 :       *replaced = (*node)->value();
     349                 :            : 
     350                 :          6 :     (*node)->value() = value;
     351                 :            : 
     352                 :    1179687 :     return true;
     353                 :            :   }
     354                 :            : 
     355                 :            :   template<typename container_iterator>
     356                 :     345807 :   static node_type * optimize(const container_iterator & begin,
     357                 :            :                               const container_iterator & end,
     358                 :            :                               const node_comparator & comparator)
     359                 :            :   {
     360                 :     345807 :     node_type *midpoint = 0;
     361                 :            :     typename container_iterator::difference_type diff;
     362                 :            : 
     363                 :     345807 :     diff = end - begin;
     364                 :            : 
     365   [ +  +  +  +  :     345807 :     if(diff > 1) {
                   +  + ]
     366                 :     172893 :       discriminator_type discriminator = comparator.discriminator;
     367                 :     172893 :       container_iterator nth = begin + (diff >> 1);
     368                 :     172893 :       container_iterator nthprev = nth - 1;
     369                 :            : 
     370                 :            :       //std::nth_element(begin, nth, end, comparator);
     371                 :     172893 :       std::stable_sort(begin, end, comparator);
     372                 :            : 
     373                 :            :       // Ties go in the right subtree.
     374 [ +  + ][ +  + ]:     173796 :       while(nth > begin &&
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     375                 :            :             (*nth)->point()[discriminator] == 
     376                 :            :             (*nthprev)->point()[discriminator])
     377                 :            :         {
     378                 :        903 :           --nth;
     379                 :        903 :           --nthprev;
     380                 :            :         }
     381                 :            : 
     382                 :     172893 :       midpoint = *nth;
     383                 :     172893 :       midpoint->discriminator = discriminator;
     384                 :            : 
     385   [ +  +  +  +  :     172893 :       if(++discriminator >= traits::dimensions)
                   +  + ]
     386                 :      58212 :         discriminator = 0;
     387                 :            : 
     388                 :     172893 :       comparator.discriminator = discriminator;
     389                 :            : 
     390                 :            :       // Left subtree
     391                 :     172893 :       midpoint->child_low = optimize(begin, nth, comparator);
     392                 :            : 
     393                 :     172893 :       comparator.discriminator = discriminator;
     394                 :            : 
     395                 :            :       // Right subtree
     396                 :     172893 :       midpoint->child_high = optimize(nth + 1, end, comparator);
     397 [ +  + ][ +  + ]:     172914 :     } else if(diff == 1) {
                 [ +  + ]
     398                 :     171171 :       midpoint = *begin;
     399                 :     171171 :       midpoint->discriminator = comparator.discriminator;
     400                 :     171171 :       midpoint->child_low = 0;
     401                 :     171171 :       midpoint->child_high = 0;
     402                 :            :     }
     403                 :            : 
     404                 :     345807 :     return midpoint;
     405                 :            :   }
     406                 :            : 
     407                 :            :   template<class container>
     408                 :     688149 :   static void fill_container(container & c, node_type * const node) {
     409 [ +  + ][ +  + ]:     688149 :     if(node == 0)
                 [ +  + ]
     410                 :     688149 :       return;
     411                 :     344064 :     c.push_back(node);
     412                 :     344064 :     fill_container(c, node->child_low);
     413                 :     344064 :     fill_container(c, node->child_high);
     414                 :            :   }
     415                 :            : 
     416                 :            : public:
     417                 :            : 
     418                 :            :   /**
     419                 :            :    * Constructs an empty kd_tree.
     420                 :            :    */
     421                 :         48 :   explicit kd_tree() :
     422 [ +  - ][ +  - ]:         48 :     _root(0), _size(0), _end_iterator(), _const_end_iterator()
                 [ +  - ]
     423                 :         48 :   { }
     424                 :            : 
     425                 :            :   /**
     426                 :            :    * Constructs a copy of a kd_tree.
     427                 :            :    *
     428                 :            :    * @param tree The kd_tree to copy.
     429                 :            :    */
     430                 :          3 :   kd_tree(const kd_tree & tree) :
     431 [ +  - ][ +  - ]:          3 :     _root(0), _size(0), _end_iterator(), _const_end_iterator()
                 [ +  - ]
     432                 :            :   {
     433 [ +  - ][ +  - ]:      49155 :     for(const_iterator p = tree.begin(); !p.end_of_range(); ++p)
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
     434 [ +  - ][ +  - ]:      49152 :       insert(p->first, p->second);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     435                 :          3 :   }
     436                 :            : 
     437                 :            :   /**
     438                 :            :    * Deallocates the memory allocated by the kd_tree.
     439                 :            :    */
     440 [ +  + ][ +  - ]:         51 :   virtual ~kd_tree() { delete _root; }
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
         [ +  - ][ -  + ]
         [ +  + ][ +  - ]
         [ +  - ][ -  + ]
     441                 :            : 
     442                 :            :   /**
     443                 :            :    * Removes all elements from the container, leaving it empty.
     444                 :            :    */
     445                 :         26 :   void clear() {
     446 [ +  - ][ +  - ]:         26 :     delete _root;
                 [ +  - ]
     447                 :         26 :     _root = 0;
     448                 :         26 :     _size = 0;
     449                 :         26 :   }
     450                 :            : 
     451                 :            :   /**
     452                 :            :    * Copies the contents of a kd_tree, destroying all existing
     453                 :            :    * values.
     454                 :            :    *
     455                 :            :    * @param tree The kd_tree to copy.
     456                 :            :    * @return *this
     457                 :            :    */
     458                 :          3 :   kd_tree & operator=(const kd_tree & tree) {
     459                 :          3 :     clear();
     460 [ +  - ][ +  + ]:      49155 :     for(const_iterator p = tree.begin(); !p.end_of_range(); ++p)
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
     461 [ +  - ][ +  - ]:      49152 :       insert(p->first, p->second);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     462                 :          3 :     return *this;
     463                 :            :   }
     464                 :            : 
     465                 :            :   /**
     466                 :            :    * Returns the number of point-value mappings in the kd_tree.
     467                 :            :    *
     468                 :            :    * @return The number of point-value mappings in the kd_tree.
     469                 :            :    */
     470                 :        114 :   const size_type size() const {
     471                 :        114 :     return _size;
     472                 :            :   }
     473                 :            : 
     474                 :            :   /**
     475                 :            :    * Returns the maximum number of elements that can be contained.
     476                 :            :    *
     477                 :            :    * @return The maximum number of elements that can be contained.
     478                 :            :    */
     479                 :          3 :   const size_type max_size() const {
     480                 :          3 :     return std::numeric_limits<size_type>::max();
     481                 :            :   }
     482                 :            : 
     483                 :            :   /**
     484                 :            :    * Returns true if the container has no elements, false if it
     485                 :            :    * contains one or more elements.
     486                 :            :    *
     487                 :            :    * @return true if the container has no elements, false if it
     488                 :            :    * contains one or more elements.
     489                 :            :    */
     490                 :         48 :   bool empty() const {
     491                 :         48 :     return (_root == 0);
     492                 :            :   }
     493                 :            : 
     494                 :            :   /**
     495                 :            :    * Returns an iterator pointing to the leftmost bottommost point in
     496                 :            :    * the container.  If empty, it equals end().
     497                 :            :    *
     498                 :            :    * @return An iterator pointing to the leftmost bottommost point in
     499                 :            :    * the container.  If empty, it equals end().
     500                 :            :    */
     501                 :         27 :   iterator begin() {
     502                 :         27 :     return iterator(default_region_type(traits::lower_bound, traits::upper_bound), _root);
     503                 :            :   }
     504                 :            : 
     505                 :            :   /**
     506                 :            :    * Returns a const iterator pointing to the leftmost bottommost point in
     507                 :            :    * the container.  If empty, it equals end().
     508                 :            :    *
     509                 :            :    * @return A const iterator pointing to the leftmost bottommost point in
     510                 :            :    * the container.  If empty, it equals end().
     511                 :            :    */
     512                 :         15 :   const_iterator begin() const {
     513                 :         15 :     return const_iterator(default_region_type(traits::lower_bound, traits::upper_bound), _root);
     514                 :            :   }
     515                 :            : 
     516                 :            :   /**
     517                 :            :    * Returns an iterator denoting the end of a range.
     518                 :            :    *
     519                 :            :    * @return An iterator denoting the end of a range.
     520                 :            :    */
     521                 :     294968 :   iterator & end() {
     522                 :     294968 :     return _end_iterator;
     523                 :            :   }
     524                 :            : 
     525                 :            :   /**
     526                 :            :    * Returns a const iterator denoting the end of a range.
     527                 :            :    *
     528                 :            :    * @return A const iterator denoting the end of a range.
     529                 :            :    */
     530                 :      98304 :   const const_iterator & end() const {
     531                 :      98304 :     return _const_end_iterator;
     532                 :            :   }
     533                 :            : 
     534                 :            :   /**
     535                 :            :    * Inserts a key value pair, replacing any existing value that may
     536                 :            :    * be present, and optionally retrieving the replaced value.
     537                 :            :    *
     538                 :            :    * @param point The key corresponding to the value to be inserted
     539                 :            :    * @param value The value to be inserted.
     540                 :            :    * @param replaced If you want to retrieve a value that was
     541                 :            :    * replaced, have this parameter point to a valid object to store
     542                 :            :    * the value.  If not, its default value of zero will prevent it
     543                 :            :    * from being retrieved.
     544                 :            :    * @return true if value is replaced, false if not.
     545                 :            :    */
     546                 :     294948 :   bool insert(const key_type & point, const mapped_type & value,
     547                 :            :               mapped_type * const replaced = 0)
     548                 :            :   {
     549                 :            :     node_type *parent;
     550                 :     294948 :     node_type *node = get_node(point, &parent);
     551                 :            : 
     552                 :     294948 :     return add(point, value, &node, parent, replaced);
     553                 :            :   }
     554                 :            : 
     555                 :            :   /**
     556                 :            :    * Inserts a key value pair, but--in conformance with the STL
     557                 :            :    * container interface--doesn't replace any existing value that may
     558                 :            :    * be present.  Note, this method is slower than
     559                 :            :    * bool insert(const key_type &, const mapped_type, mapped_type*)
     560                 :            :    *
     561                 :            :    * @return A pair containing the iterator pointing to the inserted
     562                 :            :    * value and true if the mapping is inserted.  If the value is not
     563                 :            :    * inserted, a pair containing the iterator pointing to the existing
     564                 :            :    * value and false.
     565                 :            :    */
     566                 :      49155 :   std::pair<iterator,bool> insert(const value_type & mapping) {
     567                 :            :     // Ideally, we'd do this all in one step, but that will have
     568                 :            :     // to wait until we optimize the way we handle iterators.
     569                 :            :     mapped_type existing;
     570                 :      49155 :     const bool replaced  = insert(mapping.first, mapping.second, &existing);
     571                 :      98310 :     const iterator value = find(mapping.first);
     572                 :            : 
     573   [ +  +  +  +  :      49155 :     if(replaced)
                   +  + ]
     574                 :          3 :       value._node->value() = existing;
     575                 :            : 
     576 [ +  - ][ +  - ]:      98310 :     return std::pair<iterator,bool>(value,!replaced);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     577                 :            :   }
     578                 :            : 
     579                 :            : 
     580                 :            :   /**
     581                 :            :    * Retrieves the value at the given location.  In conformance with
     582                 :            :    * the STL map interface, if the point key does not occur in the
     583                 :            :    * kd_tree, a new value is inserted and returned using the default
     584                 :            :    * constructor for kd_tree::mapped_type.
     585                 :            :    *
     586                 :            :    * @param point The location from which to retrieve the value.
     587                 :            :    * @return The value at the given location.
     588                 :            :    */
     589                 :     933891 :   mapped_type & operator[](const key_type & point) {
     590                 :            :     node_type *parent;
     591                 :     933891 :     node_type *node = get_node(point, &parent);
     592                 :            : 
     593   [ +  +  +  +  :     933891 :     if(node == 0)
                   +  + ]
     594                 :     884739 :       add(point, mapped_type(), &node, parent);
     595                 :            : 
     596                 :     933891 :     return node->value();
     597                 :            :   }
     598                 :            : 
     599                 :            :   /**
     600                 :            :    * Removes the point-value mapping corresponding to the given point key.
     601                 :            :    * Optionally, retrieves the removed value if a mapping was present.
     602                 :            :    *
     603                 :            :    * @param point The point key of the mapping to remove.
     604                 :            :    * @param erased A pointer to a mapped_type in which to store the
     605                 :            :    * erased value.  This pointer may be null if you do not want to
     606                 :            :    * retrieve the removed value and only want to remove the mapping.
     607                 :            :    * @return true if a mapping was present and removed, false if not.
     608                 :            :    */
     609                 :      98313 :   bool remove(const key_type & point, mapped_type * const erased = 0) {
     610                 :            :     node_type *parent;
     611                 :      98313 :     node_type * const node = get_node(point, &parent);
     612                 :            : 
     613   [ +  +  +  +  :      98313 :     if(node == 0)
                   +  + ]
     614                 :          6 :       return false;
     615                 :            : 
     616 [ +  + ][ +  + ]:      98307 :     if(erased != 0)
                 [ +  + ]
     617                 :      98304 :       *erased = node->value();
     618                 :            : 
     619                 :      98313 :     return remove(node, parent);
     620                 :            :   }
     621                 :            : 
     622                 :            :   /**
     623                 :            :    * Removes the point-value mapping corresponding to the given point key.
     624                 :            :    *
     625                 :            :    * @param point The point key of the mapping to remove.
     626                 :            :    * @return The number of mappings erased (0 or 1).
     627                 :            :    */
     628                 :          9 :   size_type erase(const key_type & point) {
     629                 :          9 :     return remove(point);
     630                 :            :   }
     631                 :            : 
     632                 :            :   /**
     633                 :            :    * Removes the point-value mapping at the specified position.  The
     634                 :            :    * supplied iterator becomes invalid upon a successful erasure.
     635                 :            :    *
     636                 :            :    * @param pos The kd_tree::iterator denoting the location of the mapping.
     637                 :            :    * @return An iterator pointing to the next element after pos in the
     638                 :            :    * range search sequence containing pos.  If no such element exists,
     639                 :            :    * or if the element pointed to by pos is not contained in the tree
     640                 :            :    * (making it impossible to remove from the tree), end() is returned.
     641                 :            :    */
     642                 :     245885 :   iterator erase(iterator pos) {
     643 [ -  + ][ -  + ]:     245885 :     if(pos.end_of_range())
                 [ -  + ]
     644                 :          0 :       return _end_iterator;
     645                 :            : 
     646                 :            :     node_type *parent;
     647                 :     245885 :     node_type * const node = get_node(pos->first, &parent);
     648                 :            :     
     649   [ -  +  -  +  :     245885 :     if(node == 0)
                   -  + ]
     650                 :          0 :       return _end_iterator;
     651                 :            : 
     652                 :     245885 :     typename iterator::stack_type & stack = pos._stack;
     653                 :            : 
     654                 :            :     // Pop any children.  Tree at parent and above is unchanged.
     655                 :            :     // Low child is pushed last so check it first.
     656 [ +  + ][ +  + ]:     245885 :     if(!stack.empty() && node->child_low == stack.top()) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     657                 :      55931 :       stack.pop();
     658                 :            :     }
     659 [ +  + ][ +  + ]:     245885 :     if(!stack.empty() && node->child_high == stack.top()) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
                 [ +  + ]
     660                 :     187908 :       stack.pop();
     661                 :            :     }
     662                 :            : 
     663 [ +  + ][ +  + ]:     245885 :     const bool low_child = (parent != 0 && parent->child_low == node);
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     664                 :            : 
     665 [ +  - ][ +  - ]:     245885 :     if(remove(node, parent)) {
                 [ +  - ]
     666 [ +  + ][ +  + ]:     245885 :       if(parent != 0) {
                 [ +  + ]
     667 [ +  + ][ +  + ]:     147516 :         if(low_child && parent->child_low != 0) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     668                 :      52198 :           stack.push(parent->child_low);
     669 [ +  + ][ +  + ]:      95318 :         } else if(!low_child && parent->child_high != 0) {
         [ +  + ][ +  + ]
         [ +  + ][ +  + ]
     670                 :      55467 :           stack.push(parent->child_high);
     671                 :            :         }
     672                 :     147516 :         pos.advance();
     673                 :     147516 :         return pos;
     674 [ +  + ][ +  + ]:      98369 :       } else if(_root != 0) {
                 [ +  + ]
     675                 :      98357 :         stack.push(_root);
     676                 :      98357 :         pos.advance();
     677                 :      98357 :         return pos;
     678                 :            :       }
     679                 :            :     }
     680                 :            : 
     681                 :     245885 :     return _end_iterator;
     682                 :            :   }
     683                 :            : 
     684                 :            :   /**
     685                 :            :    * Returns an iterator for mappings that are contained in the
     686                 :            :    * rectangle defined by the given lower left-hand and upper
     687                 :            :    * right-hand corners.  The mappings returned include those occuring
     688                 :            :    * at points on the bounding rectangle, not just those inside.
     689                 :            :    *
     690                 :            :    * @param lower The lower left-hand corner of the bounding
     691                 :            :    * rectangle.
     692                 :            :    * @param upper The upper right-hand corner of the bounding
     693                 :            :    * rectangle.
     694                 :            :    * @return A kd_tree::iterator for mappings that are contained in the
     695                 :            :    * specified rectangle.
     696                 :            :    */
     697                 :          6 :   iterator begin(const key_type & lower, const key_type & upper) {
     698                 :          6 :     return iterator(default_region_type(lower, upper), _root);
     699                 :            :   }
     700                 :            : 
     701                 :            :   /**
     702                 :            :    * Returns a const iterator for mappings that are contained in the
     703                 :            :    * rectangle defined by the given lower left-hand and upper
     704                 :            :    * right-hand corners.  The mappings returned include those occuring
     705                 :            :    * at points on the bounding rectangle, not just those inside.
     706                 :            :    *
     707                 :            :    * @param lower The lower left-hand corner of the bounding
     708                 :            :    * rectangle.
     709                 :            :    * @param upper The upper right-hand corner of the bounding
     710                 :            :    * rectangle.
     711                 :            :    * @return A kd_tree::const_iterator for mappings that are contained in the
     712                 :            :    * specified rectangle.
     713                 :            :    */
     714                 :            :   const_iterator begin(const key_type & lower, const key_type & upper) const {
     715                 :            :     return const_iterator(default_region_type(lower, upper), _root);
     716                 :            :   }
     717                 :            : 
     718                 :            :   // TODO: Document these.  Implement circle_region and sphere_region
     719                 :            :   // and write unit tests.  Move kd_tree_range_search_iterator out of detail.
     720                 :            :   template<typename Region>
     721                 :            :   detail::kd_tree_range_search_iterator<traits, Region>
     722                 :            :   begin(const Region & region) {
     723                 :            :     return
     724                 :            :       detail::kd_tree_range_search_iterator<traits, Region>(region, _root);
     725                 :            :   }
     726                 :            : 
     727                 :            :   template<typename Region>
     728                 :            :   detail::kd_tree_range_search_iterator<traits, Region> end() {
     729                 :            :     return detail::kd_tree_range_search_iterator<traits, Region>();
     730                 :            :   }
     731                 :            : 
     732                 :            :   template<typename Region>
     733                 :            :   detail::kd_tree_range_search_iterator<const_traits, Region>
     734                 :            :   begin(const Region & region) const {
     735                 :            :     return
     736                 :            :       detail::kd_tree_range_search_iterator<const_traits, Region>(region, _root);
     737                 :            :   }
     738                 :            : 
     739                 :            :   template<typename Region>
     740                 :            :   detail::kd_tree_range_search_iterator<const_traits, Region> end() const {
     741                 :            :     return detail::kd_tree_range_search_iterator<const_traits, Region>();
     742                 :            :   }
     743                 :            : 
     744                 :            :   /**
     745                 :            :    * Returns true if the kd_tree contains a point-value mapping for the
     746                 :            :    * specified point, false if not.  Optionally, retrieves the value
     747                 :            :    * at the given location (faster than find()).
     748                 :            :    *
     749                 :            :    * @param point The location from which to retrieve the value.
     750                 :            :    * @param value A pointer to a kd_tree::mapped_type in which to store the
     751                 :            :    * retrieved value.  This pointer may be null if you do not want to
     752                 :            :    * retrieve the value and only want to see if the point is present in
     753                 :            :    * the kd_tree.
     754                 :            :    * @return true if the kd_tree contains a point-value mapping for the
     755                 :            :    * specified point, false if not.
     756                 :            :    */
     757                 :     344073 :   bool get(const key_type & point, mapped_type * const value = 0) const {
     758                 :     344073 :     const node_type * const node = get_node(point);
     759                 :            : 
     760   [ +  +  +  +  :     344073 :     if(node == 0)
                   +  + ]
     761                 :          6 :       return false;
     762 [ +  + ][ +  + ]:     344067 :     else if(value != 0)
                 [ +  + ]
     763                 :     245763 :       *value = node->value();
     764                 :            : 
     765                 :     344073 :     return true;
     766                 :            :   }
     767                 :            : 
     768                 :            :   /**
     769                 :            :    * Returns the location of the point-value mapping for the specified
     770                 :            :    * point (slower than get()).  If there is no mapping present, the
     771                 :            :    * iterator is equivalent to end().
     772                 :            :    *
     773                 :            :    * @param point The key of the poinit-value mapping to find.
     774                 :            :    * @return A kd_tree::iterator for the location of the
     775                 :            :    * point-value mapping matching the specified point.  end() if there
     776                 :            :    * is no mapping.
     777                 :            :    */
     778                 :     245769 :   iterator find(const key_type & point) {
     779                 :     245769 :     return iterator(default_region_type(point, traits::upper_bound), _root, true);
     780                 :            :   }
     781                 :            : 
     782                 :            :   /**
     783                 :            :    * Returns the location of the point-value mapping for the specified
     784                 :            :    * point (slower than get()).  If there is no mapping present, the
     785                 :            :    * iterator is equivalent to end().
     786                 :            :    *
     787                 :            :    * @param point The key of the poinit-value mapping to find.
     788                 :            :    * @return A kd_tree::const_iterator for the location of the
     789                 :            :    * point-value mapping matching the specified point.  end() if there
     790                 :            :    * is no mapping.
     791                 :            :    */
     792                 :      98304 :   const_iterator find(const key_type & point) const {
     793                 :            :     return const_iterator(default_region_type(point, traits::upper_bound),
     794                 :      98304 :                           _root, true);
     795                 :            :   }
     796                 :            : 
     797                 :            :   /**
     798                 :            :    * Optimizes the performance of future search operations by balancing the
     799                 :            :    * kd_tree.  The balancing operation is relatively expensive, but can
     800                 :            :    * significantly improve the performance of searches.  Usually, you
     801                 :            :    * don't have to optimize a tree which contains random key values
     802                 :            :    * inserted in a random order.
     803                 :            :    */
     804                 :         21 :   void optimize() {
     805 [ -  + ][ -  + ]:         21 :     if(empty())
                 [ -  + ]
     806                 :         21 :       return;
     807                 :            : 
     808                 :            :     typedef std::vector<node_type*> container;
     809                 :         42 :     container nodes;
     810                 :            : 
     811   [ +  -  +  -  :         21 :     nodes.reserve(size());
                   +  - ]
     812 [ +  - ][ +  - ]:         21 :     fill_container(nodes, _root);
                 [ +  - ]
     813                 :            : 
     814 [ +  - ][ +  - ]:         21 :     _root = optimize(nodes.begin(), nodes.end(), node_comparator());
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
                 [ +  - ]
     815                 :            :   }
     816                 :            : 
     817                 :            :   /**
     818                 :            :    * Tests if two kd_tree instances contain exactly the same key-value
     819                 :            :    * pairs, but not necessarily in the same hierarchical arrangement.
     820                 :            :    * Note, this is an expensive operation that we don't expect will ever
     821                 :            :    * be used except in support of unit tests.
     822                 :            :    *
     823                 :            :    * Use namespace std::rel_ops from &lt;utility&gt; to gain the != operator.
     824                 :            :    *
     825                 :            :    * @param tree1 The first tree to compare.
     826                 :            :    * @param tree2 The second tree to compare.
     827                 :            :    * @return true if the two trees are equal, false if not.
     828                 :            :    */
     829                 :         15 :   friend bool operator==(const kd_tree & tree1, const kd_tree & tree2) {
     830 [ +  + ][ +  + ]:         15 :     if(tree1.size() != tree2.size())
                 [ +  + ]
     831                 :          6 :       return false;
     832                 :            : 
     833                 :            :     mapped_type value;
     834                 :            : 
     835 [ +  - ][ +  + ]:     147465 :     for(const_iterator p = tree2.begin(); !p.end_of_range(); ++p) {
         [ +  - ][ +  - ]
         [ +  + ][ +  - ]
         [ +  - ][ +  + ]
                 [ +  - ]
     836 [ +  - ][ +  - ]:     147456 :       if(!tree1.get(p->first, &value) || value != p->second)
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
     837                 :          0 :         return false;
     838                 :            :     }
     839                 :            : 
     840                 :         15 :     return true;
     841                 :            :   }
     842                 :            : 
     843                 :            :   // Experimental functions whose API may change or may become standalone
     844                 :            :   // functions or functor classes.
     845                 :            : 
     846                 :            :   /**
     847                 :            :    * Returns the location of the point-value mapping closest to the
     848                 :            :    * specified point in Euclidean space where the Euclidean distance
     849                 :            :    * between the points is non-zero (unless omit_query_point is set to
     850                 :            :    * false).  If there is more than one mapping at the same closest
     851                 :            :    * distance, one of the mappings will be returned, but which mapping
     852                 :            :    * is returned is unspecified.
     853                 :            :    *
     854                 :            :    * Note, this implementation is efficient for low dimensionalities.
     855                 :            :    * High-dimensional data is better served by an approximation algorithm.
     856                 :            :    * An approximation algorithm for high-dimensional data will be provided
     857                 :            :    * in a future release after a satisfactory refactoring is achieved to
     858                 :            :    * separate specialized search algorithms from the kd_tree class template.
     859                 :            :    *
     860                 :            :    * @param point The nearest neighbor query point.
     861                 :            :    * @param omit_query_point If true, mappings at a distance of zero are
     862                 :            :    *        omitted from the result.  If false, mappings at a distance of
     863                 :            :    *        zero are included.  The default value of this parameter is
     864                 :            :    *        true because our most common usage is to search for neighbors
     865                 :            :    *        of points already contained in the tree.
     866                 :            :    * @return A kd_tree::iterator for the location of the point-value
     867                 :            :    * mapping closest to the query point.  end() if there is no such
     868                 :            :    * mapping (e.g., the tree is empty).
     869                 :            :    */
     870                 :         23 :   iterator find_nearest_neighbor(const key_type & point,
     871                 :            :                                  const bool omit_query_point = true)
     872                 :            :   {
     873                 :         23 :     const detail::kd_tree_nearest_neighbor<traits, double> nn;
     874                 :         23 :     return iterator(nn.find(_root, point, omit_query_point));
     875                 :            :   }
     876                 :            : 
     877                 :            : #ifdef LIBSSRCKDTREE_HAVE_BOOST
     878                 :            :   typedef
     879                 :            :   typename detail::kd_tree_nearest_neighbors<traits, double>::iterator
     880                 :            :   knn_iterator;
     881                 :            : 
     882                 :            :   /**
     883                 :            :    * Returns the k-nearest neighbors to a query point as a pair of
     884                 :            :    * iterators that traverse the point-value mappings in order from
     885                 :            :    * closest to farthest.
     886                 :            :    *
     887                 :            :    * @param point The nearest neighbor query point.
     888                 :            :    * @param num_neighbors The number of neighbors to return.
     889                 :            :    * @param omit_query_point If true, mappings at a distance of zero are
     890                 :            :    *        omitted from the result.  If false, mappings at a distance of
     891                 :            :    *        zero are included.  The default value of this parameter is
     892                 :            :    *        true because our most common usage is to search for neighbors
     893                 :            :    *        of points already contained in the tree.
     894                 :            :    * @return A std::pair of kd_tree::knn_iterator instances that can
     895                 :            :    * be traversed to access the nearest neighbor point-value mappings
     896                 :            :    * in order from closest to farthest.  The first iterator marks the
     897                 :            :    * beginning of the range and and the second iterator bounds the
     898                 :            :    * end of the range.
     899                 :            :    */
     900                 :            :   std::pair<knn_iterator, knn_iterator>
     901                 :         82 :   find_nearest_neighbors(const key_type & point,
     902                 :            :                          const unsigned int num_neighbors,
     903                 :            :                          const bool omit_query_point = true)
     904                 :            :   {
     905                 :         82 :     const detail::kd_tree_nearest_neighbors<traits, double> knn;
     906 [ +  - ][ +  - ]:         82 :     return knn.find(_root, point, num_neighbors, omit_query_point);
                 [ +  - ]
     907                 :            :   }
     908                 :            : #endif
     909                 :            : 
     910                 :            : };
     911                 :            : 
     912                 :            : __END_NS_SSRC_SPATIAL
     913                 :            : 
     914                 :            : #endif