File indexing completed on 2025-01-17 09:55:19
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef _DB_STL_DB_VECTOR_H
0010 #define _DB_STL_DB_VECTOR_H
0011
0012 #include "dbstl_common.h"
0013 #include "dbstl_dbc.h"
0014 #include "dbstl_element_ref.h"
0015 #include "dbstl_resource_manager.h"
0016 #include "dbstl_container.h"
0017 #include "dbstl_base_iterator.h"
0018 #include <list>
0019 #include <algorithm>
0020
0021 START_NS(dbstl)
0022
0023 using std::list;
0024 using std::istream;
0025 using std::ostream;
0026 using std::sort;
0027
0028 #define TRandDbCursor RandDbCursor<T>
0029
0030
0031
0032 template <class T, Typename value_type_sub = ElementRef<T> >
0033 class db_vector;
0034 template <class T, Typename value_type_sub = ElementRef<T> >
0035 class db_vector_iterator;
0036 template<class kdt, class ddt> class DbCursor;
0037 template<class ddt> class RandDbCursor;
0038 template<class ddt> class ElementRef;
0039 template <typename T, typename T2>
0040 class DbstlListSpecialOps;
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 template <class T>
0075 class _exported db_vector_base_iterator : public db_base_iterator<T>
0076 {
0077 protected:
0078
0079 typedef db_vector_base_iterator<T> self;
0080 typedef db_recno_t index_type;
0081 using db_base_iterator<T>::replace_current_key;
0082 public:
0083
0084
0085
0086
0087 typedef T value_type;
0088 typedef ptrdiff_t difference_type;
0089 typedef difference_type distance_type;
0090
0091
0092
0093 typedef value_type value_type_wrap;
0094 typedef value_type& reference;
0095 typedef value_type* pointer;
0096
0097
0098 typedef std::random_access_iterator_tag iterator_category;
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 db_vector_base_iterator(const db_vector_base_iterator<T>& vi)
0109 : base(vi), pcsr_(vi.pcsr_), curpair_base_(vi.curpair_base_)
0110 {
0111
0112 }
0113
0114 explicit db_vector_base_iterator(db_container*powner,
0115 u_int32_t b_bulk_retrieval = 0, bool rmw = false,
0116 bool directdbget = true, bool readonly = false)
0117 : base(powner, directdbget, readonly, b_bulk_retrieval, rmw),
0118 pcsr_(new TRandDbCursor(b_bulk_retrieval, rmw, directdbget))
0119 {
0120
0121 }
0122
0123 db_vector_base_iterator() : pcsr_(NULL)
0124 {
0125
0126 }
0127
0128 virtual ~db_vector_base_iterator()
0129 {
0130 this->dead_ = true;
0131 if (pcsr_)
0132 pcsr_->close();
0133 }
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 inline bool operator==(const self&itr) const
0162 {
0163 COMPARE_CHECK(itr)
0164 if ((itr.itr_status_ == this->itr_status_) &&
0165 (this->itr_status_ == INVALID_ITERATOR_POSITION))
0166 return true;
0167
0168 if (this->itr_status_ != INVALID_ITERATOR_POSITION &&
0169 itr.itr_status_ != INVALID_ITERATOR_POSITION) {
0170 return (pcsr_->compare((itr.pcsr_.base_ptr())) == 0);
0171 }
0172 return false;
0173 }
0174
0175
0176
0177
0178 inline bool operator!=(const self&itr) const
0179 {
0180 return !(*this == itr) ;
0181 }
0182
0183
0184
0185
0186
0187 inline bool operator < (const self& itr) const
0188 {
0189 bool ret;
0190
0191 if (this == &itr)
0192 return false;
0193
0194 char after_last = base::IPT_AFTER_LAST,
0195 bef_fst = base::IPT_BEFORE_FIRST;
0196
0197 if (this->itr_status_ == INVALID_ITERATOR_POSITION &&
0198 this->inval_pos_type_ == after_last)
0199 ret = false;
0200 else if (this->itr_status_ == INVALID_ITERATOR_POSITION &&
0201 this->inval_pos_type_ == bef_fst)
0202 ret = itr.inval_pos_type_ != bef_fst;
0203 else {
0204 if (itr.itr_status_ == INVALID_ITERATOR_POSITION &&
0205 itr.inval_pos_type_ == after_last)
0206 ret = true;
0207 else if (itr.itr_status_ == INVALID_ITERATOR_POSITION &&
0208 itr.inval_pos_type_ == bef_fst)
0209 ret = false;
0210 else {
0211
0212
0213
0214 assert((this->itr_status_ !=
0215 INVALID_ITERATOR_POSITION) &&
0216 (itr.itr_status_ !=
0217 INVALID_ITERATOR_POSITION));
0218 ret = pcsr_->compare(
0219 (itr.pcsr_.base_ptr())) < 0;
0220 }
0221 }
0222 return ret;
0223 }
0224
0225
0226
0227
0228 inline bool operator <= (const self& itr) const
0229 {
0230 return !(this->operator>(itr));
0231 }
0232
0233
0234
0235
0236 inline bool operator >= (const self& itr) const
0237 {
0238 return !(this->operator<(itr));
0239 }
0240
0241
0242
0243
0244
0245 inline bool operator > (const self& itr) const
0246 {
0247 bool ret;
0248
0249 if (this == &itr)
0250 return false;
0251
0252 char after_last = base::IPT_AFTER_LAST,
0253 bef_fst = base::IPT_BEFORE_FIRST;
0254
0255 if (this->itr_status_ == INVALID_ITERATOR_POSITION &&
0256 this->inval_pos_type_ == after_last)
0257 ret = itr.inval_pos_type_ != after_last;
0258 else if (this->itr_status_ == INVALID_ITERATOR_POSITION &&
0259 this->inval_pos_type_ == bef_fst)
0260 ret = false;
0261 else {
0262 if (itr.itr_status_ == INVALID_ITERATOR_POSITION &&
0263 itr.inval_pos_type_ == after_last)
0264 ret = false;
0265 else if (itr.itr_status_ == INVALID_ITERATOR_POSITION &&
0266 itr.inval_pos_type_ == bef_fst)
0267 ret = true;
0268 else {
0269
0270
0271
0272 assert((this->itr_status_ !=
0273 INVALID_ITERATOR_POSITION) &&
0274 (itr.itr_status_ !=
0275 INVALID_ITERATOR_POSITION));
0276 ret = pcsr_->compare(
0277 (itr.pcsr_.base_ptr())) > 0;
0278 }
0279 }
0280 return ret;
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304 inline self& operator++()
0305 {
0306 move_by(*this, 1, false);
0307 return *this;
0308 }
0309
0310
0311
0312
0313
0314
0315
0316 inline self operator++(int)
0317 {
0318 self itr(*this);
0319 move_by(*this, 1, false);
0320
0321 return itr;
0322 }
0323
0324
0325
0326
0327
0328
0329
0330 inline self& operator--()
0331 {
0332 move_by(*this, 1, true);
0333 return *this;
0334 }
0335
0336
0337
0338
0339
0340
0341
0342
0343 inline self operator--(int)
0344 {
0345 self itr = *this;
0346 move_by(*this, 1, true);
0347 return itr;
0348 }
0349
0350
0351
0352
0353
0354
0355
0356
0357 inline const self& operator=(const self&itr)
0358 {
0359 ASSIGNMENT_PREDCOND(itr)
0360 base::operator=(itr);
0361
0362 if (pcsr_)
0363 pcsr_->close();
0364 pcsr_ = itr.pcsr_;
0365 curpair_base_ = itr.curpair_base_;
0366 return itr;
0367 }
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377 inline self operator+(difference_type n) const
0378 {
0379 self itr(*this);
0380 move_by(itr, n, false);
0381 return itr;
0382 }
0383
0384
0385
0386
0387
0388 inline const self& operator+=(difference_type n)
0389 {
0390 move_by(*this, n, false);
0391 return *this;
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401 inline self operator-(difference_type n) const
0402 {
0403 self itr(*this);
0404 move_by(itr, n);
0405
0406 return itr;
0407 }
0408
0409
0410
0411
0412
0413 inline const self& operator-=(difference_type n)
0414 {
0415 move_by(*this, n);
0416 return *this;
0417 }
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 difference_type operator-(const self&itr) const
0430 {
0431 difference_type p1, p2;
0432
0433 if (itr == end_itr_) {
0434 if (itr.inval_pos_type_ == base::IPT_BEFORE_FIRST)
0435 p2 = -1;
0436 else if (
0437 this->inval_pos_type_ == base::IPT_AFTER_LAST) {
0438 self pitr2(itr);
0439 pitr2.open();
0440 pitr2.last();
0441 p2 = pitr2.get_current_index() + 1;
0442 } else {
0443 THROW0(InvalidIteratorException);
0444 }
0445 } else
0446 p2 = itr.get_current_index();
0447
0448 if (*this == end_itr_) {
0449 if (this->inval_pos_type_ == base::IPT_BEFORE_FIRST)
0450 p1 = -1;
0451 else if (
0452 this->inval_pos_type_ == base::IPT_AFTER_LAST) {
0453 self pitr1(*this);
0454 pitr1.open();
0455 pitr1.last();
0456 p1 = pitr1.get_current_index() + 1;
0457 } else {
0458 THROW0(InvalidIteratorException);
0459 }
0460 } else
0461 p1 = this->get_current_index();
0462
0463 return (difference_type)(p1 - p2);
0464 }
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484 inline reference operator*() const
0485 {
0486 if (this->directdb_get_)
0487 update_cur_pair();
0488 return curpair_base_;
0489 }
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499 inline pointer operator->() const
0500 {
0501 if (this->directdb_get_)
0502 update_cur_pair();
0503 return &(curpair_base_);
0504 }
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515 inline value_type_wrap operator[](difference_type _Off) const
0516 {
0517 self itr(*this + _Off);
0518 return itr.curpair_base_;
0519 }
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534 inline index_type get_current_index() const
0535 {
0536 return pcsr_->get_current_index() - 1;
0537 }
0538
0539
0540
0541
0542
0543
0544
0545
0546 inline void move_to(index_type n) const
0547 {
0548 T d;
0549 int ret;
0550
0551 this->itr_status_ = pcsr_->move_to(n + 1);
0552 ret = pcsr_->get_current_data(d);
0553 dbstl_assert(ret == 0);
0554 if (this->itr_status_ == 0)
0555 update_cur_pair();
0556 }
0557
0558
0559
0560
0561
0562 virtual int refresh(bool from_db = true)
0563 {
0564
0565 if (from_db && !this->directdb_get_)
0566 this->pcsr_->update_current_key_data_from_db(
0567 DbCursorBase::SKIP_NONE);
0568 this->pcsr_->get_current_data(curpair_base_);
0569
0570 return 0;
0571 }
0572
0573
0574
0575 inline void close_cursor() const
0576 {
0577 this->pcsr_->close();
0578 }
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589 bool set_bulk_buffer(u_int32_t sz)
0590 {
0591 bool ret = this->pcsr_->set_bulk_buffer(sz);
0592 if (ret)
0593 this->bulk_retrieval_ = sz;
0594 return ret;
0595 }
0596
0597
0598
0599
0600
0601 u_int32_t get_bulk_bufsize()
0602 {
0603 this->bulk_retrieval_ = pcsr_->get_bulk_bufsize();
0604 return this->bulk_retrieval_;
0605 }
0606
0607
0608
0609 protected:
0610 typedef T value_type_base;
0611 typedef db_base_iterator<T> base;
0612 typedef index_type size_type;
0613 typedef index_type key_type;
0614 typedef T data_type;
0615
0616
0617 static self end_itr_;
0618
0619
0620
0621 mutable LazyDupCursor<TRandDbCursor> pcsr_;
0622
0623 void open() const
0624 {
0625 u_int32_t oflags = 0, oflags2 = 0;
0626 int ret;
0627 DbEnv *penv = this->owner_->get_db_env_handle();
0628
0629 oflags2 = this->owner_->get_cursor_open_flags();
0630 if (!this->read_only_ && penv != NULL) {
0631 BDBOP((penv->get_open_flags(&oflags)), ret);
0632
0633
0634 if ((oflags & DB_INIT_CDB) != 0)
0635 oflags2 |= DB_WRITECURSOR;
0636 }
0637
0638 if (!this->pcsr_) {
0639
0640 this->pcsr_.set_cursor(new TRandDbCursor(
0641 this->bulk_retrieval_,
0642 this->rmw_csr_, this->directdb_get_));
0643 }
0644 this->itr_status_ = this->pcsr_->open(this->owner_, oflags2);
0645 }
0646
0647
0648
0649 inline int first() const
0650 {
0651 int ret = 0;
0652
0653 if ((ret = pcsr_->first()) == 0)
0654 update_cur_pair();
0655 else
0656 this->itr_status_ = ret;
0657
0658 return ret;
0659 }
0660
0661
0662
0663 inline index_type last() const
0664 {
0665 index_type pos_index, lsz;
0666
0667
0668 lsz = pcsr_->last_index();
0669 if (lsz > 0) {
0670 pos_index = lsz - 1;
0671 this->itr_status_ = 0;
0672 update_cur_pair();
0673 } else {
0674 this->itr_status_ = INVALID_ITERATOR_POSITION;
0675 pos_index = INVALID_INDEX;
0676 }
0677
0678 return pos_index;
0679 }
0680
0681 void set_curpair_base(const T& d)
0682 {
0683 curpair_base_ = d;
0684 }
0685
0686
0687
0688
0689
0690
0691 virtual void update_cur_pair() const
0692 {
0693 this->pcsr_->get_current_data(curpair_base_);
0694 }
0695
0696
0697
0698
0699
0700
0701
0702
0703 void move_by(const self&itr, difference_type n, bool back = true) const
0704 {
0705 if (n == 0)
0706 return;
0707 if (!back)
0708 n = -n;
0709 if (itr == end_itr_) {
0710 if (n > 0) {
0711 itr.open();
0712 itr.last();
0713
0714
0715 if (n > 1) {
0716 itr.itr_status_ =
0717 itr.pcsr_->advance(-n + 1);
0718 if (itr.itr_status_ ==
0719 INVALID_ITERATOR_POSITION)
0720 itr.inval_pos_type_ =
0721 base::IPT_BEFORE_FIRST;
0722 }
0723 } else
0724
0725 return;
0726
0727 } else {
0728 if (n == 1)
0729 itr.itr_status_ = itr.pcsr_->prev();
0730 else if (n == -1)
0731 itr.itr_status_ = itr.pcsr_->next();
0732 else
0733 itr.itr_status_ = itr.pcsr_->advance(-n);
0734 }
0735
0736 itr.update_cur_pair();
0737 if (itr.itr_status_ != 0) {
0738 if (n > 0)
0739 itr.inval_pos_type_ = base::IPT_BEFORE_FIRST;
0740 else
0741 itr.inval_pos_type_ = base::IPT_AFTER_LAST;
0742 }
0743 }
0744
0745 private:
0746
0747 mutable T curpair_base_;
0748
0749
0750 friend class db_vector<T, ElementHolder<T> >;
0751 friend class db_vector<T, ElementRef<T> >;
0752 friend class DbCursor<index_type, T>;
0753 friend class RandDbCursor<T>;
0754 friend class ElementRef<T>;
0755 friend class ElementHolder<T>;
0756 };
0757
0758 template <Typename T>
0759 db_vector_base_iterator<T> db_vector_base_iterator<T>::end_itr_;
0760
0761
0762
0763
0764
0765
0766
0767
0768 template <class T, Typename value_type_sub>
0769 class _exported db_vector_iterator :
0770 public db_vector_base_iterator<T>
0771 {
0772 protected:
0773 typedef db_vector_iterator<T, value_type_sub> self;
0774 typedef db_recno_t index_type;
0775 using db_base_iterator<T>::replace_current_key;
0776 public:
0777 typedef T value_type;
0778 typedef ptrdiff_t difference_type;
0779 typedef difference_type distance_type;
0780 typedef value_type_sub& reference;
0781
0782
0783
0784 typedef value_type_sub value_type_wrap;
0785 typedef value_type_sub* pointer;
0786
0787
0788 typedef std::random_access_iterator_tag iterator_category;
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798 db_vector_iterator(const db_vector_iterator<T, value_type_sub>& vi)
0799 : db_vector_base_iterator<T>(vi),
0800 curpair_(vi.curpair_)
0801 {
0802 curpair_._DB_STL_SetIterator(this);
0803 }
0804
0805 explicit db_vector_iterator(db_container*powner,
0806 u_int32_t b_bulk_retrieval = 0, bool brmw = false,
0807 bool directdbget = true, bool b_read_only = false)
0808 : db_vector_base_iterator<T>(powner,
0809 b_bulk_retrieval, brmw, directdbget, b_read_only)
0810 {
0811 curpair_._DB_STL_SetIterator(this);
0812 this->read_only_ = b_read_only;
0813 this->rmw_csr_ = brmw;
0814 }
0815
0816 db_vector_iterator() : db_vector_base_iterator<T>()
0817 {
0818 curpair_._DB_STL_SetIterator(this);
0819 }
0820
0821 db_vector_iterator(const db_vector_base_iterator<T>&obj)
0822 : db_vector_base_iterator<T>(obj)
0823 {
0824 curpair_._DB_STL_CopyData(*obj);
0825 }
0826
0827 virtual ~db_vector_iterator()
0828 {
0829 this->dead_ = true;
0830 }
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857 inline self& operator++()
0858 {
0859 this->move_by(*this, 1, false);
0860 return *this;
0861 }
0862
0863
0864
0865
0866 inline self operator++(int)
0867 {
0868 self itr(*this);
0869 this->move_by(*this, 1, false);
0870
0871 return itr;
0872 }
0873
0874
0875
0876
0877 inline self& operator--()
0878 {
0879 this->move_by(*this, 1, true);
0880 return *this;
0881 }
0882
0883
0884
0885
0886 inline self operator--(int)
0887 {
0888 self itr = *this;
0889 this->move_by(*this, 1, true);
0890 return itr;
0891 }
0892
0893
0894
0895
0896
0897
0898
0899
0900 inline const self& operator=(const self&itr)
0901 {
0902 ASSIGNMENT_PREDCOND(itr)
0903 base::operator=(itr);
0904
0905 curpair_._DB_STL_CopyData(itr.curpair_);
0906 return itr;
0907 }
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919 inline self operator+(difference_type n) const
0920 {
0921 self itr(*this);
0922 this->move_by(itr, n, false);
0923 return itr;
0924 }
0925
0926
0927
0928
0929
0930
0931 inline const self& operator+=(difference_type n)
0932 {
0933 this->move_by(*this, n, false);
0934 return *this;
0935 }
0936
0937
0938
0939
0940
0941
0942
0943
0944
0945 inline self operator-(difference_type n) const
0946 {
0947 self itr(*this);
0948 this->move_by(itr, n);
0949
0950 return itr;
0951 }
0952
0953
0954
0955
0956
0957
0958 inline const self& operator-=(difference_type n)
0959 {
0960 this->move_by(*this, n);
0961 return *this;
0962 }
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975 difference_type operator-(const self&itr) const
0976 {
0977 return base::operator-(itr);
0978 }
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002 inline reference operator*() const
1003 {
1004 if (this->directdb_get_)
1005 update_cur_pair();
1006 return curpair_;
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 inline pointer operator->() const
1018 {
1019 if (this->directdb_get_)
1020 update_cur_pair();
1021 return &curpair_;
1022 }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 inline value_type_wrap operator[](difference_type _Off) const
1038 {
1039 self *itr = new self(*this + _Off);
1040
1041 value_type_sub ref(itr->curpair_);
1042 ref._DB_STL_SetDelItr();
1043 return ref;
1044 }
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 virtual int refresh(bool from_db = true)
1057 {
1058 T d;
1059
1060 if (from_db && !this->directdb_get_)
1061 this->pcsr_->update_current_key_data_from_db(
1062 DbCursorBase::SKIP_NONE);
1063 this->pcsr_->get_current_data(d);
1064 curpair_._DB_STL_SetData(d);
1065 this->set_curpair_base(d);
1066 return 0;
1067 }
1068
1069
1070 protected:
1071 typedef T value_type_base;
1072 typedef db_vector_base_iterator<T> base;
1073 typedef index_type size_type;
1074 typedef index_type key_type;
1075 typedef T data_type;
1076 typedef db_vector<T, value_type_sub> OwnerType;
1077
1078 friend class db_vector<T, value_type_sub>;
1079 friend class DbCursor<index_type, T>;
1080 friend class RandDbCursor<T>;
1081 friend class ElementRef<T>;
1082 friend class ElementHolder<T>;
1083
1084
1085
1086
1087
1088
1089 mutable value_type_sub curpair_;
1090
1091 virtual void delete_me() const
1092 {
1093 if (!this->dead_)
1094 delete this;
1095 }
1096
1097 virtual self* dup_itr() const
1098 {
1099 self *itr = new self(*this);
1100
1101
1102
1103 return itr;
1104 }
1105
1106
1107
1108
1109
1110 virtual int replace_current(const T& d)
1111 {
1112 int ret = 0;
1113
1114 if (this->read_only_) {
1115 THROW(InvalidFunctionCall, (
1116 "replace_current can't be called via a readonly iterator."));
1117 }
1118 ret = this->pcsr_->replace(d);
1119
1120 return ret;
1121 }
1122
1123
1124
1125 virtual int replace_current_key(const T&) {
1126 THROW(InvalidFunctionCall, (
1127 "replace_current_key not supported by db_vector_iterator<>"));
1128 }
1129
1130
1131
1132
1133
1134
1135 virtual void update_cur_pair() const
1136 {
1137 T t;
1138
1139 this->pcsr_->get_current_data(t);
1140 curpair_._DB_STL_CopyData(t);
1141 base::update_cur_pair();
1142 }
1143
1144
1145 };
1146
1147
1148
1149
1150
1151 template <Typename T>
1152 db_vector_base_iterator<T> operator+(typename db_vector_base_iterator<T>::
1153 difference_type n, db_vector_base_iterator<T> itr)
1154 {
1155 db_vector_base_iterator<T> i2 = itr;
1156
1157 i2 += n;
1158 return i2;
1159 }
1160
1161 template <Typename T, Typename value_type_sub>
1162 db_vector_iterator<T, value_type_sub> operator+(
1163 typename db_vector_iterator<T, value_type_sub>::
1164 difference_type n, db_vector_iterator<T, value_type_sub> itr)
1165 {
1166 db_vector_iterator<T, value_type_sub> i2 = itr;
1167
1168 i2 += n;
1169 return i2;
1170 }
1171
1172 template <Typename iterator, Typename iterator2>
1173 db_reverse_iterator<iterator, iterator2> operator+(typename
1174 db_reverse_iterator<iterator, iterator2>::difference_type n,
1175 db_reverse_iterator<iterator, iterator2> itr)
1176 {
1177 db_reverse_iterator<iterator, iterator2> i2 = itr;
1178
1179
1180
1181 i2 += n;
1182 return i2;
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 template <Typename T, Typename value_type_sub>
1218 class _exported db_vector: public db_container
1219 {
1220 private:
1221 typedef db_vector<T, value_type_sub> self;
1222 typedef db_recno_t index_type;
1223 public:
1224 typedef T value_type;
1225 typedef value_type_sub value_type_wrap;
1226 typedef value_type_sub* pointer;
1227 typedef db_vector_iterator<T, value_type_sub> iterator;
1228 typedef db_vector_base_iterator<T> const_iterator;
1229 typedef index_type size_type;
1230 typedef db_reverse_iterator<iterator, const_iterator> reverse_iterator;
1231 typedef const value_type_sub* const_pointer;
1232 typedef db_reverse_iterator<const_iterator, iterator>
1233 const_reverse_iterator;
1234
1235 typedef typename value_type_sub::content_type const_value_type;
1236
1237
1238
1239
1240
1241 typedef value_type_sub reference;
1242
1243
1244 typedef const_value_type const_reference;
1245 typedef ptrdiff_t difference_type;
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289 iterator begin(ReadModifyWriteOption rmw =
1290 ReadModifyWriteOption::no_read_modify_write(),
1291 bool readonly = false, BulkRetrievalOption bulk_read =
1292 BulkRetrievalOption::no_bulk_retrieval(),
1293 bool directdb_get = true)
1294 {
1295 bool b_rmw;
1296 u_int32_t bulk_retrieval;
1297
1298 bulk_retrieval = 0;
1299 b_rmw = (rmw == ReadModifyWriteOption::read_modify_write());
1300 if (readonly && b_rmw)
1301 b_rmw = false;
1302
1303 if (readonly && bulk_read ==
1304 BulkRetrievalOption::BulkRetrieval)
1305 bulk_retrieval = bulk_read.bulk_buf_size();
1306
1307 iterator itr((db_container*)this, bulk_retrieval, b_rmw,
1308 directdb_get, readonly);
1309
1310 open_itr(itr, readonly);
1311 itr.first();
1312
1313 return itr;
1314 }
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328 const_iterator begin(BulkRetrievalOption bulkretrieval =
1329 (BulkRetrievalOption::no_bulk_retrieval()),
1330 bool directdb_get = true) const
1331 {
1332 u_int32_t b_bulk_retrieval = (bulkretrieval ==
1333 BulkRetrievalOption::BulkRetrieval) ?
1334 bulkretrieval.bulk_buf_size() : 0;
1335
1336 const_iterator itr((db_container*)this, b_bulk_retrieval,
1337 false, directdb_get, true);
1338
1339 open_itr(itr, true);
1340 itr.first();
1341
1342 return itr;
1343 }
1344
1345
1346
1347
1348 inline iterator end()
1349 {
1350 end_itr_.owner_ = (db_container*)this;
1351 end_itr_.inval_pos_type_ = iterator::IPT_AFTER_LAST;
1352 return end_itr_;
1353 }
1354
1355
1356
1357
1358 inline const_iterator end() const
1359 {
1360 end_itr_.owner_ = (db_container*)this;
1361 end_itr_.inval_pos_type_ = iterator::IPT_AFTER_LAST;
1362 return end_itr_;
1363 }
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 reverse_iterator rbegin(
1382 ReadModifyWriteOption rmw =
1383 ReadModifyWriteOption::no_read_modify_write(),
1384 bool readonly = false, BulkRetrievalOption bulk_read =
1385 BulkRetrievalOption::no_bulk_retrieval(),
1386 bool directdb_get = true)
1387 {
1388 u_int32_t bulk_retrieval = 0;
1389
1390 reverse_iterator itr(end());
1391 itr.rmw_csr_ =
1392 (rmw == (ReadModifyWriteOption::read_modify_write()));
1393 itr.directdb_get_ = directdb_get;
1394 itr.read_only_ = readonly;
1395 itr.owner_ = (db_container*)this;
1396
1397
1398 if (readonly &&
1399 bulk_read == BulkRetrievalOption::BulkRetrieval)
1400 bulk_retrieval = bulk_read.bulk_buf_size();
1401 itr.bulk_retrieval_ = bulk_retrieval;
1402
1403 return itr;
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418 const_reverse_iterator rbegin(BulkRetrievalOption bulkretrieval =
1419 BulkRetrievalOption(BulkRetrievalOption::no_bulk_retrieval()),
1420 bool directdb_get = true) const
1421 {
1422 const_reverse_iterator itr(end());
1423 itr.bulk_retrieval_ =
1424 (bulkretrieval == (BulkRetrievalOption::BulkRetrieval) ?
1425 bulkretrieval.bulk_buf_size() : 0);
1426
1427 itr.directdb_get_ = directdb_get;
1428 itr.read_only_ = true;
1429 itr.owner_ = (db_container*)this;
1430
1431 return itr;
1432 }
1433
1434
1435
1436
1437 inline reverse_iterator rend()
1438 {
1439 reverse_iterator itr;
1440
1441 itr.itr_status_ = INVALID_ITERATOR_POSITION;
1442 itr.owner_ = (db_container*)this;
1443 itr.inval_pos_type_ = iterator::IPT_BEFORE_FIRST;
1444 return itr;
1445 }
1446
1447
1448
1449
1450 inline const_reverse_iterator rend() const
1451 {
1452 const_reverse_iterator itr;
1453
1454 itr.itr_status_ = INVALID_ITERATOR_POSITION;
1455 itr.owner_ = (db_container*)this;
1456 itr.inval_pos_type_ = iterator::IPT_BEFORE_FIRST;
1457 return itr;
1458 }
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470 size_type size() const
1471 {
1472 index_type sz;
1473
1474 try {
1475 this->begin_txn();
1476 const_iterator derefitr;
1477 init_itr(derefitr);
1478 open_itr(derefitr, true);
1479 sz = derefitr.last() + 1;
1480 this->commit_txn();
1481 return (size_type)sz;
1482 } catch (...) {
1483 this->abort_txn();
1484 throw;
1485 }
1486 }
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498 inline size_type max_size() const
1499 {
1500 return SIZE_T_MAX;
1501 }
1502
1503
1504 inline size_type capacity() const
1505 {
1506 return SIZE_T_MAX;
1507 }
1508
1509
1510
1511
1512 inline bool empty() const
1513 {
1514 const_iterator itr = begin();
1515 return itr.itr_status_ == INVALID_ITERATOR_POSITION;
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533 inline reference operator[](index_type n)
1534 {
1535 iterator derefitr, *pitr;
1536
1537 init_itr(derefitr);
1538 open_itr(derefitr);
1539 if (n == INVALID_INDEX)
1540 n = derefitr.last();
1541 derefitr.move_to(n);
1542
1543 pitr = new iterator(derefitr);
1544 reference ref(pitr->curpair_);
1545 ref._DB_STL_SetDelItr();
1546 return ref;
1547 }
1548
1549
1550
1551
1552
1553
1554
1555 inline const_reference operator[](index_type n) const
1556 {
1557 const_iterator derefitr;
1558
1559 init_itr(derefitr);
1560 open_itr(derefitr);
1561 if (n == INVALID_INDEX)
1562 n = derefitr.last();
1563 derefitr.move_to(n);
1564
1565
1566 return (*derefitr);
1567 }
1568
1569
1570
1571
1572
1573
1574 inline reference at(index_type n)
1575 {
1576 return (*this)[n];
1577 }
1578
1579
1580
1581
1582
1583
1584
1585
1586 inline const_reference at(index_type n) const
1587 {
1588 return (*this)[n];
1589 }
1590
1591
1592
1593
1594 inline reference front()
1595 {
1596 iterator itr, *pitr;
1597
1598 init_itr(itr);
1599 open_itr(itr);
1600 itr.first();
1601
1602 pitr = new iterator(itr);
1603 reference ref(pitr->curpair_);
1604 ref._DB_STL_SetDelItr();
1605 return ref;
1606 }
1607
1608
1609
1610
1611
1612
1613 inline const_reference front() const
1614 {
1615 const_iterator itr;
1616
1617 init_itr(itr);
1618 open_itr(itr);
1619 itr.first();
1620 return (*itr);
1621 }
1622
1623
1624
1625
1626 inline reference back()
1627 {
1628 iterator itr, *pitr;
1629
1630 init_itr(itr);
1631 open_itr(itr);
1632 itr.last();
1633
1634 pitr = new iterator(itr);
1635 reference ref(pitr->curpair_);
1636 ref._DB_STL_SetDelItr();
1637 return ref;
1638 }
1639
1640
1641
1642
1643
1644
1645 inline const_reference back() const
1646 {
1647 const_iterator itr;
1648
1649 init_itr(itr);
1650 open_itr(itr);
1651 itr.last();
1652 return (*itr);
1653 }
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671 explicit db_vector(Db* dbp = NULL, DbEnv *penv = NULL)
1672 : base(dbp, penv)
1673 {
1674 const char *errmsg;
1675
1676 this->open_db_handles(dbp, penv, DB_RECNO, DB_CREATE |
1677 DB_THREAD, DB_RENUMBER);
1678 if ((errmsg = verify_config(dbp, penv)) != NULL) {
1679 THROW(InvalidArgumentException, ("Db*", errmsg));
1680 }
1681 this->set_db_handle_int(dbp, penv);
1682 }
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695 explicit db_vector(size_type n, const T& val = T(), Db* dbp = NULL,
1696 DbEnv *penv = NULL) : base(dbp, penv)
1697 {
1698 size_type i;
1699 const char *errmsg;
1700
1701 this->open_db_handles(dbp, penv, DB_RECNO, DB_CREATE |
1702 DB_THREAD, DB_RENUMBER);
1703 if ((errmsg = verify_config(dbp, penv)) != NULL) {
1704 THROW(InvalidArgumentException, ("Db*", errmsg));
1705 }
1706 this->set_db_handle_int(dbp, penv);
1707
1708 this->begin_txn();
1709
1710
1711
1712
1713 try {
1714 for (i = 0; i < n; i++)
1715 push_back(val);
1716 } catch (...) {
1717 this->abort_txn();
1718 throw;
1719 }
1720 this->commit_txn();
1721 }
1722
1723
1724
1725
1726
1727
1728 db_vector(const self& x) : db_container(x)
1729 {
1730
1731
1732
1733 verify_db_handles(x);
1734 this->set_db_handle_int(this->clone_db_config(
1735 x.get_db_handle()), x.get_db_env_handle());
1736
1737 this->begin_txn();
1738
1739 try {
1740 copydb(x);
1741 } catch (...) {
1742 this->abort_txn();
1743 throw;
1744 }
1745 this->commit_txn();
1746 }
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 template <class InputIterator>
1763 db_vector(Db*dbp, DbEnv *penv,
1764 InputIterator first, InputIterator last) : base(dbp, penv)
1765 {
1766 const char *errmsg;
1767
1768 this->open_db_handles(dbp, penv, DB_RECNO, DB_CREATE |
1769 DB_THREAD, DB_RENUMBER);
1770 if ((errmsg = verify_config(dbp, penv)) != NULL)
1771 THROW(InvalidArgumentException, ("Db*", errmsg));
1772
1773 this->set_db_handle_int(dbp, penv);
1774
1775 this->begin_txn();
1776 try {
1777 push_range(first, last);
1778 } catch (...) {
1779 this->abort_txn();
1780 throw;
1781 }
1782
1783 this->commit_txn();
1784 }
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795 db_vector(const_iterator first, const_iterator last,
1796 Db*dbp = NULL, DbEnv *penv = NULL) : base(dbp, penv)
1797 {
1798 const char *errmsg;
1799
1800 this->open_db_handles(dbp, penv, DB_RECNO, DB_CREATE |
1801 DB_THREAD, DB_RENUMBER);
1802 if ((errmsg = verify_config(dbp, penv)) != NULL)
1803 THROW(InvalidArgumentException, ("Db*", errmsg));
1804 this->set_db_handle_int(dbp, penv);
1805
1806 this->begin_txn();
1807 try {
1808 push_range(first, last);
1809 } catch (...) {
1810 this->abort_txn();
1811 throw;
1812 }
1813
1814 this->commit_txn();
1815 }
1816
1817
1818
1819
1820
1821 virtual ~db_vector() {
1822 }
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833 const self& operator=(const self& x)
1834 {
1835 ASSIGNMENT_PREDCOND(x)
1836
1837 db_container::operator =(x);
1838 verify_db_handles(x);
1839 this->begin_txn();
1840 try {
1841 copydb(x);
1842 } catch (...) {
1843 this->abort_txn();
1844 throw;
1845 }
1846
1847 this->commit_txn();
1848 return x;
1849 }
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863 template <Typename T2, Typename T3>
1864 bool operator==(const db_vector<T2, T3>& v2) const
1865 {
1866 bool ret;
1867 size_t sz;
1868
1869 verify_db_handles(v2);
1870 typename self::iterator i1;
1871 typename db_vector<T2, T3>::iterator i2;
1872
1873 try {
1874 this->begin_txn();
1875 if ((sz = this->size()) != v2.size()) {
1876 ret = false;
1877 this->commit_txn();
1878 return ret;
1879 }
1880 if (sz == 0) {
1881 ret = true;
1882 this->commit_txn();
1883 return ret;
1884 }
1885
1886
1887 for (i1 = begin(), i2 = v2.begin(); i1 != end() &&
1888 i2 != v2.end(); ++i1, ++i2)
1889 if (!((T)(*i1) == (T2)(*i2))) {
1890 ret = false;
1891 this->commit_txn();
1892 return ret;
1893 }
1894
1895
1896 ret = true;
1897 this->commit_txn();
1898 return ret;
1899 } catch (...) {
1900 this->abort_txn();
1901 throw;
1902 }
1903 }
1904
1905
1906
1907
1908
1909
1910
1911 template <Typename T2, Typename T3>
1912 bool operator!=(const db_vector<T2, T3>& v2) const
1913 {
1914 return !this->operator==(v2);
1915 }
1916
1917
1918
1919
1920
1921
1922 bool operator==(const self& v2) const
1923 {
1924 bool ret;
1925
1926 COMPARE_CHECK(v2)
1927 verify_db_handles(v2);
1928
1929 try {
1930 this->begin_txn();
1931 if (this->size() != v2.size()) {
1932 ret = false;
1933 this->commit_txn();
1934 return ret;
1935 }
1936 typename self::const_iterator i1;
1937 typename self::const_iterator i2;
1938
1939 for (i1 = begin(), i2 = v2.begin(); i1 != end() &&
1940 i2 != v2.end(); ++i1, ++i2)
1941 if (!(*i1 == *i2)) {
1942 ret = false;
1943 this->commit_txn();
1944 return ret;
1945 }
1946
1947
1948 ret = true;
1949 this->commit_txn();
1950 return ret;
1951 } catch (...) {
1952 this->abort_txn();
1953 throw;
1954 }
1955 }
1956
1957
1958
1959
1960
1961
1962
1963 bool operator!=(const self& v2) const
1964 {
1965 return !this->operator==(v2);
1966 }
1967
1968
1969
1970
1971
1972
1973
1974 bool operator<(const self& v2) const
1975 {
1976 bool ret;
1977
1978 if (this == &v2)
1979 return false;
1980
1981 verify_db_handles(v2);
1982 typename self::const_iterator i1;
1983 typename self::const_iterator i2;
1984 size_t s1, s2, sz, i;
1985
1986 try {
1987 this->begin_txn();
1988 s1 = this->size();
1989 s2 = v2.size();
1990 sz = s1 < s2 ? s1 : s2;
1991
1992
1993 for (i1 = begin(), i = 0, i2 = v2.begin();
1994 i < sz;
1995 ++i1, ++i2, ++i) {
1996 if (*i1 == *i2)
1997 continue;
1998 else {
1999 if (*i1 < *i2)
2000 ret = true;
2001 else
2002 ret = false;
2003 this->commit_txn();
2004 return ret;
2005 }
2006 }
2007
2008 ret = s1 < s2;
2009 this->commit_txn();
2010 return ret;
2011 } catch (...) {
2012 this->abort_txn();
2013 throw;
2014 }
2015 }
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026 inline void resize(size_type n, T t = T())
2027 {
2028 size_t i, sz;
2029
2030 try {
2031 begin_txn();
2032 if (n == (sz = size())) {
2033 commit_txn();
2034 return;
2035 }
2036
2037 if (n < sz)
2038 erase(begin() + n, end());
2039 else
2040 for (i = sz; i < n; i++)
2041 push_back(t);
2042 commit_txn();
2043 } catch (...) {
2044 abort_txn();
2045 throw;
2046 }
2047 }
2048
2049
2050
2051
2052
2053
2054 inline void reserve(size_type )
2055 {
2056 }
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081 template <class InputIterator>
2082 void assign ( InputIterator first, InputIterator last,
2083 bool b_truncate = true)
2084 {
2085 if (this->get_db_handle() == NULL)
2086 return;
2087
2088 this->begin_txn();
2089 try {
2090 clear(b_truncate);
2091 push_range(first, last);
2092 } catch (...) {
2093 this->abort_txn();
2094 throw;
2095 }
2096 this->commit_txn();
2097 }
2098
2099
2100
2101
2102
2103 void assign(const_iterator first, const_iterator last,
2104 bool b_truncate = true)
2105 {
2106 if (this->get_db_handle() == NULL)
2107 return;
2108
2109 this->begin_txn();
2110 try {
2111 clear(b_truncate);
2112 push_range(first, last);
2113
2114 } catch (...) {
2115 this->abort_txn();
2116 throw;
2117 }
2118 this->commit_txn();
2119 }
2120
2121
2122
2123
2124
2125
2126 void assign ( size_type n, const T& u, bool b_truncate = true)
2127 {
2128 if (this->get_db_handle() == NULL)
2129 return;
2130
2131 this->begin_txn();
2132 try {
2133 clear(b_truncate);
2134 size_t i;
2135 for (i = 0; i < n; i++)
2136 push_back(u);
2137 } catch (...) {
2138 this->abort_txn();
2139 throw;
2140 }
2141
2142 this->commit_txn();
2143 }
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 inline void push_back ( const T& x )
2157 {
2158 index_type k0 = 0;
2159 int ret;
2160
2161
2162 DataItem dt(x, false), k(k0, true);
2163
2164
2165 BDBOP(this->get_db_handle()->put(ResourceManager::instance()->
2166 current_txn(this->get_db_env_handle()),
2167 &(k.get_dbt()), &(dt.get_dbt()), DB_APPEND), ret);
2168 }
2169
2170
2171
2172
2173
2174 void pop_back ()
2175 {
2176 try {
2177 iterator derefitr;
2178
2179 this->begin_txn();
2180 init_itr(derefitr);
2181 open_itr(derefitr);
2182 derefitr.last();
2183 derefitr.pcsr_->del();
2184 this->commit_txn();
2185 } catch(...) {
2186 this->abort_txn();
2187 throw;
2188 }
2189 }
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207 void push_front (const T& x)
2208 {
2209 int flag, ret;
2210
2211 try {
2212 this->begin_txn();
2213 iterator derefitr;
2214 init_itr(derefitr);
2215 open_itr(derefitr);
2216
2217 ret = derefitr.first();
2218 if (ret < 0)
2219 flag = DB_KEYLAST;
2220 else
2221 flag = DB_BEFORE;
2222 derefitr.pcsr_->insert(x, flag);
2223 this->commit_txn();
2224 } catch(...) {
2225 this->abort_txn();
2226 throw;
2227 }
2228 }
2229
2230
2231
2232
2233 void pop_front ()
2234 {
2235 try {
2236 this->begin_txn();
2237 iterator derefitr;
2238 init_itr(derefitr);
2239 open_itr(derefitr);
2240 derefitr.first();
2241 derefitr.pcsr_->del();
2242 this->commit_txn();
2243 } catch(...) {
2244 this->abort_txn();
2245 throw;
2246 }
2247
2248 }
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269 iterator insert (iterator pos, const T& x)
2270 {
2271 u_int32_t flag;
2272 bool isempty;
2273
2274 make_insert_args(pos, flag, isempty);
2275
2276 pos.pcsr_->insert(x, flag);
2277 pos.update_cur_pair();
2278
2279 return pos;
2280 }
2281
2282
2283
2284
2285
2286 void insert (iterator pos, size_type n, const T& x)
2287 {
2288 u_int32_t flag;
2289 size_t i;
2290 bool isempty;
2291
2292 make_insert_args(pos, flag, isempty);
2293
2294 for (i = 0; i < n; i++) {
2295 pos.pcsr_->insert(x, flag);
2296 pos.update_cur_pair();
2297
2298
2299
2300
2301
2302 if (flag == DB_BEFORE)
2303 ++pos;
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314 if (flag == DB_KEYLAST) {
2315 if(isempty)
2316 flag = DB_AFTER;
2317 else
2318
2319
2320
2321
2322 flag = DB_BEFORE;
2323 }
2324 }
2325 }
2326
2327
2328
2329
2330
2331
2332
2333
2334 template <class InputIterator>
2335 void insert (iterator pos, InputIterator first, InputIterator last)
2336 {
2337 u_int32_t flag;
2338 InputIterator itr;
2339 bool isempty;
2340
2341 make_insert_args(pos, flag, isempty);
2342
2343
2344
2345
2346
2347 for (itr = first; itr != last; ++itr) {
2348 pos.pcsr_->insert(*itr, flag);
2349 pos.update_cur_pair();
2350
2351
2352
2353
2354
2355 if (flag == DB_BEFORE)
2356 ++pos;
2357
2358
2359
2360
2361 if (flag == DB_KEYLAST) {
2362
2363 if(isempty)
2364 flag = DB_AFTER;
2365 else
2366
2367
2368
2369
2370 flag = DB_BEFORE;
2371 }
2372 }
2373 }
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383 void insert (iterator pos, const_iterator first, const_iterator last)
2384 {
2385 u_int32_t flag;
2386 iterator itr;
2387 bool isempty;
2388
2389 make_insert_args(pos, flag, isempty);
2390
2391 for (itr = first; itr != last; ++itr) {
2392 pos.pcsr_->insert(*itr, flag);
2393 pos.update_cur_pair();
2394
2395
2396
2397
2398
2399 if (flag == DB_BEFORE)
2400 ++pos;
2401
2402
2403
2404
2405 if (flag == DB_KEYLAST) {
2406
2407 if(isempty)
2408 flag = DB_AFTER;
2409 else
2410 flag = DB_BEFORE;
2411 }
2412 }
2413 }
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424 inline iterator erase (iterator pos)
2425 {
2426 if (pos == end_itr_)
2427 return pos;
2428 pos.pcsr_->del();
2429 ++pos;
2430
2431 return pos;
2432 }
2433
2434
2435
2436
2437
2438 iterator erase (iterator first, iterator last)
2439 {
2440 iterator itr;
2441 int ret = 0;
2442 Dbt k, d;
2443
2444
2445
2446
2447 for (itr = first; itr != last && ret == 0; ++itr) {
2448 if (itr == end_itr_)
2449 return itr;
2450 ret = itr.pcsr_->del();
2451 }
2452 return itr;
2453 }
2454
2455
2456
2457
2458
2459
2460
2461 void swap (self& vec)
2462 {
2463 T tmp;
2464 size_t sz, vsz, i, j, m;
2465 self& me = *this;
2466 self *longer, *shorter;
2467
2468 verify_db_handles(vec);
2469 this->begin_txn();
2470 try {
2471 sz = this->size();
2472 vsz = vec.size();
2473
2474 for (i = 0; (i < sz) && (i < vsz); i++) {
2475 tmp = me[(index_type)i];
2476 me[(index_type)i] = vec[(index_type)i];
2477 vec[(index_type)i] = tmp;
2478 }
2479
2480
2481
2482
2483 if (sz == vsz)
2484 return;
2485 else if (sz < vsz) {
2486 longer = &vec;
2487 shorter = &me;
2488 j = vsz;
2489 } else {
2490 longer = &me;
2491 shorter = &vec;
2492 j = sz;
2493 }
2494
2495 self &lv = *longer;
2496 self &sv = *shorter;
2497 m = i;
2498 for (; i < j; i++)
2499 sv.push_back(lv[(index_type)i]);
2500
2501 typename self::iterator itr1 =
2502 lv.begin() + (int)m, itr2 = lv.end();
2503
2504 lv.erase(itr1, itr2);
2505 } catch (...) {
2506 this->abort_txn();
2507 throw;
2508 }
2509 this->commit_txn();
2510 }
2511
2512
2513
2514
2515
2516
2517
2518 void clear(bool b_truncate = true)
2519 {
2520 int ret;
2521 u_int32_t flag;
2522 DbEnv *penv = this->get_db_handle()->get_env();
2523
2524 if (b_truncate) {
2525 ResourceManager::instance()->close_db_cursors(
2526 this->get_db_handle());
2527
2528 BDBOP2(this->get_db_handle()->truncate(
2529 ResourceManager::instance()->current_txn(penv),
2530 NULL, 0), ret, this->abort_txn());
2531 } else {
2532 ReadModifyWriteOption brmw(
2533 ReadModifyWriteOption::no_read_modify_write());
2534
2535 BDBOP(penv->get_open_flags(&flag), ret);
2536
2537
2538 if ((flag & DB_INIT_LOCK) || (flag & DB_INIT_CDB) ||
2539 (flag & DB_INIT_TXN))
2540 brmw =
2541 ReadModifyWriteOption::read_modify_write();
2542
2543 try {
2544 this->begin_txn();
2545 erase(begin(brmw, false), end());
2546 this->commit_txn();
2547 } catch (...) {
2548 this->abort_txn();
2549 throw;
2550 }
2551 }
2552 }
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565 void remove(const T& value)
2566 {
2567 iterator i;
2568
2569 try {
2570 begin_txn();
2571 for (i = begin(); i != end(); ++i)
2572 if (*i == value)
2573 erase(i);
2574 commit_txn();
2575 } catch (...) {
2576 abort_txn();
2577 throw;
2578 }
2579 }
2580
2581
2582
2583
2584
2585
2586 template <class Predicate>
2587 void remove_if(Predicate pred)
2588 {
2589 iterator i;
2590
2591 try {
2592 begin_txn();
2593 for (i = begin(); i != end(); ++i)
2594 if (pred(*i))
2595 erase(i);
2596 commit_txn();
2597 } catch (...) {
2598 abort_txn();
2599 throw;
2600 }
2601 }
2602
2603
2604
2605
2606
2607
2608 void merge(self& x)
2609 {
2610 DbstlListSpecialOps<T, value_type_sub> obj(this);
2611 obj.merge(x);
2612 }
2613
2614
2615
2616
2617
2618
2619
2620
2621 template <class Compare>
2622 void merge(self& x, Compare comp)
2623 {
2624 verify_db_handles(x);
2625 iterator itr, itrx;
2626
2627 try {
2628 begin_txn();
2629 for (itr = begin(), itrx = x.begin();
2630 itr != end_itr_ && itrx != x.end();) {
2631 if (!comp(*itr, *itrx)) {
2632 insert(itr, *itrx);
2633 ++itrx;
2634 } else
2635 ++itr;
2636 }
2637 if (itr == end_itr_ && itrx != x.end())
2638 insert(itr, itrx, x.end());
2639 x.clear();
2640 commit_txn();
2641 } catch (...) {
2642 abort_txn();
2643 throw;
2644 }
2645 }
2646
2647
2648
2649
2650
2651 void unique()
2652 {
2653 DbstlListSpecialOps<T, value_type_sub> obj(this);
2654 obj.unique();
2655 }
2656
2657
2658
2659
2660
2661
2662 template <class BinaryPredicate>
2663 void unique(BinaryPredicate binary_pred)
2664 {
2665 DbstlListSpecialOps<T, value_type_sub> obj(this);
2666 obj.unique(binary_pred);
2667 }
2668
2669
2670
2671
2672
2673 void sort()
2674 {
2675 DbstlListSpecialOps<T, value_type_sub> obj(this);
2676 obj.sort();
2677 }
2678
2679
2680
2681
2682
2683
2684 template <class Compare>
2685 void sort(Compare comp)
2686 {
2687 DbstlListSpecialOps<T, value_type_sub> obj(this);
2688 obj.sort(comp);
2689 }
2690
2691
2692
2693
2694
2695 void reverse()
2696 {
2697 try {
2698 self tmp;
2699 const self &cthis = *this;
2700 const_reverse_iterator ri;
2701
2702 begin_txn();
2703 for (ri = cthis.rbegin(BulkRetrievalOption::
2704 bulk_retrieval()); ri != rend(); ++ri)
2705 tmp.push_back(*ri);
2706 assign(tmp.begin(), tmp.end());
2707 commit_txn();
2708 } catch (...) {
2709 abort_txn();
2710 throw;
2711 }
2712 }
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725 void splice (iterator position, self& x)
2726 {
2727 verify_db_handles(x);
2728 try {
2729 begin_txn();
2730 insert(position, x.begin(), x.end());
2731 x.clear();
2732 commit_txn();
2733 } catch (...) {
2734 abort_txn();
2735 throw;
2736 }
2737 }
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751 void splice (iterator position, self& x, iterator i)
2752 {
2753 verify_db_handles(x);
2754 try {
2755 begin_txn();
2756 assert(!(i == x.end()));
2757 insert(position, *i);
2758 x.erase(i);
2759 commit_txn();
2760 } catch (...) {
2761 abort_txn();
2762 throw;
2763 }
2764 }
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779 void splice (iterator position, self& x, iterator first, iterator last)
2780 {
2781 verify_db_handles(x);
2782 try {
2783 begin_txn();
2784 insert(position, first, last);
2785 x.erase(first, last);
2786 commit_txn();
2787 } catch (...) {
2788 abort_txn();
2789 throw;
2790 }
2791 }
2792
2793
2794
2795 private:
2796 typedef db_vector_iterator<T, value_type_sub> iterator_type;
2797 typedef db_container base;
2798 friend class db_vector_iterator<T, value_type_sub>;
2799 friend class db_vector_base_iterator<T>;
2800 friend class db_reverse_iterator<iterator, const_iterator>;
2801 friend class db_reverse_iterator<const_iterator, iterator>;
2802 friend class DbstlListSpecialOps<T, value_type_sub>;
2803
2804
2805 inline void copydb(const self&x)
2806 {
2807 const_iterator itr;
2808
2809
2810
2811 clear(false);
2812 for (itr = x.begin(); itr != x.end(); ++itr)
2813 push_back(*itr);
2814 }
2815
2816 static iterator end_itr_;
2817
2818 template <Typename InputIterator>
2819 inline void push_range(InputIterator& first, InputIterator& last)
2820 {
2821 InputIterator itr;
2822
2823 for (itr = first; itr != last; ++itr)
2824 push_back(*itr);
2825 }
2826
2827 inline void push_range(const_iterator& first, const_iterator& last)
2828 {
2829 const_iterator itr;
2830
2831 for (itr = first; itr != last; ++itr)
2832 push_back(*itr);
2833
2834 }
2835
2836
2837 inline void end_to_last(const const_iterator& pos) const
2838 {
2839 if (pos != end_itr_)
2840 return;
2841 pos.pcsr_.set_cursor(new TRandDbCursor());
2842 open_itr(pos);
2843 pos.last();
2844 }
2845
2846
2847 void make_insert_args(iterator& pos, u_int32_t& flag, bool &isempty)
2848 {
2849 isempty = false;
2850 if (pos.itr_status_ == INVALID_ITERATOR_POSITION) {
2851 ((self*)pos.owner_)->end_to_last(pos);
2852
2853 if (((self*)pos.owner_)->empty()) {
2854 flag = DB_KEYLAST;
2855 isempty = true;
2856 } else
2857
2858 flag = DB_AFTER;
2859 } else
2860 flag = DB_BEFORE;
2861 }
2862
2863
2864
2865 void open_itr(const const_iterator&itr, bool readonly = false) const
2866 {
2867 u_int32_t oflags = 0;
2868 int ret;
2869 DbEnv *penv = this->get_db_handle()->get_env();
2870
2871 itr.owner_ = (db_container*)this;
2872 if (!readonly && penv != NULL) {
2873 BDBOP((penv->get_open_flags(&oflags)), ret);
2874
2875
2876 if ((oflags & DB_INIT_CDB) != 0)
2877 ((self *)this)->set_cursor_open_flags(
2878 this->get_cursor_open_flags() |
2879 DB_WRITECURSOR);
2880 }
2881 if (!itr.pcsr_)
2882 itr.pcsr_.set_cursor(new TRandDbCursor(
2883 itr.bulk_retrieval_,
2884 itr.rmw_csr_, itr.directdb_get_));
2885 itr.itr_status_ = itr.pcsr_->open((db_container*)this,
2886 this->get_cursor_open_flags());
2887 }
2888
2889 void open_itr(const reverse_iterator &itr, bool readonly = false) const
2890 {
2891 u_int32_t oflags = 0;
2892 int ret;
2893 DbEnv *penv = this->get_db_handle()->get_env();
2894
2895 itr.owner_ = (db_container*)this;
2896 if (!readonly && penv != NULL) {
2897 BDBOP((penv->get_open_flags(&oflags)) , ret);
2898
2899
2900 if ((oflags & DB_INIT_CDB) != 0)
2901 ((self *)this)->set_cursor_open_flags(
2902 this->get_cursor_open_flags() |
2903 DB_WRITECURSOR);
2904 }
2905 if (!itr.pcsr_)
2906 itr.pcsr_.set_cursor(new TRandDbCursor(
2907 itr.bulk_retrieval_,
2908 itr.rmw_csr_, itr.directdb_get_));
2909 itr.itr_status_ = itr.pcsr_->open((db_container*)this,
2910 this->get_cursor_open_flags());
2911 itr.update_cur_pair();
2912 }
2913
2914 inline void init_itr(const_iterator &itr) const
2915 {
2916 itr.owner_ = (db_container*)this;
2917 }
2918
2919
2920
2921
2922
2923 virtual const char* verify_config(Db*db, DbEnv*env) const
2924 {
2925 u_int32_t oflags, sflags, oflags2;
2926 const char *errmsg = NULL;
2927 int ret;
2928 DBTYPE dbtype;
2929
2930 errmsg = db_container::verify_config(db, env);
2931 if (errmsg)
2932 return errmsg;
2933
2934 oflags = sflags = oflags2 = 0;
2935 BDBOP((db->get_type(&dbtype)) || (db->get_open_flags(&oflags))
2936 || (db->get_flags(&sflags)) ||
2937 (env->get_open_flags(&oflags2)), ret);
2938
2939 if (dbtype != DB_RECNO)
2940 errmsg = "Must use DB_RECNO type of database.";
2941
2942
2943
2944
2945 return errmsg;
2946 }
2947
2948
2949 };
2950
2951 template <Typename T, Typename value_type_sub>
2952 typename db_vector<T, value_type_sub>::iterator
2953 db_vector<T, value_type_sub>::end_itr_;
2954
2955
2956 template <Typename T, Typename value_type_sub>
2957 void swap(db_vector<T, value_type_sub>&v1, db_vector<T, value_type_sub>&v2)
2958 {
2959 v1.swap(v2);
2960 }
2961
2962
2963
2964 template <typename T, typename T2>
2965 class _exported DbstlListSpecialOps
2966 {
2967 typedef db_vector<T, T2> partner;
2968 typedef typename partner::iterator iterator;
2969 partner *that;
2970 public:
2971 DbstlListSpecialOps(partner *that1)
2972 {
2973 that = that1;
2974 }
2975
2976 template <class BinaryPredicate>
2977 void unique(BinaryPredicate binary_pred)
2978 {
2979 T t, t2;
2980
2981 try {
2982 that->begin_txn();
2983 iterator i = that->begin();
2984 t2 = *i;
2985 ++i;
2986 for (; i != that->end_itr_; ++i) {
2987 if (binary_pred((t = *i), t2))
2988 that->erase(i);
2989 else
2990 t2 = t;
2991 }
2992 that->commit_txn();
2993 } catch (...) {
2994 that->abort_txn();
2995 throw;
2996 }
2997 }
2998
2999 void unique()
3000 {
3001 T t, t2;
3002
3003 try {
3004 that->begin_txn();
3005 iterator i = that->begin();
3006 t2 = *i;
3007 ++i;
3008 for (; i != that->end_itr_; ++i) {
3009 if ((t = *i) == t2)
3010 that->erase(i);
3011 else
3012 t2 = t;
3013 }
3014 that->commit_txn();
3015 } catch (...) {
3016 that->abort_txn();
3017 throw;
3018 }
3019 }
3020
3021
3022 void merge(partner& x)
3023 {
3024 that->verify_db_handles(x);
3025 T b;
3026 iterator itr, itrx;
3027
3028 try {
3029 that->begin_txn();
3030 for (itr = that->begin(), itrx = x.begin();
3031 itr != that->end_itr_ && itrx != x.end();) {
3032 if (*itr > (b = *itrx)) {
3033 that->insert(itr, b);
3034 ++itrx;
3035 } else
3036 ++itr;
3037 }
3038 if (itr == that->end_itr_ && itrx != x.end())
3039 that->insert(itr, itrx, x.end());
3040 x.clear();
3041 that->commit_txn();
3042 } catch (...) {
3043 that->abort_txn();
3044 throw;
3045 }
3046 }
3047
3048
3049 void sort()
3050 {
3051 try {
3052 that->begin_txn();
3053 std::sort(that->begin(), that->end());
3054 that->commit_txn();
3055 } catch (...) {
3056 that->abort_txn();
3057 throw;
3058 }
3059 }
3060
3061
3062 template <class Compare>
3063 void sort(Compare comp)
3064 {
3065 try {
3066 that->begin_txn();
3067 std::sort(that->begin(), that->end(), comp);
3068 that->commit_txn();
3069 } catch (...) {
3070 that->abort_txn();
3071 throw;
3072 }
3073 }
3074
3075
3076
3077 };
3078
3079
3080 template <typename T, typename T2>
3081 class _exported DbstlListSpecialOps<T*, T2>
3082 {
3083 typedef db_vector<T*, T2> partner;
3084 typedef typename partner::iterator iterator;
3085 typedef typename partner::const_iterator const_iterator;
3086 partner *that;
3087 DbstlElemTraits<T> *inst;
3088 typename DbstlElemTraits<T>::ElemSizeFunct sizef;
3089 typename DbstlElemTraits<T>::SequenceLenFunct seqlenf;
3090 typename DbstlElemTraits<T>::SequenceCopyFunct seqcopyf;
3091 typename DbstlElemTraits<T>::SequenceCompareFunct seqcmpf;
3092
3093 void seq_assign(T *&dest, const T*src)
3094 {
3095 size_t sz = 0;
3096 size_t seql = seqlenf(src);
3097
3098
3099 if (sizef == NULL)
3100 sz = sizeof(T) * (seql + 1);
3101 else {
3102
3103 for (size_t i = 0; i < seql; i++)
3104 sz += sizef(src[i]);
3105
3106
3107 T tmp;
3108 sz += sizef(tmp);
3109 }
3110 dest = (T *)DbstlReAlloc(dest, sz);
3111 memset(dest, 0, sz);
3112 seqcopyf(dest, src, seql);
3113 }
3114
3115 template <typename T4>
3116 class CompareInt
3117 {
3118 typename DbstlElemTraits<T4>::SequenceCompareFunct cmpf;
3119 public:
3120 CompareInt(typename DbstlElemTraits<T4>::
3121 SequenceCompareFunct cmpf1)
3122 {
3123 cmpf = cmpf1;
3124 }
3125
3126 bool operator()(const std::basic_string<T4,
3127 DbstlElemTraits<T4> >
3128 &a, const std::basic_string<T, DbstlElemTraits<T4> > &b)
3129 {
3130 return cmpf(a.c_str(), b.c_str());
3131 }
3132
3133 };
3134
3135 template <typename T4, typename Compare>
3136 class CompareInt2
3137 {
3138 public:
3139 Compare comp_;
3140
3141 CompareInt2(Compare comp)
3142 {
3143 comp_ = comp;
3144 }
3145
3146 bool operator()(const std::basic_string<T4,
3147 DbstlElemTraits<T4> >
3148 &s1, const std::basic_string<T4, DbstlElemTraits<T4> >& s2)
3149 {
3150 return comp_(s1.c_str(), s2.c_str());
3151 }
3152
3153 };
3154 public:
3155 DbstlListSpecialOps(partner *that1)
3156 {
3157 that = that1;
3158
3159
3160
3161
3162
3163 DbstlElemTraits<char> * cstarinst =
3164 DbstlElemTraits<char>::instance();
3165 cstarinst->set_sequence_len_function(dbstl_strlen);
3166 cstarinst->set_sequence_copy_function(dbstl_strcpy);
3167 cstarinst->set_sequence_compare_function(dbstl_strcmp);
3168 cstarinst->set_sequence_n_compare_function(dbstl_strncmp);
3169
3170 DbstlElemTraits<wchar_t> *wcstarinst =
3171 DbstlElemTraits<wchar_t>::instance();
3172 wcstarinst->set_sequence_copy_function(dbstl_wcscpy);
3173 wcstarinst->set_sequence_len_function(dbstl_wcslen);
3174 wcstarinst->set_sequence_compare_function(dbstl_wcscmp);
3175 wcstarinst->set_sequence_n_compare_function(dbstl_wcsncmp);
3176
3177 inst = DbstlElemTraits<T>::instance();
3178 sizef = inst->get_size_function();
3179 seqlenf = inst->get_sequence_len_function();
3180 seqcopyf = inst->get_sequence_copy_function();
3181 seqcmpf = inst->get_sequence_compare_function();
3182 }
3183
3184 template <class BinaryPredicate>
3185 void unique(BinaryPredicate binary_pred)
3186 {
3187 T *t2 = NULL;
3188
3189 try {
3190 that->begin_txn();
3191 iterator i = that->begin();
3192
3193 seq_assign(t2, *i);
3194 ++i;
3195 for (; i != that->end(); ++i) {
3196 if (binary_pred(*i, t2))
3197 that->erase(i);
3198 else
3199 seq_assign(t2, *i);
3200 }
3201 that->commit_txn();
3202 free(t2);
3203 } catch (...) {
3204 that->abort_txn();
3205 free(t2);
3206 throw;
3207 }
3208 }
3209
3210 void unique()
3211 {
3212 T *t2 = NULL;
3213
3214 try {
3215 that->begin_txn();
3216 iterator i = that->begin();
3217 seq_assign(t2, *i);
3218 ++i;
3219 for (; i != that->end(); ++i) {
3220 if (seqcmpf(*i, t2) == 0)
3221 that->erase(i);
3222 else
3223 seq_assign(t2, *i);
3224 }
3225 that->commit_txn();
3226 free(t2);
3227 } catch (...) {
3228 that->abort_txn();
3229 free(t2);
3230 throw;
3231 }
3232 }
3233
3234
3235 void merge(partner& x)
3236 {
3237 that->verify_db_handles(x);
3238 iterator itr, itrx;
3239
3240 try {
3241 that->begin_txn();
3242 for (itr = that->begin(), itrx = x.begin();
3243 itr != that->end() && itrx != x.end();) {
3244 if (seqcmpf(*itr, *itrx) > 0) {
3245 that->insert(itr, *itrx);
3246 ++itrx;
3247 } else
3248 ++itr;
3249 }
3250 if (itr == that->end() && itrx != x.end())
3251 that->insert(itr, itrx, x.end());
3252 x.clear();
3253 that->commit_txn();
3254 } catch (...) {
3255 that->abort_txn();
3256 throw;
3257 }
3258 }
3259
3260 void sort()
3261 {
3262 try {
3263 typedef std::basic_string<T, DbstlElemTraits<T> >
3264 string_t;
3265 CompareInt<T> comp(DbstlElemTraits<T>::instance()->
3266 get_sequence_compare_function());
3267 std::list<string_t> tmplist(that->size());
3268
3269 that->begin_txn();
3270 const_iterator itr;
3271 const partner&cthat = *that;
3272 typename std::list<string_t>::iterator itr1;
3273
3274 for (itr = cthat.begin(BulkRetrievalOption::
3275 bulk_retrieval()), itr1 = tmplist.begin();
3276 itr1 != tmplist.end(); ++itr, ++itr1)
3277 *itr1 = string_t(*itr);
3278
3279 tmplist.sort();
3280 that->clear(false);
3281 for (typename std::list<string_t>::iterator
3282 it = tmplist.begin();
3283 it != tmplist.end(); ++it)
3284 that->push_back((T*)(it->c_str()));
3285
3286 that->commit_txn();
3287 } catch (...) {
3288 that->abort_txn();
3289 throw;
3290 }
3291 }
3292
3293
3294 template <class Compare>
3295 void sort(Compare comp)
3296 {
3297 try {
3298 typedef std::basic_string<T, DbstlElemTraits<T> >
3299 string_t;
3300 CompareInt2<T, Compare> comp2(comp);
3301
3302 std::list<string_t> tmplist(that->size());
3303 that->begin_txn();
3304 const_iterator itr;
3305 const partner&cthat = *that;
3306 typename std::list<string_t>::iterator itr1;
3307
3308 for (itr = cthat.begin(BulkRetrievalOption::
3309 bulk_retrieval()), itr1 = tmplist.begin();
3310 itr1 != tmplist.end(); ++itr, ++itr1)
3311 *itr1 = string_t(*itr);
3312
3313 tmplist.sort(comp2);
3314 that->clear(false);
3315 for (typename std::list<string_t>::iterator it =
3316 tmplist.begin();
3317 it != tmplist.end(); ++it)
3318 that->push_back((T*)(it->c_str()));
3319
3320 that->commit_txn();
3321 } catch (...) {
3322 that->abort_txn();
3323 throw;
3324 }
3325 }
3326
3327
3328 };
3329
3330 END_NS
3331 #endif
3332