00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef W_LIST_H
00054 #define W_LIST_H
00055
00056 #include "w_defines.h"
00057
00058
00059
00060 #ifndef W_BASE_H
00061 #include <w_base.h>
00062 #endif
00063
00064 #include <iostream>
00065
00066
00067
00068
00069
00070
00071
00072 class w_list_base_t;
00073 template <class T, class LOCK> class w_list_t;
00074 template <class T, class LOCK> class w_list_i;
00075 template <class T, class LOCK, class K> class w_hash_t;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 class unsafe_list_dummy_lock_t
00088 {};
00089 unsafe_list_dummy_lock_t* const unsafe_nolock=NULL;
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 class w_link_t {
00102 public:
00103 NORET w_link_t();
00104 NORET ~w_link_t();
00105 NORET w_link_t(const w_link_t&);
00106 w_link_t& operator=(const w_link_t&);
00107
00108
00109
00110 void attach(w_link_t* prev_link);
00111 void check() {
00112 w_assert9(_prev == this && _next == this);
00113 }
00114
00115 w_link_t* detach();
00116 w_list_base_t* member_of() const;
00117
00118 w_link_t* next() const;
00119 w_link_t* prev() const;
00120
00121 private:
00122 w_list_base_t* _list;
00123 w_link_t* _next;
00124 w_link_t* _prev;
00125
00126 friend class w_list_base_t;
00127 };
00128
00129
00130
00131
00132 class w_list_base_t : public w_vbase_t {
00133
00134 public:
00135 bool is_empty() const;
00136 uint4_t num_members() const;
00137
00138 void dump();
00139 protected:
00140 NORET w_list_base_t();
00141 NORET w_list_base_t(uint4_t offset);
00142 NORET ~w_list_base_t();
00143
00144 void set_offset(uint4_t offset);
00145
00146 w_link_t _tail;
00147 uint4_t _cnt;
00148 uint4_t _adj;
00149
00150 private:
00151 NORET w_list_base_t(w_list_base_t&);
00152 w_list_base_t& operator=(w_list_base_t&);
00153
00154 friend class w_link_t;
00155 };
00156
00157 inline NORET
00158 w_link_t::w_link_t()
00159 : _list(0)
00160 {
00161 _next = this;
00162 _prev = this;
00163
00164 }
00165
00166 inline NORET
00167 w_link_t::~w_link_t()
00168 {
00169 w_assert1(_next == this && _prev == this && _list == 0);
00170 }
00171
00172 inline NORET
00173 w_link_t::w_link_t(const w_link_t&)
00174 : _list(0)
00175 {
00176 _next = _prev = this;
00177 }
00178
00179 inline w_link_t&
00180 w_link_t::operator=(const w_link_t&)
00181 {
00182 _list = 0;
00183 return *(_next = _prev = this);
00184 }
00185
00186 inline w_list_base_t*
00187 w_link_t::member_of() const
00188 {
00189 return _list;
00190 }
00191
00192 inline w_link_t*
00193 w_link_t::prev() const
00194 {
00195 return _prev;
00196 }
00197
00198 inline w_link_t*
00199 w_link_t::next() const
00200 {
00201 return _next;
00202 }
00203
00204 inline NORET
00205 w_list_base_t::w_list_base_t()
00206 : _cnt(0), _adj(uint4_max)
00207
00208
00209
00210 {
00211 _tail._list = 0;
00212 w_assert9(_tail._next == &_tail && _tail._prev == &_tail);
00213 }
00214
00215 inline NORET
00216 w_list_base_t::w_list_base_t(uint4_t offset)
00217 : _cnt(0), _adj(offset)
00218 {
00219 _tail._list = this;
00220 w_assert9(_tail._next == &_tail && _tail._prev == &_tail);
00221 }
00222
00223 inline void
00224 w_list_base_t::set_offset(uint4_t offset)
00225 {
00226 w_assert9(_cnt == 0 && _adj == uint4_max && _tail._list == 0);
00227 _tail._list = this;
00228 _adj = offset;
00229 }
00230
00231 inline NORET
00232 w_list_base_t::~w_list_base_t()
00233 {
00234 _tail._list = 0;
00235 w_assert9(_cnt == 0);
00236 }
00237
00238 inline bool
00239 w_list_base_t::is_empty() const
00240 {
00241 return _cnt == 0;
00242 }
00243
00244 inline w_base_t::uint4_t
00245 w_list_base_t::num_members() const
00246 {
00247 return _cnt;
00248 }
00249
00250 template <class T, class L> class w_list_t;
00251
00252 BIND_FRIEND_OPERATOR_PART_1(T, L, w_list_t<T,L>)
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 template <class T, class LOCK>
00264 class w_list_t : public w_list_base_t {
00265 protected:
00266
00267
00268 w_link_t* link_of(T* t) {
00269 w_assert3(t);
00270 return CAST(w_link_t*, CAST(char*,t)+_adj);
00271 }
00272
00273
00274 const w_link_t* link_of(const T* t) const {
00275 w_assert3(t);
00276 return CAST(w_link_t*, CAST(char*,t)+_adj);
00277 }
00278
00279
00280 T* base_of(w_link_t* p) const {
00281 w_assert3(p);
00282 return CAST(T*, CAST(char*, p) - _adj);
00283 }
00284
00285
00286 const T* base_of(const w_link_t* p) const {
00287 w_assert3(p);
00288 return CAST(T*, CAST(char*, p) - _adj);
00289 }
00290
00291 private:
00292 LOCK *lock;
00293 public:
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 NORET w_list_t(uint4_t link_offset, LOCK *l)
00309 : w_list_base_t(link_offset), lock(l)
00310 {
00311 #ifdef __GNUC__
00312 #else
00313 w_assert2(link_offset + sizeof(w_link_t) <= sizeof(T));
00314 #endif
00315 }
00316
00317 public:
00318
00319
00320
00321 NORET w_list_t() : lock(NULL) {}
00322
00323 public:
00324
00325 NORET ~w_list_t() {}
00326
00327
00328
00329
00330
00331 void set_offset(uint4_t link_offset) {
00332 w_list_base_t::set_offset(link_offset);
00333 }
00334
00335
00336
00337 virtual void put_in_order(T* t) {
00338 w_list_t<T,LOCK>::push(t);
00339 }
00340
00341
00342
00343 w_list_t<T,LOCK>& push_front(T* t) { return push(t); }
00344 w_list_t<T,LOCK>& push_back (T* t) { return append(t); }
00345 T* front() { return top(); }
00346 T* back() { return bottom(); }
00347 T* pop_front() { return pop(); }
00348 T* pop_back() { return chop(); }
00349
00350
00351 w_list_t<T,LOCK>& push(T* t) {
00352 link_of(t)->attach(&_tail);
00353 return *this;
00354 }
00355
00356
00357 w_list_t<T,LOCK>& append(T* t) {
00358 link_of(t)->attach(_tail.prev());
00359 return *this;
00360 }
00361
00362
00363 T* pop() {
00364 return _cnt ? base_of(_tail.next()->detach()) : 0;
00365 }
00366
00367
00368 T* chop() {
00369 return _cnt ? base_of(_tail.prev()->detach()) : 0;
00370 }
00371
00372
00373 T* top() {
00374 return _cnt ? base_of(_tail.next()) : 0;
00375 }
00376
00377
00378 T* bottom(){
00379 return _cnt ? base_of(_tail.prev()) : 0;
00380 }
00381
00382
00383 T* next(w_link_t* p) {
00384 w_assert1(p->member_of() == this);
00385 return base_of(p->next());
00386 }
00387
00388
00389 T* prev(w_link_t* p) {
00390 w_assert1(p->member_of() == this);
00391 return base_of(p->prev());
00392 }
00393
00394
00395 friend ostream& operator<< BIND_FRIEND_OPERATOR_PART_2(T, LOCK) (
00396 ostream& o,
00397 const w_list_t<T,LOCK>& l);
00398
00399 private:
00400
00401 NORET w_list_t(const w_list_t<T,LOCK>&x) ;
00402 w_list_t<T,LOCK>& operator=(const w_list_t<T,LOCK>&) ;
00403
00404 friend class w_list_i<T, LOCK>;
00405 };
00406
00407
00408 #define W_LIST_ARG(class,member) w_offsetof(class,member)
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 template <class T, class LOCK>
00438 class w_list_i : public w_base_t {
00439 public:
00440
00441
00442
00443 NORET w_list_i()
00444 : _list(0), _next(0), _curr(0), _backwards(false) {};
00445
00446
00447
00448 NORET w_list_i(const w_list_t<T,LOCK>& l, bool backwards = false)
00449 : _list(&l), _curr(0), _backwards(backwards) {
00450 _next = (backwards ? l._tail.prev() : l._tail.next());
00451 }
00452
00453 virtual NORET ~w_list_i() {};
00454
00455
00456
00457 void reset(const w_list_t<T, LOCK>& l, bool backwards = false) {
00458 _list = &l;
00459 _curr = 0;
00460 _backwards = backwards;
00461 _next = (_backwards ? l._tail.prev() : l._tail.next());
00462 }
00463
00464
00465
00466
00467
00468
00469 T* next()
00470 {
00471 if (_next) {
00472 _curr = (_next == &(_list->_tail)) ? 0 : _list->base_of(_next);
00473 _next = (_backwards ? _next->prev() : _next->next());
00474
00475
00476
00477 w_assert1(_next != NULL);
00478 }
00479 return _curr;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 T* curr() const {
00489 return _curr;
00490 }
00491
00492 protected:
00493 const w_list_t<T, LOCK>* _list;
00494 private:
00495 w_link_t* _next;
00496 T* _curr;
00497 bool _backwards;
00498
00499
00500 NORET w_list_i(w_list_i<T, LOCK>&) ;
00501 w_list_i<T, LOCK>& operator=(w_list_i<T, LOCK>&) ;
00502 };
00503
00504
00505
00506
00507
00508
00509
00510 template <class T, class LOCK>
00511 class w_list_const_i : public w_list_i<T, LOCK> {
00512 public:
00513 NORET w_list_const_i() {};
00514 NORET w_list_const_i(const w_list_t<T,LOCK>& l)
00515 : w_list_i<T,LOCK>(* (w_list_t<T,LOCK>*)(&l)) {};
00516 NORET ~w_list_const_i() {};
00517
00518 void reset(const w_list_t<T,LOCK>& l) {
00519 w_list_i<T,LOCK>::reset(* (w_list_t<T,LOCK>*) (&l));
00520 }
00521
00522 const T* next() { return w_list_i<T,LOCK>::next(); }
00523 const T* curr() const {
00524 return w_list_i<T,LOCK>::curr();
00525 }
00526 private:
00527
00528 NORET w_list_const_i(w_list_const_i<T,LOCK>&);
00529 w_list_const_i<T,LOCK>& operator=(w_list_const_i<T,LOCK>&);
00530 };
00531
00532
00533
00534
00535
00536
00537 template <class T, class LOCK, class K>
00538 class w_keyed_list_t : public w_list_t<T,LOCK> {
00539 public:
00540 T* first() { return w_list_t<T,LOCK>::top(); }
00541 T* last() { return w_list_t<T,LOCK>::bottom(); }
00542 virtual T* search(const K& k);
00543
00544 NORET w_keyed_list_t(LOCK *lock);
00545 NORET w_keyed_list_t(
00546 w_base_t::uint4_t key_offset,
00547 w_base_t::uint4_t link_offset,
00548 LOCK * lock
00549 );
00550
00551 NORET ~w_keyed_list_t() {};
00552
00553 void set_offset(
00554 w_base_t::uint4_t key_offset,
00555 w_base_t::uint4_t link_offset);
00556
00557 protected:
00558 const K& key_of(const T& t) {
00559 return * (K*) (((const char*)&t) + _key_offset);
00560 }
00561
00562 using w_list_t<T,LOCK>::_tail;
00563 using w_list_t<T,LOCK>::base_of;
00564
00565 private:
00566
00567 NORET w_keyed_list_t(const w_keyed_list_t<T,LOCK,K>&);
00568 w_base_t::uint4_t _key_offset;
00569
00570
00571 w_list_t<T,LOCK>& push(T* t);
00572 w_list_t<T,LOCK>& append(T* t) ;
00573 T* chop();
00574 T* top();
00575 T* bottom();
00576 };
00577
00578 #define W_KEYED_ARG(class,key,link) \
00579 W_LIST_ARG(class,key), W_LIST_ARG(class,link)
00580
00581
00582
00583
00584
00585
00586
00587 template <class T, class LOCK, class K>
00588 class w_ascend_list_t : public w_keyed_list_t<T,LOCK, K> {
00589 using w_keyed_list_t<T,LOCK, K>::_tail;
00590 using w_keyed_list_t<T,LOCK, K>::base_of;
00591
00592 public:
00593 NORET w_ascend_list_t(
00594 w_base_t::uint4_t key_offset,
00595 w_base_t::uint4_t link_offset,
00596 LOCK *lock)
00597 : w_keyed_list_t<T,LOCK, K>(key_offset, link_offset, lock) { };
00598 NORET ~w_ascend_list_t() {};
00599
00600 virtual T* search(const K& k);
00601 virtual void put_in_order(T* t);
00602
00603 private:
00604 NORET w_ascend_list_t(
00605 const w_ascend_list_t<T,LOCK,K>&);
00606 };
00607
00608
00609
00610
00611
00612
00613
00614 template <class T, class LOCK, class K>
00615 class w_descend_list_t : public w_keyed_list_t<T,LOCK, K>
00616 {
00617 using w_keyed_list_t<T,LOCK, K>::_tail;
00618 using w_keyed_list_t<T,LOCK, K>::base_of;
00619
00620 public:
00621 NORET w_descend_list_t(
00622 w_base_t::uint4_t key_offset,
00623 w_base_t::uint4_t link_offset,
00624 LOCK *l)
00625 : w_keyed_list_t<T,LOCK, K>(
00626 key_offset, link_offset, l) { };
00627 NORET ~w_descend_list_t() {};
00628
00629 virtual T* search(const K& k);
00630 virtual void put_in_order(T* t);
00631
00632 private:
00633 NORET w_descend_list_t(
00634 const w_descend_list_t<T,LOCK,K>&);
00635 };
00636
00637
00638
00639 template <class T, class LOCK>
00640 ostream&
00641 operator<<(
00642 ostream& o,
00643 const w_list_t<T,LOCK>& l)
00644 {
00645 const w_link_t* p = l._tail.next();
00646
00647 cout << "cnt = " << l.num_members();
00648
00649 while (p != &l._tail) {
00650 const T* t = l.base_of(p);
00651 if (! (o << endl << '\t' << *t)) break;
00652 p = p->next();
00653 }
00654 return o;
00655 }
00656
00657
00658 template <class T, class LOCK, class K>
00659 NORET
00660 w_keyed_list_t<T,LOCK, K>::w_keyed_list_t(
00661 w_base_t::uint4_t key_offset,
00662 w_base_t::uint4_t link_offset,
00663 LOCK* lock
00664 )
00665 : w_list_t<T,LOCK>(link_offset, lock), _key_offset(key_offset)
00666 {
00667 #ifdef __GNUC__
00668 #else
00669 w_assert9(key_offset + sizeof(K) <= sizeof(T));
00670 #endif
00671 }
00672
00673 template <class T, class LOCK, class K>
00674 NORET
00675 w_keyed_list_t<T,LOCK, K>::w_keyed_list_t(LOCK *l)
00676 : w_list_t<T,LOCK>(0,l), _key_offset(0)
00677 {
00678 }
00679
00680 template <class T, class LOCK, class K>
00681 void
00682 w_keyed_list_t<T,LOCK, K>::set_offset(
00683 w_base_t::uint4_t key_offset,
00684 w_base_t::uint4_t link_offset)
00685 {
00686 w_assert3(_key_offset == 0);
00687 w_list_t<T,LOCK>::set_offset(link_offset);
00688 _key_offset = key_offset;
00689 }
00690
00691 template <class T, class LOCK, class K>
00692 T*
00693 w_keyed_list_t<T,LOCK, K>::search(const K& k)
00694 {
00695 w_link_t *p;
00696 for (p = _tail.next();
00697 p != &_tail && (key_of(*base_of(p)) != k);
00698 p = p->next()) ;
00699 return (p && (p!=&_tail)) ? base_of(p) : 0;
00700 }
00701
00702 template <class T, class LOCK, class K>
00703 T*
00704 w_ascend_list_t<T,LOCK, K>::search(const K& k)
00705 {
00706 w_link_t *p;
00707 for (p = _tail.next();
00708 p != &_tail && (key_of(*base_of(p)) < k);
00709 p = p->next()) ;
00710
00711 return p ? base_of(p) : 0;
00712 }
00713
00714 template <class T, class LOCK, class K>
00715 void
00716 w_ascend_list_t<T,LOCK, K>::put_in_order(T* t)
00717 {
00718 w_link_t *p;
00719 for (p = _tail.next();
00720 p != &_tail && (key_of(*base_of(p)) <= key_of(*t));
00721 p = p->next()) ;
00722
00723 if (p) {
00724 link_of(t)->attach(p->prev());
00725 } else {
00726 link_of(t)->attach(_tail.prev());
00727 }
00728 }
00729
00730 template <class T, class LOCK, class K>
00731 T*
00732 w_descend_list_t<T,LOCK, K>::search(const K& k)
00733 {
00734 w_link_t *p;
00735 for (p = _tail.next();
00736 p != &_tail && (key_of(*base_of(p)) > k);
00737 p = p->next()) ;
00738
00739 return p ? base_of(p) : 0;
00740 }
00741
00742 template <class T, class LOCK, class K>
00743 void
00744 w_descend_list_t<T,LOCK, K>::put_in_order(T* t)
00745 {
00746 w_link_t *p;
00747 for (p = _tail.next();
00748 p != &_tail && (key_of(*base_of(p)) >= key_of(*t));
00749 p = p->next()) ;
00750
00751 if (p) {
00752 link_of(t)->attach(p->prev());
00753 } else {
00754 link_of(t)->attach(_tail.prev());
00755 }
00756 }
00757
00758
00759 #endif