LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiSmallObjectList.h

00001 /*
00002  * Copyright (C) 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiSmallObjectList.h
00027  * authors ....: Gustavo Quiros
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 12.12.03
00030  * revisions ..: $Id: ltiSmallObjectList.h,v 1.8 2006/02/07 20:37:33 ltilib Exp $ 
00031  */
00032 
00033 #ifndef _LTI_SMALL_OBJECT_LIST_H_
00034 #define _LTI_SMALL_OBJECT_LIST_H_
00035 
00036 #include "ltiObject.h"
00037 #include "ltiIoObject.h"
00038 #include "ltiTypes.h"
00039 #include "ltiException.h"
00040 #include "ltiAssert.h"
00041 
00042 /**
00043  * Performance macro, temporarily here
00044  * The segment size of the heap. Indicates the amount of nodes
00045  * that will be allocated at once when there is no more available
00046  * memory.
00047  */
00048 #define _LTI_PERFORMANCE_SMALLOBJECTLIST_HEAP_SEGMENT_SIZE 100
00049 
00050 namespace lti {
00051   
00052   /**
00053    * smallObjectList template class.
00054    *
00055    * The %lti::smallObjectList is an efficient implementation
00056    * of a (double) linked list for small data types. It maintains a
00057    * common heap for all lists of the same contained type. It should
00058    * serve, in many cases, as a drop-in replacement for std::list. 
00059    */
00060 
00061   template <typename T>
00062   class smallObjectList : public ioObject {
00063     
00064     struct node;
00065     class heap;
00066 
00067   public:
00068     
00069     class iterator;
00070     class const_iterator;
00071     friend class iterator;
00072     friend class const_iterator;
00073 
00074     /**
00075      * The type used to store the size of this list.
00076      */
00077     typedef unsigned int size_type;
00078 
00079     /**
00080      * reference type (allows read and write operations)
00081      * The use of the reference classes is similar to the
00082      * references of the STL (Standard Template Library).
00083      */
00084     typedef T& reference;
00085 
00086     /**
00087      * const_reference type (allows read-only operations)
00088      * The use of the reference classes is similar to the
00089      * references of the STL (Standard Template Library).
00090      */
00091     typedef const T& const_reference;
00092     
00093     /**
00094      * pointer type (allows read and write operations)
00095      * The use of the pointer classes is similar to the
00096      * references of the STL (Standard Template Library).
00097      */
00098     typedef T* pointer;
00099     
00100     /**
00101      * const_pointer type (allows read-only operations)
00102      * The use of the pointer classes is similar to the
00103      * references of the STL (Standard Template Library).
00104      */
00105     typedef const T* const_pointer;
00106 
00107     /**
00108      * Default constructor. Creates an empty smallObjectList.
00109      */
00110     smallObjectList() :
00111       theHeap(heap::instance()),
00112       count(0), first(0), last(0){
00113     }
00114     
00115     /**
00116      * Copy constructor. Creates a smallObjectList with the same
00117      * contents as the given list.
00118      */
00119     smallObjectList(const smallObjectList& l)
00120       : theHeap(heap::instance()),
00121         count(0), first(0), last(0) {
00122       operator = (l);
00123     }
00124 
00125     /**
00126      * Destructor
00127      */
00128     ~smallObjectList() { clear(); }
00129 
00130     /**
00131      * Returns the number of elements in the list.
00132      */
00133     size_type size() const { return count; }
00134 
00135     /**
00136      * Returns true if the list has no elements, false otherwise.
00137      */
00138     bool empty() const { return count == 0; }
00139 
00140     /**
00141      * Empties the list.
00142      */
00143     void clear() { while(count > 0) { pop_back(); } }
00144     
00145     /**
00146      * Returns an iterator pointing to the first element of the list.
00147      * The use of the interators is similar to the iterators of the
00148      * Standard Template Library (STL).
00149      */
00150     iterator begin() { return iterator(this,first); }
00151 
00152     /**
00153      * Returns an iterator pointing after the last element of the list.
00154      * The use of the interators is similar to the iterators of the
00155      * Standard Template Library (STL).
00156      */
00157     iterator end() { return iterator(this,0); }
00158     
00159     /**
00160      * Returns a const_iterator pointing to the first element of the list.
00161      * The use of the interators is similar to the iterators of the
00162      * Standard Template Library (STL).
00163      */
00164     const_iterator begin() const { return const_iterator(this,first); }
00165     
00166     /**
00167      * Returns a const_iterator pointing after the last element of the list.
00168      * The use of the interators is similar to the iterators of the
00169      * Standard Template Library (STL).
00170      */
00171     const_iterator end() const { return const_iterator(this,0); }
00172     
00173     /**
00174      * Erases the element at position pos, and returns an iterator pointing
00175      * to the next element after pos.
00176      */
00177     iterator erase(iterator pos);
00178     
00179     /**
00180      * Erases the elements between first and last, and returns an iterator
00181      * pointing to the next element after last.
00182      */
00183     iterator erase(iterator first, iterator last);
00184     
00185     /**
00186      * Inserts the range [first, last) before pos, and returns an iterator
00187      * pointing after the last inserted element.
00188      */
00189     iterator insert(iterator pos, const_iterator first, const_iterator last);
00190 
00191     /**
00192      * Inserts n copies of x before pos, and returns an iterator pointing 
00193      * after the last inserted element.
00194      */
00195     iterator insert(iterator pos, size_type n, const T& x);
00196     
00197     /**
00198      * Inserts x before pos, and returns an iterator pointing after the
00199      * inserted element.
00200      */
00201     iterator insert(iterator pos, const T& x);
00202 
00203     /**
00204      * Removes the first instance of T found in the list. If the value
00205      * \a x is not in the list, the list remains unchanged.
00206      * @param x value to be removed from the list
00207      */
00208     void remove(const T& x);
00209 
00210     /**
00211      * Inserts x at the beginning of the list.
00212      */
00213     void push_front(const T& x);
00214     
00215     /**
00216      * Inserts x at the end of the list.
00217      */
00218     void push_back(const T& x);
00219     
00220     /**
00221      * Removes the first element from the list.
00222      */
00223     void pop_front();
00224     
00225     /**
00226      * Removes the last element from the list.
00227      */
00228     void pop_back();
00229     
00230     /**
00231      * Returns a reference to the first element of the list.
00232      */
00233     reference front() { return *begin(); }
00234     
00235     /**
00236      * Returns a const_reference to the first element of the list.
00237      */
00238     const_reference front() const { return *begin(); }
00239     
00240     /**
00241      * Returns a reference to the last element of the list.
00242      */
00243     reference back() { return *(--end()); }
00244     
00245     /**
00246      * Returns a const_reference to the last element of the list.
00247      */
00248     const_reference back() const { return *(--end()); }
00249 
00250     /**
00251      * Sorts this list according to the < operator.
00252      */
00253     void sort();
00254 
00255     /**
00256      * Swaps the contents of this list with the given list.
00257      */
00258     void swap(smallObjectList<T>& l){
00259       std::swap(count,l.count);
00260       std::swap(first,l.first);
00261       std::swap(last,l.last);
00262     }
00263 
00264     /**
00265      * Inserts all elements from the given list before the given position,
00266      * and removes them from the given list. This is a constant
00267      * time operation.
00268      */
00269     void splice(iterator position, smallObjectList<T>& l);
00270     
00271     /**
00272      * Assignment operator. Clears this list, and copies the contents
00273      * of the given list.
00274      */
00275     smallObjectList<T>& operator = (const smallObjectList<T>& l);
00276     
00277     /**
00278      * iterator class (allows read and write operations)
00279      * The use of the iterator classes is similar to the iterators of
00280      * the STL (Standard Template Library).
00281      */
00282     class iterator {
00283       
00284     public:
00285       
00286       /**
00287        * Iterator traits. These are required by the algorithms
00288        * of the STL.
00289        */
00290       typedef std::bidirectional_iterator_tag iterator_category;
00291       typedef T value_type;
00292       typedef T difference_type;
00293       typedef T* pointer;
00294       typedef T& reference;
00295 
00296     private:
00297 
00298       friend class smallObjectList<T>;
00299       friend class const_iterator;
00300       
00301       /**
00302        * Pointer to the list being iterated.
00303        */
00304       smallObjectList *theList; 
00305 
00306       /**
00307        * Pointer to the current position.
00308        */
00309       node *pos;
00310  
00311     protected:
00312 
00313       /**
00314        * Creates an iterator for the given list, at the given position.
00315        */
00316       iterator(smallObjectList *l, node *p)
00317         : theList(l),
00318           pos(p) {
00319       }
00320       
00321     public:
00322 
00323       /**
00324        * Creates an uninitialized iterator.
00325        */
00326       iterator() : theList(0), pos(0) {}
00327 
00328       /**
00329        * Copy constructor. Creates a copy of the given iterator.
00330        */
00331       iterator(const iterator& i)
00332         : theList(i.theList),
00333           pos(i.pos) {
00334       }
00335 
00336       /**
00337        * Returns true if both iterators are at the same position on the
00338        * same list, false otherwise.
00339        */
00340       bool operator == (const iterator& i) const {
00341         return pos == i.pos;
00342       }
00343       
00344       /**
00345        * Returns false if both iterators are at the same position on the
00346        * same list, true otherwise.
00347        */
00348       bool operator != (const iterator& i) const {
00349         return pos != i.pos;
00350       }
00351       
00352       /**
00353        * Returns a reference to the current element.
00354        */
00355       reference operator * () const {
00356         return pos->obj;
00357       }
00358 
00359       /**
00360        * Overwrites the current element with the given element.
00361        */
00362       reference operator * (T obj) const {
00363         return pos->obj = obj;
00364       }
00365 
00366       /**
00367        * Returns a pointer to the current element.
00368        */
00369       pointer operator -> () const {
00370         return &(*pos.obj);
00371       }
00372       
00373       /**
00374        * Moves forward one element in the list, and returns itself.
00375        */
00376       iterator& operator ++ () {
00377         pos = pos->next;
00378         return *this;
00379       }
00380       
00381       /**
00382        * Moves forward one element in the list, and returns a copy of itself
00383        * before the move.
00384        */
00385       iterator operator ++ (int) { 
00386         iterator tmp(*this);
00387         ++*this;
00388         return tmp;
00389       }
00390 
00391       /**
00392        * Moves backward one element in the list, and returns itself.
00393        */
00394       iterator& operator -- () {
00395         pos = ((pos == 0) ? theList->last : pos->prev);
00396         return *this;
00397       }
00398       
00399       /**
00400        * Moves backward one element in the list, and returns a copy of itself
00401        * before the move.
00402        */
00403       iterator operator -- (int) { 
00404         iterator tmp(*this);
00405         --*this;
00406         return tmp;
00407       }
00408 
00409     };
00410 
00411     /**
00412      * const_iterator class (allows read-only operations)
00413      * The use of the iterator classes is similar to the iterators of
00414      * the STL (Standard Template Library).
00415      */
00416     class const_iterator {
00417   
00418     public:
00419 
00420       /**
00421        * Iterator traits. These are required by the algorithms
00422        * of the STL.
00423        */
00424       typedef std::bidirectional_iterator_tag iterator_category;
00425       typedef T value_type;
00426       typedef T difference_type;
00427       typedef T* pointer;
00428       typedef T& reference;
00429 
00430     private:
00431       
00432       friend class smallObjectList<T>;
00433       
00434       /**
00435        * Pointer to the list being iterated.
00436        */
00437       smallObjectList const *theList; 
00438 
00439       /**
00440        * Pointer to the current position.
00441        */
00442       node *pos;
00443       
00444     protected:
00445       
00446       /**
00447        * Creates an const_iterator for the given list, at the given position.
00448        */
00449       const_iterator(const smallObjectList *l, node *p)
00450         : theList(l),
00451           pos(p) {
00452       }
00453       
00454     public:
00455       
00456       /**
00457        * Creates an uninitialized const_iterator.
00458        */      
00459       const_iterator() : theList(0), pos(0) {}
00460       
00461       /**
00462        * Copy constructor. Creates a copy of the given const_iterator.
00463        */
00464       const_iterator(const const_iterator& i)
00465         : theList(i.theList),
00466           pos(i.pos) {
00467       }
00468       
00469       /**
00470        * Copy constructor. Creates a copy of the given iterator.
00471        */
00472       const_iterator(const iterator& i)
00473         : theList(i.theList),
00474           pos(i.pos) {
00475       }
00476 
00477       /**
00478        * Returns true if both iterators are at the same position on the
00479        * same list, false otherwise.
00480        */
00481       bool operator == (const const_iterator& i) const {
00482         return pos == i.pos;
00483       }
00484 
00485       /**
00486        * Returns false if both iterators are at the same position on the
00487        * same list, true otherwise.
00488        */
00489       bool operator != (const const_iterator& i) const {
00490         return pos != i.pos;
00491       }
00492       
00493       /**
00494        * Returns a const_reference to the current element.
00495        */
00496       const_reference operator * () const {
00497         return pos->obj;
00498       }
00499 
00500       /**
00501        * Returns a const_pointer to the current element.
00502        */
00503       const_pointer operator -> () const {
00504         return &(pos->obj);
00505       }
00506       
00507       /**
00508        * Moves forward one element in the list, and returns itself.
00509        */
00510       const_iterator& operator ++ () {
00511         pos = pos->next;
00512         return *this;
00513       }
00514       
00515       /**
00516        * Moves forward one element in the list, and returns a copy of itself
00517        * before the move.
00518        */
00519       const_iterator operator ++ (int) { 
00520         const_iterator tmp(*this);
00521         ++*this;
00522         return tmp;
00523       }
00524 
00525       /**
00526        * Moves backward one element in the list, and returns itself.
00527        */
00528       const_iterator& operator -- () {
00529         pos = ((pos == 0) ? theList->last : pos->prev);
00530         return *this;
00531       }
00532 
00533       /**
00534        * Moves backward one element in the list, and returns a copy of itself
00535        * before the move.
00536        */
00537       const_iterator operator -- (int) { 
00538         const_iterator tmp(*this);
00539         --*this;
00540         return tmp;
00541       }
00542 
00543     };
00544 
00545   private:
00546     
00547     /**
00548      * node structure. Represents a node of the linked list.
00549      */
00550     struct node {
00551       
00552       /**
00553        * The stored element.
00554        */
00555       T obj;
00556 
00557       /**
00558        * Pointer to the previous node.
00559        */
00560       node *prev;
00561 
00562       /**
00563        * Pointer to the next node.
00564        */
00565       node *next;
00566 
00567     };
00568     
00569     /**
00570      * A segment of the heap, used to allocate memory for nodes. Since
00571      * these nodes are used for a linked list, the unused nodes are
00572      * kept in a (singly) linked list of free nodes.
00573      */
00574     class segment {
00575 
00576       friend class heap;
00577       
00578       /**
00579        * The array of nodes contained in this segment
00580        */
00581       node nodes[_LTI_PERFORMANCE_SMALLOBJECTLIST_HEAP_SEGMENT_SIZE];
00582 
00583       /**
00584        * A pointer to the first free node of the segment
00585        */
00586       node *firstFree;
00587       
00588       /**
00589        * A pointer to the next segment in the heap
00590        */
00591       segment *next;
00592 
00593       /**
00594        * A pointer to the previous segment in the heap
00595        */
00596       segment *prev;
00597       
00598       /**
00599        * The number of nodes currently allocated in this segment
00600        */
00601       short int nodeCount;
00602 
00603       /**
00604        * Constructor. Initializes the list of free nodes.
00605        */
00606       segment();
00607 
00608       /**
00609        * Destructor
00610        */
00611       ~segment();
00612 
00613       /**
00614        * Determines if the given node is contained in this segment, that is,
00615        * if the pointer points within the inner node array.
00616        */
00617       inline bool contains(node *node) {
00618         return
00619           (node >= &nodes[0]) &&
00620           (node < &nodes[_LTI_PERFORMANCE_SMALLOBJECTLIST_HEAP_SEGMENT_SIZE]);
00621       }
00622 
00623       /**
00624        * 'Grabs' (allocates) a node in this segment.
00625        */
00626       inline node* grab(){
00627         ++nodeCount;
00628         node *n = firstFree;
00629         firstFree = firstFree->next;
00630         return n;
00631       }
00632 
00633       /**
00634        * Releases the given node in this segment
00635        */
00636       inline void release(node *n){
00637         --nodeCount;
00638         n->next = firstFree;
00639         firstFree = n;
00640       }
00641       
00642     };
00643     
00644     /**
00645      * A heap of nodes. Stores nodes in dynamically allocated
00646      * segments.
00647      */
00648     class heap {
00649       
00650       /**
00651        * A pointer to the first segment in the list of segments
00652        */
00653       segment *first;
00654       
00655       /**
00656        * A pointer to the segment most recently used for allocation
00657        */
00658       segment *recentAlloc;
00659 
00660       /**
00661        * A pointer to the segment most recently used for deallocation
00662        */
00663       segment *recentDealloc;
00664 
00665       /**
00666        * The total object count contained in this heap
00667        */
00668       unsigned long int objectCount;
00669 
00670       /**
00671        * The number of segments in this heap
00672        */
00673       unsigned long int segmentCount;
00674 
00675       /**
00676        * Constructor. Segment lists are initially empty.
00677        */
00678       heap() : first(new segment), recentAlloc(first), recentDealloc(first),
00679                objectCount(0), segmentCount(1) {
00680       }
00681       
00682       /**
00683        * Destructor. Frees the lists of segments
00684        */
00685       ~heap(){
00686         segment *s, *n;
00687         s = first;
00688         while(s){
00689           n = s->next;
00690           delete s;
00691           s = n;
00692         }
00693       }
00694       
00695       /**
00696        * Disable the copy constructor
00697        */
00698       heap(const heap&);
00699 
00700       /**
00701        * Disable the assignment operator
00702        */
00703       heap& operator = (const heap&);
00704 
00705     public:
00706       
00707       /**
00708        * The singleton instance accessor
00709        */
00710       static heap& instance(){
00711         static heap theInstance;
00712         return theInstance;
00713       }
00714       
00715       /**
00716        * Allocates a new node in the heap
00717        */
00718       node *allocate();
00719       
00720       /**
00721        * Frees the given node from the heap
00722        */
00723       void deallocate(node *n);
00724       
00725     };
00726     
00727     /**
00728      * The heap of nodes, used for memory allocation and management.
00729      */
00730     heap& theHeap;
00731     
00732     /**
00733      * The counter of stored elements in the list. It stores the size of
00734      * the list.
00735      */
00736     size_type count;
00737 
00738     /**
00739      * The pointer to the first element of the list. 
00740      */
00741     node *first;
00742 
00743     /**
00744      * The pointer to the last element of the list. 
00745      */
00746     node *last;
00747     
00748     /**
00749      * Quicksort implementation used by sort().
00750      */
00751     void quicksort(iterator front, iterator back);
00752        
00753   };
00754   
00755 }
00756 
00757 #include "ltiSmallObjectList_template.h"
00758 
00759 #endif

Generated on Sat Apr 10 15:26:12 2010 for LTI-Lib by Doxygen 1.6.1