Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-05-18 08:29:45

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