00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef STXXL_CONTAINERS_BTREE__ITERATOR_H
00014 #define STXXL_CONTAINERS_BTREE__ITERATOR_H
00015
00016 #include <iterator>
00017 #include <cassert>
00018 #include <stxxl/bits/verbose.h>
00019
00020
00021 __STXXL_BEGIN_NAMESPACE
00022
00023
00024 namespace btree
00025 {
00026 template <class BTreeType>
00027 class iterator_map;
00028 template <class BTreeType>
00029 class btree_iterator;
00030 template <class BTreeType>
00031 class btree_const_iterator;
00032 template <class KeyType_, class DataType_, class KeyCmp_, unsigned LogNElem_, class BTreeType>
00033 class normal_leaf;
00034
00035 template <class BTreeType>
00036 class btree_iterator_base
00037 {
00038 public:
00039 typedef BTreeType btree_type;
00040 typedef typename btree_type::leaf_bid_type bid_type;
00041 typedef typename btree_type::value_type value_type;
00042 typedef typename btree_type::reference reference;
00043 typedef typename btree_type::const_reference const_reference;
00044 typedef std::bidirectional_iterator_tag iterator_category;
00045 typedef typename btree_type::difference_type difference_type;
00046
00047 friend class iterator_map<btree_type>;
00048 template <class KeyType_, class DataType_,
00049 class KeyCmp_, unsigned LogNElem_, class BTreeType__>
00050 friend class normal_leaf;
00051
00052 template <class BTreeType_>
00053 friend bool operator == (const btree_iterator<BTreeType_> & a,
00054 const btree_const_iterator<BTreeType_> & b);
00055 template <class BTreeType_>
00056 friend bool operator != (const btree_iterator<BTreeType_> & a,
00057 const btree_const_iterator<BTreeType_> & b);
00058
00059 protected:
00060 btree_type * btree_;
00061 bid_type bid;
00062 unsigned pos;
00063
00064 btree_iterator_base()
00065 {
00066 STXXL_VERBOSE3("btree_iterator_base def construct addr=" << this);
00067 make_invalid();
00068 }
00069
00070 btree_iterator_base(
00071 btree_type * btree__,
00072 const bid_type & b,
00073 unsigned p
00074 ) : btree_(btree__), bid(b), pos(p)
00075 {
00076 STXXL_VERBOSE3("btree_iterator_base parameter construct addr=" << this);
00077 btree_->iterator_map_.register_iterator(*this);
00078 }
00079
00080 void make_invalid()
00081 {
00082 btree_ = NULL;
00083 }
00084
00085 btree_iterator_base(const btree_iterator_base & obj)
00086 {
00087 STXXL_VERBOSE3("btree_iterator_base constr from" << (&obj) << " to " << this);
00088 btree_ = obj.btree_;
00089 bid = obj.bid;
00090 pos = obj.pos;
00091 if (btree_)
00092 btree_->iterator_map_.register_iterator(*this);
00093 }
00094
00095 btree_iterator_base & operator = (const btree_iterator_base & obj)
00096 {
00097 STXXL_VERBOSE3("btree_iterator_base copy from" << (&obj) << " to " << this);
00098 if (&obj != this)
00099 {
00100 if (btree_)
00101 btree_->iterator_map_.unregister_iterator(*this);
00102
00103 btree_ = obj.btree_;
00104 bid = obj.bid;
00105 pos = obj.pos;
00106 if (btree_)
00107 btree_->iterator_map_.register_iterator(*this);
00108 }
00109 return *this;
00110 }
00111
00112 reference non_const_access()
00113 {
00114 assert(btree_);
00115 typename btree_type::leaf_type * Leaf = btree_->leaf_cache_.get_node(bid);
00116 assert(Leaf);
00117 return (reference)((*Leaf)[pos]);
00118 }
00119
00120 const_reference const_access() const
00121 {
00122 assert(btree_);
00123 typename btree_type::leaf_type const * Leaf = btree_->leaf_cache_.get_const_node(bid);
00124 assert(Leaf);
00125 return (reference)((*Leaf)[pos]);
00126 }
00127
00128 bool operator == (const btree_iterator_base & obj) const
00129 {
00130 return bid == obj.bid && pos == obj.pos && btree_ == obj.btree_;
00131 }
00132
00133 bool operator != (const btree_iterator_base & obj) const
00134 {
00135 return bid != obj.bid || pos != obj.pos || btree_ != obj.btree_;
00136 }
00137
00138 btree_iterator_base & increment()
00139 {
00140 assert(btree_);
00141 bid_type cur_bid = bid;
00142 typename btree_type::leaf_type const * Leaf = btree_->leaf_cache_.get_const_node(bid, true);
00143 assert(Leaf);
00144 Leaf->increment_iterator(*this);
00145 btree_->leaf_cache_.unfix_node(cur_bid);
00146 return *this;
00147 }
00148
00149 btree_iterator_base & decrement()
00150 {
00151 assert(btree_);
00152 bid_type cur_bid = bid;
00153 typename btree_type::leaf_type const * Leaf = btree_->leaf_cache_.get_const_node(bid, true);
00154 assert(Leaf);
00155 Leaf->decrement_iterator(*this);
00156 btree_->leaf_cache_.unfix_node(cur_bid);
00157 return *this;
00158 }
00159
00160 public:
00161 virtual ~btree_iterator_base()
00162 {
00163 STXXL_VERBOSE3("btree_iterator_base deconst " << this);
00164 if (btree_)
00165 btree_->iterator_map_.unregister_iterator(*this);
00166 }
00167 };
00168
00169 template <class BTreeType>
00170 class btree_iterator : public btree_iterator_base<BTreeType>
00171 {
00172 public:
00173 typedef BTreeType btree_type;
00174 typedef typename btree_type::leaf_bid_type bid_type;
00175 typedef typename btree_type::value_type value_type;
00176 typedef typename btree_type::reference reference;
00177 typedef typename btree_type::const_reference const_reference;
00178 typedef typename btree_type::pointer pointer;
00179
00180 template <class KeyType_, class DataType_,
00181 class KeyCmp_, unsigned LogNElem_, class BTreeType__>
00182 friend class normal_leaf;
00183
00184 using btree_iterator_base<btree_type>::non_const_access;
00185
00186 btree_iterator() : btree_iterator_base<btree_type>()
00187 { }
00188
00189 btree_iterator(const btree_iterator & obj) :
00190 btree_iterator_base<btree_type>(obj)
00191 { }
00192
00193 btree_iterator & operator = (const btree_iterator & obj)
00194 {
00195 btree_iterator_base<btree_type>::operator = (obj);
00196 return *this;
00197 }
00198
00199 reference operator * ()
00200 {
00201 return non_const_access();
00202 }
00203
00204 pointer operator -> ()
00205 {
00206 return &(non_const_access());
00207 }
00208
00209 bool operator == (const btree_iterator & obj) const
00210 {
00211 return btree_iterator_base<btree_type>::operator == (obj);
00212 }
00213
00214 bool operator != (const btree_iterator & obj) const
00215 {
00216 return btree_iterator_base<btree_type>::operator != (obj);
00217 }
00218
00219 btree_iterator & operator ++ ()
00220 {
00221 assert(*this != btree_iterator_base<btree_type>::btree_->end());
00222 btree_iterator_base<btree_type>::increment();
00223 return *this;
00224 }
00225
00226 btree_iterator & operator -- ()
00227 {
00228 btree_iterator_base<btree_type>::decrement();
00229 return *this;
00230 }
00231
00232 btree_iterator operator ++ (int)
00233 {
00234 assert(*this != btree_iterator_base<btree_type>::btree_->end());
00235 btree_iterator result(*this);
00236 btree_iterator_base<btree_type>::increment();
00237 return result;
00238 }
00239
00240 btree_iterator operator -- (int)
00241 {
00242 btree_iterator result(*this);
00243 btree_iterator_base<btree_type>::decrement();
00244 return result;
00245 }
00246
00247 private:
00248 btree_iterator(
00249 btree_type * btree__,
00250 const bid_type & b,
00251 unsigned p
00252 ) : btree_iterator_base<btree_type>(btree__, b, p)
00253 { }
00254 };
00255
00256 template <class BTreeType>
00257 class btree_const_iterator : public btree_iterator_base<BTreeType>
00258 {
00259 public:
00260 typedef btree_iterator<BTreeType> iterator;
00261
00262 typedef BTreeType btree_type;
00263 typedef typename btree_type::leaf_bid_type bid_type;
00264 typedef typename btree_type::value_type value_type;
00265 typedef typename btree_type::const_reference reference;
00266 typedef typename btree_type::const_pointer pointer;
00267
00268 template <class KeyType_, class DataType_,
00269 class KeyCmp_, unsigned LogNElem_, class BTreeType__>
00270 friend class normal_leaf;
00271
00272 using btree_iterator_base<btree_type>::const_access;
00273
00274 btree_const_iterator() : btree_iterator_base<btree_type>()
00275 { }
00276
00277 btree_const_iterator(const btree_const_iterator & obj) :
00278 btree_iterator_base<btree_type>(obj)
00279 { }
00280
00281 btree_const_iterator(const iterator & obj) :
00282 btree_iterator_base<btree_type>(obj)
00283 { }
00284
00285 btree_const_iterator & operator = (const btree_const_iterator & obj)
00286 {
00287 btree_iterator_base<btree_type>::operator = (obj);
00288 return *this;
00289 }
00290
00291 reference operator * ()
00292 {
00293 return const_access();
00294 }
00295
00296 pointer operator -> ()
00297 {
00298 return &(const_access());
00299 }
00300
00301
00302 bool operator == (const iterator & obj) const
00303 {
00304 return btree_iterator_base<btree_type>::operator == (obj);
00305 }
00306
00307 bool operator != (const iterator & obj) const
00308 {
00309 return btree_iterator_base<btree_type>::operator != (obj);
00310 }
00311
00312 bool operator == (const btree_const_iterator & obj) const
00313 {
00314 return btree_iterator_base<btree_type>::operator == (obj);
00315 }
00316
00317 bool operator != (const btree_const_iterator & obj) const
00318 {
00319 return btree_iterator_base<btree_type>::operator != (obj);
00320 }
00321
00322 btree_const_iterator & operator ++ ()
00323 {
00324 assert(*this != btree_iterator_base<btree_type>::btree_->end());
00325 btree_iterator_base<btree_type>::increment();
00326 return *this;
00327 }
00328
00329 btree_const_iterator & operator -- ()
00330 {
00331 btree_iterator_base<btree_type>::decrement();
00332 return *this;
00333 }
00334
00335 btree_const_iterator operator ++ (int)
00336 {
00337 assert(*this != btree_iterator_base<btree_type>::btree_->end());
00338 btree_const_iterator result(*this);
00339 btree_iterator_base<btree_type>::increment();
00340 return result;
00341 }
00342
00343 btree_const_iterator operator -- (int)
00344 {
00345 btree_const_iterator result(*this);
00346 btree_iterator_base<btree_type>::decrement();
00347 return result;
00348 }
00349
00350 private:
00351 btree_const_iterator(
00352 btree_type * btree__,
00353 const bid_type & b,
00354 unsigned p
00355 ) : btree_iterator_base<btree_type>(btree__, b, p)
00356 { }
00357 };
00358
00359 template <class BTreeType>
00360 inline bool operator == (const btree_iterator<BTreeType> & a,
00361 const btree_const_iterator<BTreeType> & b)
00362 {
00363 return a.btree_iterator_base<BTreeType>::operator == (b);
00364 }
00365
00366 template <class BTreeType>
00367 inline bool operator != (const btree_iterator<BTreeType> & a,
00368 const btree_const_iterator<BTreeType> & b)
00369 {
00370 return a.btree_iterator_base<BTreeType>::operator != (b);
00371 }
00372 }
00373
00374 __STXXL_END_NAMESPACE
00375
00376 #endif