File indexing completed on 2025-01-18 09:38:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
0018 #define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
0019
0020 #include <boost/intrusive/detail/config_begin.hpp>
0021 #include <boost/intrusive/intrusive_fwd.hpp>
0022
0023 #include <cstddef>
0024 #include <boost/intrusive/detail/algo_type.hpp>
0025 #include <boost/intrusive/bstree_algorithms.hpp>
0026
0027 #if defined(BOOST_HAS_PRAGMA_ONCE)
0028 # pragma once
0029 #endif
0030
0031 namespace boost {
0032 namespace intrusive {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 template<class NodeTraits>
0060 class sgtree_algorithms
0061 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0062 : public bstree_algorithms<NodeTraits>
0063 #endif
0064 {
0065 public:
0066 typedef typename NodeTraits::node node;
0067 typedef NodeTraits node_traits;
0068 typedef typename NodeTraits::node_ptr node_ptr;
0069 typedef typename NodeTraits::const_node_ptr const_node_ptr;
0070
0071
0072 private:
0073
0074 typedef bstree_algorithms<NodeTraits> bstree_algo;
0075
0076
0077
0078 public:
0079
0080
0081 struct insert_commit_data
0082 : bstree_algo::insert_commit_data
0083 {
0084 std::size_t depth;
0085 };
0086
0087 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0088
0089 static node_ptr get_header(const_node_ptr n) BOOST_NOEXCEPT;
0090
0091
0092 static node_ptr begin_node(const_node_ptr header) BOOST_NOEXCEPT;
0093
0094
0095 static node_ptr end_node(const_node_ptr header) BOOST_NOEXCEPT;
0096
0097
0098 static void swap_tree(node_ptr header1, node_ptr header2) BOOST_NOEXCEPT;
0099
0100
0101 static void swap_nodes(node_ptr node1, node_ptr node2) BOOST_NOEXCEPT;
0102
0103
0104 static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2) BOOST_NOEXCEPT;
0105
0106
0107 static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node) BOOST_NOEXCEPT;
0108
0109
0110 static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node) BOOST_NOEXCEPT;
0111
0112
0113
0114
0115
0116 static node_ptr unlink_leftmost_without_rebalance(node_ptr header) BOOST_NOEXCEPT;
0117
0118
0119 static bool unique(const_node_ptr n) BOOST_NOEXCEPT;
0120
0121
0122 static std::size_t size(const_node_ptr header) BOOST_NOEXCEPT;
0123
0124
0125 static node_ptr next_node(node_ptr n) BOOST_NOEXCEPT;
0126
0127
0128 static node_ptr prev_node(node_ptr n) BOOST_NOEXCEPT;
0129
0130
0131 static void init(node_ptr n) BOOST_NOEXCEPT;
0132
0133
0134 static void init_header(node_ptr header) BOOST_NOEXCEPT;
0135 #endif
0136
0137
0138 template<class AlphaByMaxSize>
0139 static node_ptr erase(node_ptr header, node_ptr z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize)
0140 {
0141 bstree_algo::erase(header, z);
0142 --tree_size;
0143 if (tree_size > 0 &&
0144 tree_size < static_cast<std::size_t>(alpha_by_maxsize(max_tree_size))){
0145 bstree_algo::rebalance(header);
0146 max_tree_size = tree_size;
0147 }
0148 return z;
0149 }
0150
0151 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0152
0153 template <class Cloner, class Disposer>
0154 static void clone
0155 (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer);
0156
0157
0158 template<class Disposer>
0159 static void clear_and_dispose(node_ptr header, Disposer disposer) BOOST_NOEXCEPT;
0160
0161
0162 template<class KeyType, class KeyNodePtrCompare>
0163 static node_ptr lower_bound
0164 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0165
0166
0167 template<class KeyType, class KeyNodePtrCompare>
0168 static node_ptr upper_bound
0169 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0170
0171
0172 template<class KeyType, class KeyNodePtrCompare>
0173 static node_ptr find
0174 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0175
0176
0177 template<class KeyType, class KeyNodePtrCompare>
0178 static std::pair<node_ptr, node_ptr> equal_range
0179 (const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0180
0181
0182 template<class KeyType, class KeyNodePtrCompare>
0183 static std::pair<node_ptr, node_ptr> bounded_range
0184 (const_node_ptr header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
0185 , bool left_closed, bool right_closed);
0186
0187
0188 template<class KeyType, class KeyNodePtrCompare>
0189 static std::size_t count(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp);
0190
0191 #endif
0192
0193
0194 template<class NodePtrCompare, class H_Alpha>
0195 static node_ptr insert_equal_upper_bound
0196 (node_ptr h, node_ptr new_node, NodePtrCompare comp
0197 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
0198 {
0199 std::size_t depth;
0200 bstree_algo::insert_equal_upper_bound(h, new_node, comp, &depth);
0201 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0202 return new_node;
0203 }
0204
0205
0206 template<class NodePtrCompare, class H_Alpha>
0207 static node_ptr insert_equal_lower_bound
0208 (node_ptr h, node_ptr new_node, NodePtrCompare comp
0209 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
0210 {
0211 std::size_t depth;
0212 bstree_algo::insert_equal_lower_bound(h, new_node, comp, &depth);
0213 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0214 return new_node;
0215 }
0216
0217
0218 template<class NodePtrCompare, class H_Alpha>
0219 static node_ptr insert_equal
0220 (node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp
0221 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
0222 {
0223 std::size_t depth;
0224 bstree_algo::insert_equal(header, hint, new_node, comp, &depth);
0225 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0226 return new_node;
0227 }
0228
0229
0230 template<class H_Alpha>
0231 static node_ptr insert_before
0232 (node_ptr header, node_ptr pos, node_ptr new_node
0233 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
0234 {
0235 std::size_t depth;
0236 bstree_algo::insert_before(header, pos, new_node, &depth);
0237 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0238 return new_node;
0239 }
0240
0241
0242 template<class H_Alpha>
0243 static void push_back(node_ptr header, node_ptr new_node
0244 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
0245 {
0246 std::size_t depth;
0247 bstree_algo::push_back(header, new_node, &depth);
0248 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0249 }
0250
0251
0252 template<class H_Alpha>
0253 static void push_front(node_ptr header, node_ptr new_node
0254 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
0255 {
0256 std::size_t depth;
0257 bstree_algo::push_front(header, new_node, &depth);
0258 rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
0259 }
0260
0261
0262 template<class KeyType, class KeyNodePtrCompare>
0263 static std::pair<node_ptr, bool> insert_unique_check
0264 (const_node_ptr header, const KeyType &key
0265 ,KeyNodePtrCompare comp, insert_commit_data &commit_data)
0266 {
0267 std::size_t depth;
0268 std::pair<node_ptr, bool> ret =
0269 bstree_algo::insert_unique_check(header, key, comp, commit_data, &depth);
0270 commit_data.depth = depth;
0271 return ret;
0272 }
0273
0274
0275 template<class KeyType, class KeyNodePtrCompare>
0276 static std::pair<node_ptr, bool> insert_unique_check
0277 (const_node_ptr header, node_ptr hint, const KeyType &key
0278 ,KeyNodePtrCompare comp, insert_commit_data &commit_data)
0279 {
0280 std::size_t depth;
0281 std::pair<node_ptr, bool> ret =
0282 bstree_algo::insert_unique_check
0283 (header, hint, key, comp, commit_data, &depth);
0284 commit_data.depth = depth;
0285 return ret;
0286 }
0287
0288
0289 template<class H_Alpha>
0290 BOOST_INTRUSIVE_FORCEINLINE static void insert_unique_commit
0291 (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data
0292 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
0293 { return insert_commit(header, new_value, commit_data, tree_size, h_alpha, max_tree_size); }
0294
0295
0296 template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize>
0297 static bool transfer_unique
0298 ( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size
0299 , node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size
0300 ,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize)
0301 {
0302 insert_commit_data commit_data;
0303 bool const transferable = insert_unique_check(header1, z, comp, commit_data).second;
0304 if(transferable){
0305 erase(header2, z, tree2_size, max_tree2_size, alpha_by_maxsize);
0306 insert_commit(header1, z, commit_data, tree1_size, h_alpha, max_tree1_size);
0307 }
0308 return transferable;
0309 }
0310
0311
0312 template<class NodePtrCompare, class H_Alpha, class AlphaByMaxSize>
0313 static void transfer_equal
0314 ( node_ptr header1, NodePtrCompare comp, std::size_t tree1_size, std::size_t &max_tree1_size
0315 , node_ptr header2, node_ptr z, std::size_t tree2_size, std::size_t &max_tree2_size
0316 ,H_Alpha h_alpha, AlphaByMaxSize alpha_by_maxsize)
0317 {
0318 insert_commit_data commit_data;
0319 insert_equal_upper_bound_check(header1, z, comp, commit_data);
0320 erase(header2, z, tree2_size, max_tree2_size, alpha_by_maxsize);
0321 insert_commit(header1, z, commit_data, tree1_size, h_alpha, max_tree1_size);
0322 }
0323
0324 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
0325
0326 static bool is_header(const_node_ptr p) BOOST_NOEXCEPT;
0327
0328
0329 static void rebalance(node_ptr header) BOOST_NOEXCEPT;
0330
0331
0332 static node_ptr rebalance_subtree(node_ptr old_root) BOOST_NOEXCEPT
0333 #endif
0334
0335
0336 private:
0337
0338 template<class KeyType, class KeyNodePtrCompare>
0339 static void insert_equal_upper_bound_check
0340 (node_ptr header, const KeyType &key
0341 ,KeyNodePtrCompare comp, insert_commit_data &commit_data)
0342 {
0343 std::size_t depth;
0344 bstree_algo::insert_equal_upper_bound_check(header, key, comp, commit_data, &depth);
0345 commit_data.depth = depth;
0346 }
0347
0348 template<class H_Alpha>
0349 static void insert_commit
0350 (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data
0351 ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
0352 {
0353 bstree_algo::insert_unique_commit(header, new_value, commit_data);
0354 rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size);
0355 }
0356
0357 template<class H_Alpha>
0358 static void rebalance_after_insertion
0359 (node_ptr x, std::size_t depth
0360 , std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size) BOOST_NOEXCEPT
0361 {
0362 if(tree_size > max_tree_size)
0363 max_tree_size = tree_size;
0364
0365 if(tree_size > 2 &&
0366
0367
0368
0369 depth > h_alpha(tree_size)){
0370
0371
0372
0373
0374
0375
0376
0377 node_ptr s = x;
0378 std::size_t size = 1;
0379 for(std::size_t ancestor = 1; ancestor != depth; ++ancestor){
0380 const node_ptr s_parent = NodeTraits::get_parent(s);
0381 const node_ptr s_parent_left = NodeTraits::get_left(s_parent);
0382
0383 const node_ptr s_sibling = s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left;
0384 size += 1 + bstree_algo::subtree_size(s_sibling);
0385 s = s_parent;
0386 if(ancestor > h_alpha(size)){
0387 bstree_algo::rebalance_subtree(s);
0388 return;
0389 }
0390 }
0391
0392 max_tree_size = tree_size;
0393 bstree_algo::rebalance_subtree(NodeTraits::get_parent(s));
0394 }
0395 }
0396
0397 };
0398
0399
0400
0401 template<class NodeTraits>
0402 struct get_algo<SgTreeAlgorithms, NodeTraits>
0403 {
0404 typedef sgtree_algorithms<NodeTraits> type;
0405 };
0406
0407 template <class ValueTraits, class NodePtrCompare, class ExtraChecker>
0408 struct get_node_checker<SgTreeAlgorithms, ValueTraits, NodePtrCompare, ExtraChecker>
0409 {
0410 typedef detail::bstree_node_checker<ValueTraits, NodePtrCompare, ExtraChecker> type;
0411 };
0412
0413
0414
0415 }
0416 }
0417
0418 #include <boost/intrusive/detail/config_end.hpp>
0419
0420 #endif