PageRenderTime 52ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/libstdc++-v3/doc/html/ext/pb_ds/tree_based_containers.html

https://bitbucket.org/pizzafactory/pf-gcc
HTML | 358 lines | 293 code | 65 blank | 0 comment | 0 complexity | 8a7d24d8198ca69c11413e2063ded906 MD5 | raw file
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <meta name="generator" content=
  6. "HTML Tidy for Linux/x86 (vers 12 April 2005), see www.w3.org" />
  7. <title>Tree-Based Containers</title>
  8. <meta http-equiv="Content-Type" content=
  9. "text/html; charset=us-ascii" />
  10. </head>
  11. <body>
  12. <div id="page">
  13. <h1>Tree Design</h1>
  14. <h2><a name="overview" id="overview">Overview</a></h2>
  15. <p>The tree-based container has the following declaration:</p>
  16. <pre>
  17. <b>template</b>&lt;
  18. <b>typename</b> Key,
  19. <b>typename</b> Mapped,
  20. <b>typename</b> Cmp_Fn = std::less&lt;Key&gt;,
  21. <b>typename</b> Tag = <a href="rb_tree_tag.html">rb_tree_tag</a>,
  22. <b>template</b>&lt;
  23. <b>typename</b> Const_Node_Iterator,
  24. <b>typename</b> Node_Iterator,
  25. <b>typename</b> Cmp_Fn_,
  26. <b>typename</b> Allocator_&gt;
  27. <b>class</b> Node_Update = <a href=
  28. "null_tree_node_update.html">null_tree_node_update</a>,
  29. <b>typename</b> Allocator = std::allocator&lt;<b>char</b>&gt; &gt;
  30. <b>class</b> <a href=
  31. "tree.html">tree</a>;
  32. </pre>
  33. <p>The parameters have the following meaning:</p>
  34. <ol>
  35. <li><tt>Key</tt> is the key type.</li>
  36. <li><tt>Mapped</tt> is the mapped-policy.</li>
  37. <li><tt>Cmp_Fn</tt> is a key comparison functor</li>
  38. <li><tt>Tag</tt> specifies which underlying data structure
  39. to use.</li>
  40. <li><tt>Node_Update</tt> is a policy for updating node
  41. invariants. This is described in <a href="#invariants">Node
  42. Invariants</a>.</li>
  43. <li><tt>Allocator</tt> is an allocator
  44. type.</li>
  45. </ol>
  46. <p>The <tt>Tag</tt> parameter specifies which underlying
  47. data structure to use. Instantiating it by <a href=
  48. "rb_tree_tag.html"><tt>rb_tree_tag</tt></a>, <a href=
  49. "splay_tree_tag.html"><tt>splay_tree_tag</tt></a>, or
  50. <a href="ov_tree_tag.html"><tt>ov_tree_tag</tt></a>,
  51. specifies an underlying red-black tree, splay tree, or
  52. ordered-vector tree, respectively; any other tag is illegal.
  53. Note that containers based on the former two contain more types
  54. and methods than the latter (<i>e.g.</i>,
  55. <tt>reverse_iterator</tt> and <tt>rbegin</tt>), and different
  56. exception and invalidation guarantees.</p>
  57. <h2><a name="invariants" id="invariants">Node
  58. Invariants</a></h2>
  59. <p>Consider the two trees in Figures <a href=
  60. "#node_invariants">Some node invariants</a> A and B. The first
  61. is a tree of floats; the second is a tree of pairs, each
  62. signifying a geometric line interval. Each element in a tree is refered to as a node of the tree. Of course, each of
  63. these trees can support the usual queries: the first can easily
  64. search for <tt>0.4</tt>; the second can easily search for
  65. <tt>std::make_pair(10, 41)</tt>.</p>
  66. <p>Each of these trees can efficiently support other queries.
  67. The first can efficiently determine that the 2rd key in the
  68. tree is <tt>0.3</tt>; the second can efficiently determine
  69. whether any of its intervals overlaps
  70. <tt>std::make_pair(29,42)</tt> (useful in geometric
  71. applications or distributed file systems with leases, for
  72. example). (See <a href=
  73. "http://gcc.gnu.org/viewcvs/*checkout*/trunk/libstdc%2B%2B-v3/testsuite/ext/pb_ds/example/tree_order_statistics.cc"><tt>tree_order_statistics.cc</tt></a>
  74. and <a href=
  75. "http://gcc.gnu.org/viewcvs/*checkout*/trunk/libstdc%2B%2B-v3/testsuite/ext/pb_ds/example/tree_intervals.cc"><tt>tree_intervals.cc</tt></a>
  76. for examples.) It should be noted that an <tt>std::set</tt> can
  77. only solve these types of problems with linear complexity.</p>
  78. <p>In order to do so, each tree stores some <i>metadata</i> in
  79. each node, and maintains node invariants <a href=
  80. "references.html#clrs2001">clrs2001</a>]. The first stores in
  81. each node the size of the sub-tree rooted at the node; the
  82. second stores at each node the maximal endpoint of the
  83. intervals at the sub-tree rooted at the node.</p>
  84. <h6 class="c1"><a name="node_invariants" id=
  85. "node_invariants"><img src="node_invariants.png" alt=
  86. "no image" /></a></h6>
  87. <h6 class="c1">Some node invariants.</h6>
  88. <p>Supporting such trees is difficult for a number of
  89. reasons:</p>
  90. <ol>
  91. <li>There must be a way to specify what a node's metadata
  92. should be (if any).</li>
  93. <li>Various operations can invalidate node invariants.
  94. <i>E.g.</i>, Figure <a href=
  95. "#node_invariant_invalidations">Invalidation of node
  96. invariants</a> shows how a right rotation, performed on A,
  97. results in B, with nodes <i>x</i> and <i>y</i> having
  98. corrupted invariants (the grayed nodes in C); Figure <a href=
  99. "#node_invariant_invalidations">Invalidation of node
  100. invariants</a> shows how an insert, performed on D, results
  101. in E, with nodes <i>x</i> and <i>y</i> having corrupted
  102. invariants (the grayed nodes in F). It is not feasible to
  103. know outside the tree the effect of an operation on the nodes
  104. of the tree.</li>
  105. <li>The search paths of standard associative containers are
  106. defined by comparisons between keys, and not through
  107. metadata.</li>
  108. <li>It is not feasible to know in advance which methods trees
  109. can support. Besides the usual <tt>find</tt> method, the
  110. first tree can support a <tt>find_by_order</tt> method, while
  111. the second can support an <tt>overlaps</tt> method.</li>
  112. </ol>
  113. <h6 class="c1"><a name="node_invariant_invalidations" id=
  114. "node_invariant_invalidations"><img src=
  115. "node_invariant_invalidations.png" alt="no image" /></a></h6>
  116. <h6 class="c1">Invalidation of node invariants.</h6>
  117. <p>These problems are solved by a combination of two means:
  118. node iterators, and template-template node updater
  119. parameters.</p>
  120. <h3><a name="node_it" id="node_it">Node Iterators</a></h3>
  121. <p>Each tree-based container defines two additional iterator
  122. types, <a href=
  123. "tree_const_node_iterator.html"><tt>const_node_iterator</tt></a>
  124. and <a href=
  125. "tree_node_iterator.html"><tt>node_iterator</tt></a>.
  126. These iterators allow descending from a node to one of its
  127. children. Node iterator allow search paths different than those
  128. determined by the comparison functor. <a href=
  129. "tree.html">tree</a>
  130. supports the methods:</p>
  131. <pre>
  132. <a href="tree_const_node_iterator.html"><tt>const_node_iterator</tt></a>
  133. node_begin() <b>const</b>;
  134. <a href="tree_node_iterator.html"><tt>node_iterator</tt></a>
  135. node_begin();
  136. <a href="tree_const_node_iterator.html"><tt>const_node_iterator</tt></a>
  137. node_end() <b>const</b>;
  138. <a href="tree_node_iterator.html"><tt>node_iterator</tt></a>
  139. node_end();
  140. </pre>
  141. <p>The first pairs return node iterators corresponding to the
  142. root node of the tree; the latter pair returns node iterators
  143. corresponding to a just-after-leaf node.</p>
  144. <h3><a name="node_up" id="node_up">Node Updater
  145. (Template-Template) Parameters</a></h3>
  146. <p>The tree-based containers are parametrized by a
  147. <tt>Node_Update</tt> template-template parameter. A tree-based
  148. container instantiates <tt>Node_Update</tt> to some
  149. <tt>node_update</tt> class, and publicly
  150. subclasses <tt>node_update</tt>. Figure
  151. <a href="#tree_node_update_cd">A tree and its update
  152. policy</a> shows this scheme, as well as some predefined
  153. policies (which are explained below).</p>
  154. <h6 class="c1"><a name="tree_node_update_cd" id=
  155. "tree_node_update_cd"><img src=
  156. "tree_node_update_policy_cd.png" alt="no image" /></a></h6>
  157. <h6 class="c1">A tree and its update policy.</h6>
  158. <p><tt>node_update</tt> (an instantiation of
  159. <tt>Node_Update</tt>) must define <tt>metadata_type</tt> as
  160. the type of metadata it requires. For order statistics,
  161. <i>e.g.</i>, <tt>metadata_type</tt> might be <tt>size_t</tt>.
  162. The tree defines within each node a <tt>metadata_type</tt>
  163. object.</p>
  164. <p><tt>node_update</tt> must also define the following method
  165. for restoring node invariants:</p>
  166. <pre>
  167. void
  168. operator()(<a href=
  169. "tree_node_iterator.html"><tt>node_iterator</tt></a> nd_it, <a href=
  170. "tree_const_node_iterator.html"><tt>const_node_iterator</tt></a> end_nd_it)
  171. </pre>
  172. <p>In this method, <tt>nd_it</tt> is a <a href=
  173. "tree_node_iterator.html"><tt>node_iterator</tt></a>
  174. corresponding to a node whose A) all descendants have valid
  175. invariants, and B) its own invariants might be violated;
  176. <tt>end_nd_it</tt> is a <a href=
  177. "tree_const_node_iterator.html"><tt>const_node_iterator</tt></a>
  178. corresponding to a just-after-leaf node. This method should
  179. correct the node invariants of the node pointed to by
  180. <tt>nd_it</tt>. For example, say node <i>x</i> in Figure
  181. <a href="#restoring_node_invariants">Restoring node
  182. invariants</a>-A has an invalid invariant, but its' children,
  183. <i>y</i> and <i>z</i> have valid invariants. After the
  184. invocation, all three nodes should have valid invariants, as in
  185. Figure <a href="#restoring_node_invariants">Restoring node
  186. invariants</a>-B.</p>
  187. <h6 class="c1"><a name="restoring_node_invariants" id=
  188. "restoring_node_invariants"><img src=
  189. "restoring_node_invariants.png" alt="no image" /></a></h6>
  190. <h6 class="c1">Invalidation of node invariants.</h6>
  191. <p>When a tree operation might invalidate some node invariant,
  192. it invokes this method in its <tt>node_update</tt> base to
  193. restore the invariant. For example, Figure <a href=
  194. "#update_seq_diagram">Insert update sequence diagram</a> shows
  195. an <tt>insert</tt> operation (point A); the tree performs some
  196. operations, and calls the update functor three times (points B,
  197. C, and D). (It is well known that any <tt>insert</tt>,
  198. <tt>erase</tt>, <tt>split</tt> or <tt>join</tt>, can restore
  199. all node invariants by a small number of node invariant updates
  200. [<a href="references.html#clrs2001">clrs2001</a>].)</p>
  201. <h6 class="c1"><a name="update_seq_diagram" id=
  202. "update_seq_diagram"><img src="update_seq_diagram.png" alt=
  203. "no image" /></a></h6>
  204. <h6 class="c1">Insert update sequence diagram.</h6>
  205. <p>To complete the description of the scheme, three questions
  206. need to be answered:</p>
  207. <ol>
  208. <li>How can a tree which supports order statistics define a
  209. method such as <tt>find_by_order</tt>?</li>
  210. <li>How can the node updater base access methods of the
  211. tree?</li>
  212. <li>How can the following cyclic dependency be resolved?
  213. <tt>node_update</tt> is a base class of the tree, yet it
  214. uses node iterators defined in the tree (its child).</li>
  215. </ol>
  216. <p>The first two questions are answered by the fact that
  217. <tt>node_update</tt> (an instantiation of
  218. <tt>Node_Update</tt>) is a <tt><b>public</b></tt> base class
  219. of the tree. Consequently:</p>
  220. <ol>
  221. <li>Any public methods of <tt>node_update</tt> are
  222. automatically methods of the tree [<a href=
  223. "references.html#alexandrescu01modern">alexandrescu01modern</a>].
  224. Thus an order-statistics node updater, <a href=
  225. "tree_order_statistics_node_update.html"><tt>tree_order_statistics_node_update</tt></a>
  226. defines the <tt>find_by_order</tt> method; any tree
  227. instantiated by this policy consequently supports this method
  228. as well.</li>
  229. <li>In C++, if a base class declares a method as
  230. <tt><b>virtual</b></tt>, it is <tt><b>virtual</b></tt> in its
  231. subclasses. If <tt>node_update</tt> needs to access one of
  232. the tree's methods, say the member function <tt>end</tt>, it simply
  233. declares that method as <tt><b>virtual</b></tt>
  234. abstract.</li>
  235. </ol>
  236. <p>The cyclic dependency is solved through template-template
  237. parameters. <tt>Node_Update</tt> is parametrized by the tree's node iterators, its comparison
  238. functor, and its allocator type. Thus,
  239. instantiations of <tt>Node_Update</tt> have all information required.</p>
  240. <p class="c1"><tt>pb_ds</tt> assumes that constructing a metadata object and modifying it
  241. are exception free. Suppose that during some method, say
  242. <tt>insert</tt>, a metadata-related operation
  243. (<i>e.g.</i>, changing the value of a metadata) throws an
  244. exception. Ack! Rolling back the method is unusually complex.</p>
  245. <p>In <a href=
  246. "concepts.html#concepts_null_policies">Interface::Concepts::Null
  247. Policy Classes</a> a distinction was made between <i>redundant
  248. policies</i> and <i>null policies</i>. Node invariants show a
  249. case where null policies are required.</p>
  250. <p>Assume a regular tree is required, one which need not
  251. support order statistics or interval overlap queries.
  252. Seemingly, in this case a redundant policy - a policy which
  253. doesn't affect nodes' contents would suffice. This, would lead
  254. to the following drawbacks:</p>
  255. <ol>
  256. <li>Each node would carry a useless metadata object, wasting
  257. space.</li>
  258. <li>The tree cannot know if its <tt>Node_Update</tt> policy
  259. actually modifies a node's metadata (this is halting
  260. reducible). In Figure <a href=
  261. "#rationale_null_node_update">Useless update path</a> ,
  262. assume the shaded node is inserted. The tree would have to
  263. traverse the useless path shown to the root, applying
  264. redundant updates all the way.</li>
  265. </ol>
  266. <h6 class="c1"><a name="rationale_null_node_update" id=
  267. "rationale_null_node_update"><img src=
  268. "rationale_null_node_update.png" alt="no image" /></a></h6>
  269. <h6 class="c1">Useless update path.</h6>
  270. <p>A null policy class, <a href=
  271. "null_tree_node_update.html"><tt>null_tree_node_update</tt></a>
  272. solves both these problems. The tree detects that node
  273. invariants are irrelevant, and defines all accordingly.</p>
  274. <h2><a name="add_methods" id="add_methods">Additional
  275. Methods</a></h2>
  276. <p>Tree-based containers support split and join methods.
  277. It is possible to split a tree so that it passes
  278. all nodes with keys larger than a given key to a different
  279. tree. These methods have the following advantages over the
  280. alternative of externally inserting to the destination
  281. tree and erasing from the source tree:</p>
  282. <ol>
  283. <li>These methods are efficient - red-black trees are split
  284. and joined in poly-logarithmic complexity; ordered-vector
  285. trees are split and joined at linear complexity. The
  286. alternatives have super-linear complexity.</li>
  287. <li>Aside from orders of growth, these operations perform
  288. few allocations and de-allocations. For red-black trees, allocations are not performed,
  289. and the methods are exception-free. </li>
  290. </ol>
  291. </div>
  292. </body>
  293. </html>