PODIntervalTree.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (C) 2010 Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef PODIntervalTree_h
  26. #define PODIntervalTree_h
  27. #include "PODArena.h"
  28. #include "PODInterval.h"
  29. #include "PODRedBlackTree.h"
  30. #include <wtf/Assertions.h>
  31. #include <wtf/Noncopyable.h>
  32. #include <wtf/Vector.h>
  33. namespace WebCore {
  34. #ifndef NDEBUG
  35. template<class T>
  36. struct ValueToString;
  37. #endif
  38. template <class T, class UserData = void*>
  39. class PODIntervalSearchAdapter {
  40. public:
  41. typedef PODInterval<T, UserData> IntervalType;
  42. PODIntervalSearchAdapter(Vector<IntervalType>& result, const T& lowValue, const T& highValue)
  43. : m_result(result)
  44. , m_lowValue(lowValue)
  45. , m_highValue(highValue)
  46. {
  47. }
  48. const T& lowValue() const { return m_lowValue; }
  49. const T& highValue() const { return m_highValue; }
  50. void collectIfNeeded(const IntervalType& data) const
  51. {
  52. if (data.overlaps(m_lowValue, m_highValue))
  53. m_result.append(data);
  54. }
  55. private:
  56. Vector<IntervalType>& m_result;
  57. T m_lowValue;
  58. T m_highValue;
  59. };
  60. // An interval tree, which is a form of augmented red-black tree. It
  61. // supports efficient (O(lg n)) insertion, removal and querying of
  62. // intervals in the tree.
  63. template<class T, class UserData = void*>
  64. class PODIntervalTree : public PODRedBlackTree<PODInterval<T, UserData> > {
  65. WTF_MAKE_NONCOPYABLE(PODIntervalTree);
  66. public:
  67. // Typedef to reduce typing when declaring intervals to be stored in
  68. // this tree.
  69. typedef PODInterval<T, UserData> IntervalType;
  70. typedef PODIntervalSearchAdapter<T, UserData> IntervalSearchAdapterType;
  71. PODIntervalTree(UninitializedTreeEnum unitializedTree)
  72. : PODRedBlackTree<IntervalType>(unitializedTree)
  73. {
  74. init();
  75. }
  76. PODIntervalTree()
  77. : PODRedBlackTree<IntervalType>()
  78. {
  79. init();
  80. }
  81. explicit PODIntervalTree(PassRefPtr<PODArena> arena)
  82. : PODRedBlackTree<IntervalType>(arena)
  83. {
  84. init();
  85. }
  86. // Returns all intervals in the tree which overlap the given query
  87. // interval. The returned intervals are sorted by increasing low
  88. // endpoint.
  89. Vector<IntervalType> allOverlaps(const IntervalType& interval) const
  90. {
  91. Vector<IntervalType> result;
  92. allOverlaps(interval, result);
  93. return result;
  94. }
  95. // Returns all intervals in the tree which overlap the given query
  96. // interval. The returned intervals are sorted by increasing low
  97. // endpoint.
  98. void allOverlaps(const IntervalType& interval, Vector<IntervalType>& result) const
  99. {
  100. // Explicit dereference of "this" required because of
  101. // inheritance rules in template classes.
  102. IntervalSearchAdapterType adapter(result, interval.low(), interval.high());
  103. searchForOverlapsFrom<IntervalSearchAdapterType>(this->root(), adapter);
  104. }
  105. template <class AdapterType>
  106. void allOverlapsWithAdapter(AdapterType& adapter) const
  107. {
  108. // Explicit dereference of "this" required because of
  109. // inheritance rules in template classes.
  110. searchForOverlapsFrom<AdapterType>(this->root(), adapter);
  111. }
  112. // Helper to create interval objects.
  113. static IntervalType createInterval(const T& low, const T& high, const UserData data = 0)
  114. {
  115. return IntervalType(low, high, data);
  116. }
  117. virtual bool checkInvariants() const
  118. {
  119. if (!PODRedBlackTree<IntervalType>::checkInvariants())
  120. return false;
  121. if (!this->root())
  122. return true;
  123. return checkInvariantsFromNode(this->root(), 0);
  124. }
  125. private:
  126. typedef typename PODRedBlackTree<IntervalType>::Node IntervalNode;
  127. // Initializes the tree.
  128. void init()
  129. {
  130. // Explicit dereference of "this" required because of
  131. // inheritance rules in template classes.
  132. this->setNeedsFullOrderingComparisons(true);
  133. }
  134. // Starting from the given node, adds all overlaps with the given
  135. // interval to the result vector. The intervals are sorted by
  136. // increasing low endpoint.
  137. template <class AdapterType>
  138. void searchForOverlapsFrom(IntervalNode* node, AdapterType& adapter) const
  139. {
  140. if (!node)
  141. return;
  142. // Because the intervals are sorted by left endpoint, inorder
  143. // traversal produces results sorted as desired.
  144. // See whether we need to traverse the left subtree.
  145. IntervalNode* left = node->left();
  146. if (left
  147. // This is phrased this way to avoid the need for operator
  148. // <= on type T.
  149. && !(left->data().maxHigh() < adapter.lowValue()))
  150. searchForOverlapsFrom<AdapterType>(left, adapter);
  151. // Check for overlap with current node.
  152. adapter.collectIfNeeded(node->data());
  153. // See whether we need to traverse the right subtree.
  154. // This is phrased this way to avoid the need for operator <=
  155. // on type T.
  156. if (!(adapter.highValue() < node->data().low()))
  157. searchForOverlapsFrom<AdapterType>(node->right(), adapter);
  158. }
  159. virtual bool updateNode(IntervalNode* node)
  160. {
  161. // Would use const T&, but need to reassign this reference in this
  162. // function.
  163. const T* curMax = &node->data().high();
  164. IntervalNode* left = node->left();
  165. if (left) {
  166. if (*curMax < left->data().maxHigh())
  167. curMax = &left->data().maxHigh();
  168. }
  169. IntervalNode* right = node->right();
  170. if (right) {
  171. if (*curMax < right->data().maxHigh())
  172. curMax = &right->data().maxHigh();
  173. }
  174. // This is phrased like this to avoid needing operator!= on type T.
  175. if (!(*curMax == node->data().maxHigh())) {
  176. node->data().setMaxHigh(*curMax);
  177. return true;
  178. }
  179. return false;
  180. }
  181. bool checkInvariantsFromNode(IntervalNode* node, T* currentMaxValue) const
  182. {
  183. // These assignments are only done in order to avoid requiring
  184. // a default constructor on type T.
  185. T leftMaxValue(node->data().maxHigh());
  186. T rightMaxValue(node->data().maxHigh());
  187. IntervalNode* left = node->left();
  188. IntervalNode* right = node->right();
  189. if (left) {
  190. if (!checkInvariantsFromNode(left, &leftMaxValue))
  191. return false;
  192. }
  193. if (right) {
  194. if (!checkInvariantsFromNode(right, &rightMaxValue))
  195. return false;
  196. }
  197. if (!left && !right) {
  198. // Base case.
  199. if (currentMaxValue)
  200. *currentMaxValue = node->data().high();
  201. return (node->data().high() == node->data().maxHigh());
  202. }
  203. T localMaxValue(node->data().maxHigh());
  204. if (!left || !right) {
  205. if (left)
  206. localMaxValue = leftMaxValue;
  207. else
  208. localMaxValue = rightMaxValue;
  209. } else
  210. localMaxValue = (leftMaxValue < rightMaxValue) ? rightMaxValue : leftMaxValue;
  211. if (localMaxValue < node->data().high())
  212. localMaxValue = node->data().high();
  213. if (!(localMaxValue == node->data().maxHigh())) {
  214. #ifndef NDEBUG
  215. String localMaxValueString = ValueToString<T>::string(localMaxValue);
  216. LOG_ERROR("PODIntervalTree verification failed at node 0x%p: localMaxValue=%s and data=%s",
  217. node, localMaxValueString.utf8().data(), node->data().toString().utf8().data());
  218. #endif
  219. return false;
  220. }
  221. if (currentMaxValue)
  222. *currentMaxValue = localMaxValue;
  223. return true;
  224. }
  225. };
  226. #ifndef NDEBUG
  227. // Support for printing PODIntervals at the PODRedBlackTree level.
  228. template<class T, class UserData>
  229. struct ValueToString<PODInterval<T, UserData> > {
  230. static String string(const PODInterval<T, UserData>& interval)
  231. {
  232. return interval.toString();
  233. }
  234. };
  235. #endif
  236. } // namespace WebCore
  237. #endif // PODIntervalTree_h