|
||||
File indexing completed on 2025-01-17 09:55:17
0001 /*- 0002 * Copyright (c) 2009, 2020 Oracle and/or its affiliates. All rights reserved. 0003 * 0004 * See the file LICENSE for license information. 0005 * 0006 * $Id$ 0007 */ 0008 0009 #ifndef _DB_STL_DB_BASE_ITERATOR_H 0010 #define _DB_STL_DB_BASE_ITERATOR_H 0011 0012 #include "dbstl_common.h" 0013 0014 START_NS(dbstl) 0015 0016 template <Typename ddt> 0017 class ElementRef; 0018 template <Typename ddt> 0019 class ElementHolder; 0020 0021 /** \defgroup dbstl_iterators dbstl iterator classes 0022 Common information for all dbstl iterators: 0023 0024 1. Each instance of a dbstl iterator uniquely owns a Berkeley DB cursor, 0025 so that the key/data pair it currently sits on is always valid before it moves 0026 elsewhere. It also caches the current key/data pair values in order for member 0027 functions like operator* /operator-> to work properly, but caching is not 0028 compatible with standard C++ Stl behavior --- the C++ standard requires the 0029 iterator refer to a shared piece of memory where the data is stored, 0030 thus two iterators of the same container sitting on the same element should 0031 point to the same memory location, which is false for dbstl iterators. 0032 0033 2. There are some functions common to each child class of this class which have 0034 identical behaviors, so we will document them here. 0035 0036 @{ 0037 This class is the base class for all dbstl iterators, there is no much to say 0038 about this class itself, and users are not supposed to directly use this class 0039 at all. So we will talk about some common functions of dbstl iterators in 0040 this section. 0041 0042 \sa db_vector_base_iterator db_vector_iterator db_map_base_iterator 0043 db_map_iterator db_set_base_iterator db_set_iterator 0044 */ 0045 template <Typename ddt> 0046 class db_base_iterator 0047 { 0048 protected: 0049 typedef db_base_iterator<ddt> self; 0050 friend class ElementHolder<ddt>; 0051 friend class ElementRef<ddt>; 0052 0053 // The container from which this iterator is created. 0054 mutable db_container *owner_; 0055 0056 bool dead_; // Internally used to prevent recursive destruction calls. 0057 0058 // Whether or not to always get current key/data pair directly from db; 0059 // If true, always poll db, slower but safe for concurrent use; 0060 // otherwise faster, but when multiple iterators point to the same 0061 // key/data pair (they definitely have same locker id) and use some 0062 // iterators to update current key/data pair, then other iterators' 0063 // key/data pairs are obsolete, need to call iterator::refresh(). 0064 // 0065 bool directdb_get_; 0066 0067 // Whether to do bulk retrieval for a read only iterator. If non-zero, 0068 // do bulk retrieval and use this member as the bulk buffer size, 0069 // otherwise, do not use bulk retrieval. While doing bulk retrieval, 0070 // no longer read from database even if directdb_get is true. 0071 u_int32_t bulk_retrieval_; 0072 0073 // Whether to use DB_RMW flag in Dbc::get. Users can set this flag in 0074 // db_container::begin(). The flag may be ignored when there is no 0075 // locking subsystem initialized. 0076 bool rmw_csr_; 0077 0078 // Whether this iterator is a db_set/db_multiset iterator. 0079 bool is_set_; 0080 0081 // Whether this iterator is read only. Default value is false. 0082 // The const version of begin(), or passing an explicit "readonly" 0083 // parameter to non-const begin() will will create a read only 0084 // iterator; 0085 // 0086 bool read_only_; 0087 0088 // Iteration status. If in valid range, it is 0, otherwise it is 0089 // INVALID_ITERATOR_POSITION. 0090 mutable int itr_status_; 0091 0092 // Distinguish the invalid iterator of end() and rend(). If an 0093 // iterator was invalidated in operator++, inval_pos_type_ is 0094 // IPT_AFTER_LAST, else if in operator-- it is IPT_BEFORE_FIRST. 0095 // For random iterator, inval_pos_type_ is also updated in random 0096 // movement functions. This member is only valid when itr_status_ is 0097 // set to INVALID_ITERATOR_POSITION. 0098 mutable char inval_pos_type_; 0099 // Values to denote the invalid positions. 0100 const static char IPT_BEFORE_FIRST = -1; 0101 const static char IPT_AFTER_LAST = 1; 0102 const static char IPT_UNSET = 0; 0103 0104 virtual void delete_me() const { delete this;} 0105 0106 virtual db_base_iterator* dup_itr() const 0107 { 0108 THROW(InvalidFunctionCall, ( 0109 "\ndb_base_iterator<>::dup_itr can't be called.\n")); 0110 0111 } 0112 0113 inline bool is_set_iterator() const 0114 { 0115 return is_set_; 0116 } 0117 0118 // The following two functions can't be abstract virtual for 0119 // compiler errors. 0120 virtual int replace_current(const ddt&) 0121 { 0122 THROW(InvalidFunctionCall, ( 0123 "\ndb_base_iterator<>::replace_current can't be called\n")); 0124 } 0125 0126 virtual int replace_current_key(const ddt&) 0127 { 0128 THROW(InvalidFunctionCall, ( 0129 "\ndb_base_iterator<>::replace_current_key can't be called\n")); 0130 } 0131 0132 public: 0133 #if NEVER_DEFINE_THIS_MACRO_IT_IS_FOR_DOXYGEN_ONLY 0134 /// Read data from underlying database via its cursor, and update 0135 /// its cached value. 0136 /// \param from_db Whether retrieve data from database rather than 0137 /// using the cached data in this iterator. 0138 /// \return 0 if succeeded. Otherwise an DbstlException exception 0139 /// will be thrown. 0140 int refresh(bool from_db = true); 0141 0142 /** Close its cursor. If you are sure the iterator is no longer 0143 used, call this function so that its underlying cursor is closed 0144 before this iterator is destructed, potentially increase performance 0145 and concurrency. Note that the cursor is definitely 0146 closed at iterator destruction if you don't close it explicitly. 0147 */ 0148 void close_cursor() const; 0149 0150 /** Call this function to modify bulk buffer size. Bulk retrieval is 0151 enabled when creating an iterator, so users later can only modify 0152 the bulk buffer size to another value, but can't enable/disable 0153 bulk read while an iterator is already alive. 0154 \param sz The new buffer size in bytes. 0155 \return true if succeeded, false otherwise. 0156 */ 0157 bool set_bulk_buffer(u_int32_t sz); 0158 0159 /// Return current bulk buffer size. Returns 0 if bulk retrieval is 0160 /// not enabled. 0161 u_int32_t get_bulk_bufsize(); 0162 #endif // NEVER_DEFINE_THIS_MACRO_IT_IS_FOR_DOXYGEN_ONLY 0163 0164 //////////////////////////////////////////////////////////////////// 0165 // 0166 // Begin public constructors and destructor. 0167 // 0168 /// Default constructor. 0169 db_base_iterator() 0170 { 0171 owner_ = NULL; 0172 directdb_get_ = true; 0173 dead_ = false; 0174 itr_status_ = INVALID_ITERATOR_POSITION; 0175 read_only_ = false; 0176 is_set_ = false; 0177 bulk_retrieval_ = 0; 0178 rmw_csr_ = false; 0179 inval_pos_type_ = IPT_UNSET; 0180 } 0181 0182 /// Constructor. 0183 db_base_iterator(db_container *powner, bool directdbget, 0184 bool b_read_only, u_int32_t bulk, bool rmw) 0185 { 0186 owner_ = powner; 0187 directdb_get_ = directdbget; 0188 dead_ = false; 0189 itr_status_ = INVALID_ITERATOR_POSITION; 0190 read_only_ = b_read_only; 0191 is_set_ = false; 0192 bulk_retrieval_ = bulk; 0193 rmw_csr_ = rmw; 0194 inval_pos_type_ = IPT_UNSET; 0195 } 0196 0197 /// Copy constructor. Copy all members of this class. 0198 db_base_iterator(const db_base_iterator &bi) 0199 { 0200 owner_ = bi.owner_; 0201 directdb_get_ = bi.directdb_get_; 0202 dead_ = false; 0203 itr_status_ = bi.itr_status_; 0204 read_only_ = bi.read_only_; 0205 is_set_ = bi.is_set_; 0206 bulk_retrieval_ = bi.bulk_retrieval_; 0207 rmw_csr_ = bi.rmw_csr_; 0208 inval_pos_type_ = bi.inval_pos_type_; 0209 } 0210 0211 /** 0212 Iterator assignment operator. 0213 Iterator assignment will cause the underlying cursor of the right iterator 0214 to be duplicated to the left iterator after its previous cursor is closed, 0215 to make sure each iterator owns one unique cursor. The key/data cached 0216 in the right iterator is copied to the left iterator. Consequently, 0217 the left iterator points to the same key/data pair in the database 0218 as the the right value after the assignment, and have identical cached 0219 key/data pair. 0220 \param bi The other iterator to assign with. 0221 \return The iterator bi's reference. 0222 */ 0223 inline const self& operator=(const self& bi) 0224 { 0225 ASSIGNMENT_PREDCOND(bi) 0226 owner_ = bi.owner_; 0227 directdb_get_ = bi.directdb_get_; 0228 dead_ = false; 0229 itr_status_ = bi.itr_status_; 0230 read_only_ = bi.read_only_; 0231 is_set_ = bi.is_set_; 0232 bulk_retrieval_ = bi.bulk_retrieval_; 0233 rmw_csr_ = bi.rmw_csr_; 0234 inval_pos_type_ = bi.inval_pos_type_; 0235 return bi; 0236 } 0237 0238 /// Destructor. 0239 virtual ~db_base_iterator() {} 0240 0241 //////////////////////////////////////////////////////////////////// 0242 0243 /// \brief Get bulk buffer size. 0244 /// 0245 /// Return bulk buffer size. If the size is 0, bulk retrieval is not 0246 /// enabled. 0247 u_int32_t get_bulk_retrieval() const { return bulk_retrieval_; } 0248 0249 /// \brief Get DB_RMW setting. 0250 /// 0251 /// Return true if the iterator's cursor has DB_RMW flag set, false 0252 /// otherwise. DB_RMW flag causes 0253 /// a write lock to be acquired when reading a key/data pair, so 0254 /// that the transaction won't block later when writing back the 0255 /// updated value in a read-modify-write operation cycle. 0256 bool is_rmw() const { return rmw_csr_; } 0257 0258 /// \brief Get direct database get setting. 0259 /// 0260 /// Return true if every operation to retrieve the key/data pair the 0261 /// iterator points to will read from database rather than using 0262 /// the cached value, false otherwise. 0263 bool is_directdb_get() const {return directdb_get_; } 0264 }; // db_base_iterator 0265 0266 //////////////////////////////////////////////////////////////////////// 0267 //////////////////////////////////////////////////////////////////////// 0268 // 0269 // db_reverse_iterator class template definition. 0270 // 0271 // db_reverse_iterator is the reverse iterator adapter for all iterator 0272 // classes of dbstl. It makes an original iterator its reverse iterator. 0273 // We don't want to use std::reverse_iterator<> adapter because it is more 0274 // more expensive. Here we move the original iterator one position back to 0275 // avoid unnecessary movement. 0276 // 0277 /// This class is the reverse class adaptor for all dbstl iterator classes. 0278 /// It inherits from real iterator classes like db_vector_iterator, 0279 /// db_map_iterator or db_set_iterator. When you call container::rbegin(), 0280 /// you will get an instance of this class. 0281 /// \sa db_vector_base_iterator db_vector_iterator db_map_base_iterator 0282 /// db_map_iterator db_set_base_iterator db_set_iterator 0283 template <Typename iterator, Typename twin_itr_t> 0284 class _exported db_reverse_iterator : public iterator 0285 { 0286 public: 0287 // typedefs are not inherited, so re-define them here. 0288 // 0289 typedef db_reverse_iterator<iterator, twin_itr_t> self; 0290 typedef typename iterator::value_type T; 0291 typedef iterator iterator_type; 0292 typedef typename iterator::value_type value_type; 0293 typedef typename iterator::reference reference; 0294 typedef typename iterator::pointer pointer; 0295 typedef typename iterator::iterator_category iterator_category; 0296 typedef typename iterator::key_type key_type; 0297 typedef typename iterator::data_type data_type; 0298 typedef typename iterator::difference_type difference_type; 0299 typedef typename iterator::value_type_wrap value_type_wrap; 0300 // Construct a reverse iterator from iterator vi. We don't duplicate 0301 // iterator vi here because vi is not supposed to be used again. 0302 // This function is supposed to be used by dbstl users, internally 0303 // self::set_iterator method is used. 0304 /// Constructor. Construct from an iterator of wrapped type. 0305 db_reverse_iterator(const iterator& vi) : iterator(vi) 0306 { 0307 iterator::operator--(); 0308 } 0309 0310 /// Copy constructor. 0311 db_reverse_iterator(const self& ritr) 0312 : iterator(ritr) 0313 { 0314 } 0315 0316 /// Copy constructor. 0317 db_reverse_iterator(const 0318 db_reverse_iterator<twin_itr_t, iterator>& ritr) 0319 : iterator(ritr) 0320 { 0321 } 0322 0323 /// Default constructor. 0324 db_reverse_iterator() : iterator() 0325 { 0326 } 0327 0328 // Do not throw exceptions here because it is normal to iterate to 0329 // "end()". 0330 // 0331 /// \name Reverse iterator movement functions 0332 /// When we talk about reverse iterator movement, we think the 0333 /// container is a uni-directional range, represented by [begin, end), 0334 /// and this is true no matter we are using iterators or reverse 0335 /// iterators. When an iterator is moved closer to "begin", we say it 0336 /// is moved forward, otherwise we say it is moved backward. 0337 //@{ 0338 /// Move this iterator forward by one element. 0339 /// \return The moved iterator at new position. 0340 self& operator++() 0341 { 0342 iterator::operator--(); 0343 return *this; 0344 } 0345 0346 /// Move this iterator forward by one element. 0347 /// \return The original iterator at old position. 0348 self operator++(int) 0349 { 0350 // XXX!!! This conversion relies on this class or 0351 // db_set_iterator<> having no data members at all, which 0352 // is currently the case. 0353 return (self)iterator::operator--(1); 0354 } 0355 0356 /// Move this iterator backward by one element. 0357 /// \return The moved iterator at new position. 0358 self& operator--() 0359 { 0360 iterator::operator++(); 0361 return *this; 0362 } 0363 0364 /// Move this iterator backward by one element. 0365 /// \return The original iterator at old position. 0366 self operator--(int) 0367 { 0368 // XXX!!! This conversion relies on this class or 0369 // db_set_iterator<> having no data members at all, which 0370 // is currently the case. 0371 return (self)iterator::operator++(1); 0372 } 0373 //@} // Movement operators. 0374 0375 /// Assignment operator. 0376 /// \param ri The iterator to assign with. 0377 /// \return The iterator ri. 0378 /// \sa db_base_iterator::operator=(const self&) 0379 const self& operator=(const self& ri) 0380 { 0381 ASSIGNMENT_PREDCOND(ri) 0382 iterator::operator=(ri); 0383 return ri; 0384 } 0385 0386 ////////////// Methods below only applies to random iterators. ///// 0387 /// \name Operators for random reverse iterators 0388 /// Return a new iterator by moving this iterator backward or forward 0389 /// by n elements. 0390 //@{ 0391 /// Iterator shuffle operator. 0392 /// Return a new iterator by moving this iterator forward 0393 /// by n elements. 0394 /// \param n The amount and direction of movement. If negative, 0395 /// will move towards reverse direction. 0396 /// \return A new iterator at new position. 0397 self operator+(difference_type n) const 0398 { 0399 self ritr(*this); 0400 ritr.iterator::operator-=(n); 0401 return ritr; 0402 } 0403 0404 /// Iterator shuffle operator. 0405 /// Return a new iterator by moving this iterator backward 0406 /// by n elements. 0407 /// \param n The amount and direction of movement. If negative, 0408 /// will move towards reverse direction. 0409 /// \return A new iterator at new position. 0410 self operator-(difference_type n) const 0411 { 0412 self ritr(*this); 0413 ritr.iterator::operator+=(n); 0414 return ritr; 0415 } 0416 //@} 0417 /// \name Operators for random reverse iterators 0418 /// Move this iterator backward or forward by n elements and then 0419 /// return it. 0420 //@{ 0421 /// Iterator shuffle operator. 0422 /// Move this iterator forward by n elements and then 0423 /// return it. 0424 /// \param n The amount and direction of movement. If negative, 0425 /// will move towards reverse direction. 0426 /// \return This iterator at new position. 0427 const self& operator+=(difference_type n) 0428 { 0429 iterator::operator-=(n); 0430 return *this; 0431 } 0432 0433 /// Iterator shuffle operator. 0434 /// Move this iterator backward by n elements and then 0435 /// return it. 0436 /// \param n The amount and direction of movement. If negative, 0437 /// will move towards reverse direction. 0438 /// \return This iterator at new position. 0439 const self& operator-=(difference_type n) 0440 { 0441 iterator::operator+=(n); 0442 return *this; 0443 } 0444 //@} 0445 /// \name Operators for random reverse iterators 0446 /// Reverse iterator comparison against reverse iterator itr, the one 0447 /// sitting on elements with less index is returned to be greater. 0448 //@{ 0449 /// Less compare operator. 0450 bool operator<(const self& itr) const 0451 { 0452 return (iterator::operator>(itr)); 0453 } 0454 0455 /// Greater compare operator. 0456 bool operator>(const self& itr) const 0457 { 0458 return (iterator::operator<(itr)); 0459 } 0460 0461 /// Less equal compare operator. 0462 bool operator<=(const self& itr) const 0463 { 0464 return (iterator::operator>=(itr)); 0465 } 0466 0467 /// Greater equal compare operator. 0468 bool operator>=(const self& itr) const 0469 { 0470 return (iterator::operator<=(itr)); 0471 } 0472 //@} 0473 // Because v.rend() - v.rbegin() < 0, we should negate base version. 0474 /// Return the negative value of the difference of indices of elements 0475 /// this iterator and itr are sitting on. 0476 /// \return itr.index - this->index. 0477 /// \param itr The other reverse iterator. 0478 difference_type operator-(const self&itr) const 0479 { 0480 difference_type d = iterator::operator-(itr); 0481 return -d; 0482 } 0483 0484 /// Return the reference of the element which can be reached by moving 0485 /// this reverse iterator by Off times backward. If Off is negative, 0486 /// the movement will be forward. 0487 inline value_type_wrap operator[](difference_type Off) const 0488 { 0489 self ritr(*this); 0490 value_type_wrap res = ritr.iterator::operator[](-Off); 0491 return res; 0492 } 0493 0494 }; // reverse_iterator 0495 //@} // dbstl_iterators 0496 END_NS 0497 0498 #endif // !_DB_STL_DB_BASE_ITERATOR_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |