3 #ifndef __CDS_CONTAINER_DETAILS_BRONSON_AVLTREE_BASE_H
4 #define __CDS_CONTAINER_DETAILS_BRONSON_AVLTREE_BASE_H
6 #include <cds/container/details/base.h>
7 #include <cds/opt/compare.h>
8 #include <cds/urcu/options.h>
9 #include <cds/lock/spinlock.h>
11 namespace cds { namespace container {
13 /// BronsonAVLTree related declarations
14 namespace bronson_avltree {
16 template <typename Key, typename T>
20 template <typename Key, typename T, typename Lock>
23 typedef node<Key, T> node_type;
24 typedef uint64_t version_type;
25 typedef Lock lock_type;
27 enum class version_flags : version_type
32 grow_count_increment = 1 << 3,
33 grow_count_mask = 0xff << 3,
34 shrink_count_increment = 1 << 11,
35 ignore_grow = ~(growing | grow_count_mask)
38 atomics::atomic< int > m_nHeight; ///< Node height
39 atomics::atomic<version_type> m_nVersion; ///< Version bits
40 atomics::atomic<node_type *> m_pParent; ///< Parent node
41 atomics::atomic<node_type *> m_pLeft; ///< Left child
42 atomics::atomic<node_type *> m_pRight; ///< Right child
43 lock_type m_Lock; ///< Node-level lock
45 atomics::atomic<node_type *>& child( int nDirection ) const
47 assert( nDirection != 0 );
48 return nDirection < 0 ? m_pLeft : m_pRight;
51 version_type version( atomics::memory_order order ) const
53 return m_nVersion.load( order );
56 template <typename BackOff>
57 void wait_until_shrink_completed( atomics::memory_order order ) const
60 while ( version( order ) & version_flags::shrinking )
65 template <typename Key, typename T, typename Lock>
66 struct node : public link< Key, T, Lock >
69 typedef T mapped_type;
70 typedef link< key_type, mapped_type, Lock > base_class;
73 atomics::atomic<mapped_type *> m_pValue;
77 : m_key( std::forward<Q>(key) )
82 node( Q&& key, mapped_type * pVal )
83 : m_key( std::forward<Q>(key) )
87 T * value( atomics::memory_order order ) const
89 return m_pValue.load( order );
94 /// BronsonAVLTreeMap internal statistics
95 template <typename Counter = cds::atomicity::event_counter>
97 typedef Counter event_counter; ///< Event counter type
99 event_counter m_nFindSuccess; ///< Count of success \p find() call
100 event_counter m_nFindFailed; ///< Count of failed \p find() call
101 event_counter m_nFindRetry; ///< Count of retries during \p find()
102 event_counter m_nFindWaitShrinking; ///< Count of waiting until shrinking completed duting \p find() call
105 void onFindSuccess() { ++m_nFindSuccess ; }
106 void onFindFailed() { ++m_nFindFailed ; }
107 void onFindRetry() { ++m_nFindRetry ; }
108 void onFindWaitShrinking() { ++m_nFindWaitShrinking; }
113 /// BronsonAVLTreeMap empty statistics
116 void onFindSuccess() const {}
117 void onFindFailed() const {}
118 void onFindRetry() const {}
119 void onFindWaitShrinking() const {}
123 /// BronsnAVLTreeMap traits
125 Note that there are two main specialization of Bronson et al AVL-tree:
126 - pointer-oriented - the tree node stores an user-provided pointer to value: <tt>BronsonAVLTreeMap<GC, Key, T *, Traits> </tt>
127 - data-oriented - the tree node contains a copy of values: <tt>BronsonAVLTreeMap<GC, Key, T, Traits> </tt> where \p T is not a pointer type.
129 Depends on tree specialization, different traits member can be used.
133 /// Key comparison functor
135 No default functor is provided. If the option is not specified, the \p less is used.
137 See \p cds::opt::compare option description for functor interface.
139 You should provide \p compare or \p less functor.
141 typedef opt::none compare;
143 /// Specifies binary predicate used for key compare.
145 See \p cds::opt::less option description for predicate interface.
147 You should provide \p compare or \p less functor.
149 typedef opt::none less;
151 /// Allocator for internal node
152 typedef CDS_DEFAULT_ALLOCATOR allocator;
154 /// Disposer (only for pointer-oriented tree specialization)
156 The functor used for dispose removed values.
157 The user-provided disposer is used only for pointer-oriented tree specialization
158 like \p BronsonAVLTreeMap<GC, Key, T*, Traits>. When the node becomes the rounting node without value,
159 the disposer will be called to signal that the memory for the value can be safely freed.
160 Default is \ref cds::intrusive::opt::v::delete_disposer "cds::container::opt::v::delete_disposer" which calls \p delete operator.
162 typedef opt::v::delete_disposer disposer;
165 typedef cds::SpinLock lock_type;
169 The type for item counter, by default it is disabled (\p atomicity::empty_item_counter).
170 To enable it use \p atomicity::item_counter
172 typedef atomicity::empty_item_counter item_counter;
174 /// C++ memory ordering model
176 List of available memory ordering see \p opt::memory_model
178 typedef opt::v::relaxed_ordering memory_model;
180 /// Internal statistics
182 By default, internal statistics is disabled (\p ellen_bintree::empty_stat).
183 To enable it use \p ellen_bintree::stat.
185 typedef empty_stat stat;
187 /// Back-off strategy
188 typedef cds::backoff::empty back_off;
190 /// RCU deadlock checking policy (only for \ref cds_intrusive_BronsonAVLTree_rcu "RCU-based BronsonAVLTree")
192 List of available options see \p opt::rcu_check_deadlock
194 typedef cds::opt::v::rcu_throw_deadlock rcu_check_deadlock;
197 // Internal traits, not for direct usage
198 typedef opt::none node_type;
202 /// Metafunction converting option list to BronsonAVLTreeMap traits
204 Note that there are two main specialization of Bronson et al AVL-tree:
205 - pointer-oriented - the tree node stores an user-provided pointer to value: <tt>BronsonAVLTreeMap<GC, Key, T *, Traits> </tt>
206 - data-oriented - the tree node contains a copy of values: <tt>BronsonAVLTreeMap<GC, Key, T, Traits> </tt> where \p T is not a pointer type.
208 Depends on tree specialization, different options can be specified.
211 - \p opt::compare - key compare functor. No default functor is provided.
212 If the option is not specified, \p %opt::less is used.
213 - \p opt::less - specifies binary predicate used for key compare. At least \p %opt::compare or \p %opt::less should be defined.
214 - \p opt::allocator - the allocator for internal nodes. Default is \ref CDS_DEFAULT_ALLOCATOR.
215 - \ref cds::intusive::opt::disposer "container::opt::disposer" - the functor used for dispose removed values.
216 The user-provided disposer is used only for pointer-oriented tree specialization
217 like \p BronsonAVLTreeMap<GC, Key, T*, Traits>. When the node becomes the rounting node without value,
218 the disposer will be called to signal that the memory for the value can be safely freed.
219 Default is \ref cds::intrusive::opt::v::delete_disposer "cds::container::opt::v::delete_disposer" which calls \p delete operator.
220 Due the nature of GC schema the disposer may be called asynchronously.
221 - \p opt::lock_type - node lock type, default is \p cds::SpinLock
222 - \p opt::item_counter - the type of item counting feature, by default it is disabled (\p atomicity::empty_item_counter)
223 To enable it use \p atomicity::item_counter
224 - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
225 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
226 - \p opt::stat - internal statistics, by default it is disabled (\p bronson_avltree::empty_stat)
227 To enable statistics use \p \p bronson_avltree::stat
228 - \p opt::backoff - back-off strategy, by default no strategy is used (\p cds::backoff::empty)
229 - \p opt::rcu_check_deadlock - a deadlock checking policy for RCU-based tree, default is \p opt::v::rcu_throw_deadlock
231 template <typename... Options>
233 # ifdef CDS_DOXYGEN_INVOKED
234 typedef implementation_defined type ; ///< Metafunction result
236 typedef typename cds::opt::make_options<
237 typename cds::opt::find_type_traits< traits, Options... >::type
244 } // namespace bronson_avltree
247 template < class GC, typename Key, typename T, class Traits = bronson_avltree::traits >
248 class BronsonAVLTreeMap;
250 }} // namespace cds::container
253 #endif // #ifndef __CDS_CONTAINER_DETAILS_BRONSON_AVLTREE_BASE_H