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     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