CVR-Lib last update 20 Sep 2009

cvrSmallObjectList.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998 - 2004
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 /**
00042  * \file   cvrSmallObjectList.h
00043  *         Defines a list similar to the std::list but specialized for
00044  *         an efficient access of small objects.
00045  * \author Gustavo Quiros
00046  * \date   12.12.03
00047  *
00048  * $Id: cvrSmallObjectList.h,v 1.14 2007/12/25 19:58:24 alvarado Exp $
00049  */
00050 
00051 #ifndef _CVR_SMALL_OBJECT_LIST_H_
00052 #define _CVR_SMALL_OBJECT_LIST_H_
00053 
00054 #include "cvrObject.h"
00055 #include "cvrIoObject.h"
00056 #include "cvrTypes.h"
00057 #include "cvrException.h"
00058 #include "cvrAssert.h"
00059 #include "cvrPerformanceConfig.h"
00060 
00061 namespace cvr {
00062 
00063   /**
00064    * List of objects of small size.
00065    *
00066    * The %cvr::smallObjectList is an efficient implementation
00067    * of a (double) linked list for small data types.
00068    *
00069    * Each instance maintains its own heap, which may be expensive in memory
00070    * consumption, but they are intended as very fast data structures with
00071    * respect to memory reservation issues.  It should serve, in many cases, as
00072    * a drop-in replacement for std::list.
00073    *
00074    * @see cvr::list
00075    */
00076   template <typename T>
00077   class smallObjectList {
00078 
00079   private:
00080 
00081     struct node;
00082     class heap;
00083 
00084   public:
00085 
00086     class iterator;
00087     class const_iterator;
00088     friend class iterator;
00089     friend class const_iterator;
00090 
00091     /**
00092      * The type used to store the size of this list.
00093      */
00094     typedef unsigned int size_type;
00095 
00096     /**
00097      * Reference type (allows read and write operations)
00098      * The use of the reference classes is similar to the
00099      * references of the STL (Standard Template Library).
00100      */
00101     typedef T& reference;
00102 
00103     /**
00104      * Const_reference type (allows read-only operations)
00105      * The use of the reference classes is similar to the
00106      * references of the STL (Standard Template Library).
00107      */
00108     typedef const T& const_reference;
00109 
00110     /**
00111      * Pointer type (allows read and write operations)
00112      * The use of the pointer classes is similar to the
00113      * references of the STL (Standard Template Library).
00114      */
00115     typedef T* pointer;
00116 
00117     /**
00118      * Const_pointer type (allows read-only operations)
00119      * The use of the pointer classes is similar to the
00120      * references of the STL (Standard Template Library).
00121      */
00122     typedef const T* const_pointer;
00123 
00124     /**
00125      * The type of the values stored in the list.
00126      */
00127     typedef T value_type;
00128 
00129     /**
00130      * Default constructor. Creates an empty smallObjectList.
00131      */
00132     smallObjectList();
00133 
00134     /**
00135      * Copy constructor. Creates a smallObjectList with the same
00136      * contents as the given list.
00137      */
00138     smallObjectList(const smallObjectList& l);
00139 
00140     /**
00141      * Destructor
00142      */
00143     ~smallObjectList();
00144 
00145     /**
00146      * Returns the number of elements in the list.
00147      */
00148     size_type size() const;
00149 
00150     /**
00151      * Returns true if the list has no elements, false otherwise.
00152      */
00153     bool empty() const;
00154 
00155     /**
00156      * Empties the list.
00157      */
00158     void clear();
00159 
00160     /**
00161      * Returns an iterator pointing to the first element of the list.
00162      * The use of the interators is similar to the iterators of the
00163      * Standard Template Library (STL).
00164      */
00165     iterator begin();
00166 
00167     /**
00168      * Returns an iterator pointing after the last element of the list.
00169      * The use of the interators is similar to the iterators of the
00170      * Standard Template Library (STL).
00171      */
00172     iterator end();
00173 
00174     /**
00175      * Returns a const_iterator pointing to the first element of the list.
00176      * The use of the interators is similar to the iterators of the
00177      * Standard Template Library (STL).
00178      */
00179     const_iterator begin() const;
00180 
00181     /**
00182      * Returns a const_iterator pointing after the last element of the list.
00183      * The use of the interators is similar to the iterators of the
00184      * Standard Template Library (STL).
00185      */
00186     const_iterator end() const;
00187 
00188     /**
00189      * Erases the element at position pos, and returns an iterator pointing
00190      * to the next element after pos.
00191      */
00192     iterator erase(iterator pos);
00193 
00194     /**
00195      * Erases the elements between first and last, and returns an iterator
00196      * pointing to the next element after last.
00197      */
00198     iterator erase(iterator first, iterator last);
00199 
00200     /**
00201      * Inserts the range [first, last) before pos, and returns an iterator
00202      * pointing after the last inserted element.
00203      */
00204     iterator insert(iterator pos, const_iterator first, const_iterator last);
00205 
00206     /**
00207      * Inserts n copies of x before pos, and returns an iterator pointing
00208      * after the last inserted element.
00209      */
00210     iterator insert(iterator pos, size_type n, const T& x);
00211 
00212     /**
00213      * Inserts x before pos, and returns an iterator pointing after the
00214      * inserted element.
00215      */
00216     iterator insert(iterator pos, const T& x);
00217 
00218     /**
00219      * Removes all ocurrences of x found in the list. If the value
00220      * \a x is not in the list, the list remains unchanged.
00221      * @param x value to be removed from the list
00222      */
00223     void remove(const T& x);
00224 
00225     /**
00226      * Inserts x at the beginning of the list.
00227      */
00228     void push_front(const T& x);
00229 
00230     /**
00231      * Inserts x at the end of the list.
00232      */
00233     void push_back(const T& x);
00234 
00235     /**
00236      * Removes the first element from the list.
00237      */
00238     void pop_front();
00239 
00240     /**
00241      * Removes the last element from the list.
00242      */
00243     void pop_back();
00244 
00245     /**
00246      * Returns a reference to the first element of the list.
00247      */
00248     reference front();
00249 
00250     /**
00251      * Returns a const_reference to the first element of the list.
00252      */
00253     const_reference front() const;
00254 
00255     /**
00256      * Returns a reference to the last element of the list.
00257      */
00258     reference back();
00259 
00260     /**
00261      * Returns a const_reference to the last element of the list.
00262      */
00263     const_reference back() const;
00264 
00265     /**
00266      * Sorts this list according to the < operator.
00267      */
00268     void sort();
00269 
00270     /**
00271      * Sorts this list according to the comparison function \a comp
00272      * which must return a bool and take two arguments of type T.
00273      */
00274     template <class Compare>
00275     void sort(Compare comp);
00276 
00277     /**
00278      * Swaps the contents of this list with the given list.
00279      */
00280     void swap(smallObjectList<T>& l);
00281 
00282     /**
00283      * Inserts all elements from the given list \a other before the
00284      * given \a position, and removes them from the given list.
00285      *
00286      * This is a constant time operation.
00287      */
00288     void splice(iterator position, smallObjectList<T>& other);
00289 
00290     /**
00291      * Removes the element at \a it from list \a other and inserts it
00292      * in this list before \a position.
00293      *
00294      * This is NOT a constant time operation.  The computational cost is
00295      * equivalent to use insert and erase.  The method is just provided for
00296      * interface compatibility with the std::list.
00297      */
00298     void splice(iterator position, smallObjectList<T>& other, iterator it);
00299 
00300     /**
00301      * Removes the elements in the interval [\a begin, \a end] from
00302      * list \a other and inserts them before \a position in this
00303      * list.
00304      *
00305      * This is NOT a constant time operation.  The computational cost is
00306      * equivalent to use several insert and erase calls sequentially.  The
00307      * method is just provided for interface compatibility with the std::list.
00308      */
00309     void splice(iterator position, smallObjectList<T>& other,
00310                 iterator begin, iterator end);
00311 
00312     /**
00313      * Assignment operator. Clears this list, and copies the contents
00314      * of the given list.
00315      */
00316     smallObjectList<T>& operator = (const smallObjectList<T>& l);
00317 
00318     /**
00319      * Iterator class (allows read and write operations)
00320      * The use of the iterator classes is similar to the iterators of
00321      * the STL (Standard Template Library).
00322      */
00323     class iterator {
00324 
00325     public:
00326 
00327       /**
00328        * Iterator traits. These are required by the algorithms
00329        * of the STL.
00330        */
00331       typedef std::bidirectional_iterator_tag iterator_category;
00332       typedef T value_type;
00333       typedef T difference_type;
00334       typedef T* pointer;
00335       typedef T& reference;
00336 
00337     private:
00338 
00339       friend class smallObjectList<T>;
00340       friend class const_iterator;
00341 
00342       /**
00343        * Pointer to the current node.
00344        */
00345       node *node_;
00346 
00347     protected:
00348 
00349       /**
00350        * Creates an iterator for the given list, at the given position.
00351        */
00352       iterator(node *n) : node_(n) {
00353       }
00354 
00355     public:
00356 
00357       /**
00358        * Creates an uninitialized iterator.
00359        */
00360       iterator() : node_(0) {
00361       }
00362 
00363       /**
00364        * Copy constructor. Creates a copy of the given iterator.
00365        */
00366       iterator(const iterator& i) : node_(i.node_) {
00367       }
00368 
00369       /**
00370        * Returns true if both iterators are at the same position on the
00371        * same list, false otherwise.
00372        */
00373       bool operator == (const iterator& i) const {
00374         return node_ == i.node_;
00375       }
00376 
00377       /**
00378        * Returns false if both iterators are at the same position on the
00379        * same list, true otherwise.
00380        */
00381       bool operator != (const iterator& i) const {
00382         return node_ != i.node_;
00383       }
00384 
00385       /**
00386        * Returns a reference to the current element.
00387        */
00388       reference operator * () const {
00389         return node_->obj;
00390       }
00391 
00392 //       /**
00393 //        * Overwrites the current element with the given element.
00394 //        */
00395 //       reference operator * (T obj) const {
00396 //         return node_->obj = obj;
00397 //       }
00398 
00399       /**
00400        * Returns a pointer to the current element.
00401        */
00402       pointer operator->() const {
00403         return &((*node_).obj);
00404       }
00405 
00406       /**
00407        * Moves forward one element in the list, and returns itself.
00408        */
00409       iterator& operator ++ () {
00410         node_ = node_->next;
00411         return *this;
00412       }
00413 
00414       /**
00415        * Moves forward one element in the list, and returns a copy of itself
00416        * before the move.
00417        */
00418       iterator operator ++ (int) {
00419         iterator tmp(*this);
00420         ++*this;
00421         return tmp;
00422       }
00423 
00424       /**
00425        * Moves backward one element in the list, and returns itself.
00426        */
00427       iterator& operator -- () {
00428         node_ = node_->prev;
00429         return *this;
00430       }
00431 
00432       /**
00433        * Moves backward one element in the list, and returns a copy of itself
00434        * before the move.
00435        */
00436       iterator operator -- (int) {
00437         iterator tmp(*this);
00438         --*this;
00439         return tmp;
00440       }
00441 
00442     };
00443 
00444     /**
00445      * Const_iterator class (allows read-only operations).
00446      *
00447      * The use of the iterator classes is similar to the iterators of
00448      * the STL (Standard Template Library).
00449      */
00450     class const_iterator {
00451 
00452     public:
00453 
00454       /**
00455        * Iterator traits. These are required by the algorithms
00456        * of the STL.
00457        */
00458       typedef std::bidirectional_iterator_tag iterator_category;
00459       typedef T value_type;
00460       typedef T difference_type;
00461       typedef T* pointer;
00462       typedef T& reference;
00463 
00464     private:
00465 
00466       friend class smallObjectList<T>;
00467 
00468       /**
00469        * Pointer to the current position.
00470        */
00471       const node *node_;
00472 
00473     protected:
00474 
00475       /**
00476        * Creates an const_iterator for the given list, at the given position.
00477        */
00478       const_iterator(const node *p) : node_(p) {
00479       }
00480 
00481     public:
00482 
00483       /**
00484        * Creates an uninitialized const_iterator.
00485        */
00486       const_iterator() : node_(0) {
00487       }
00488 
00489       /**
00490        * Copy constructor. Creates a copy of the given const_iterator.
00491        */
00492       const_iterator(const const_iterator& i)
00493         : node_(i.node_) {
00494       }
00495 
00496       /**
00497        * Copy constructor. Creates a copy of the given iterator.
00498        */
00499       const_iterator(const iterator& i)
00500         : node_(i.node_) {
00501       }
00502 
00503       /**
00504        * Returns true if both iterators are at the same position on the
00505        * same list, false otherwise.
00506        */
00507       bool operator == (const const_iterator& i) const {
00508         return node_ == i.node_;
00509       }
00510 
00511       /**
00512        * Returns false if both iterators are at the same position on the
00513        * same list, true otherwise.
00514        */
00515       bool operator != (const const_iterator& i) const {
00516         return node_ != i.node_;
00517       }
00518 
00519       /**
00520        * Returns a const_reference to the current element.
00521        */
00522       const_reference operator * () const {
00523         return node_->obj;
00524       }
00525 
00526       /**
00527        * Returns a const_pointer to the current element.
00528        */
00529       const_pointer operator -> () const {
00530         return &(node_->obj);
00531       }
00532 
00533       /**
00534        * Moves forward one element in the list, and returns itself.
00535        */
00536       const_iterator& operator ++ () {
00537         node_ = node_->next;
00538         return *this;
00539       }
00540 
00541       /**
00542        * Moves forward one element in the list, and returns a copy of itself
00543        * before the move.
00544        */
00545       const_iterator operator ++ (int) {
00546         const_iterator tmp(*this);
00547         ++*this;
00548         return tmp;
00549       }
00550 
00551       /**
00552        * Moves backward one element in the list, and returns itself.
00553        */
00554       const_iterator& operator -- () {
00555         node_ = node_->prev;
00556         return *this;
00557       }
00558 
00559       /**
00560        * Moves backward one element in the list, and returns a copy of itself
00561        * before the move.
00562        */
00563       const_iterator operator -- (int) {
00564         const_iterator tmp(*this);
00565         --*this;
00566         return tmp;
00567       }
00568 
00569     };
00570 
00571   private:
00572 
00573     /**
00574      * Node structure.
00575      *
00576      * Represents a node of the linked list.
00577      */
00578     struct node {
00579 
00580       /**
00581        * default constructor
00582        */
00583       node() : obj(), prev(0), next(0) {};
00584 
00585       /**
00586        * copy constructor
00587        */
00588       node(const node& other)
00589         : obj(other.obj), prev(other.prev), next(other.next) {};
00590 
00591       /**
00592        * copy the other node
00593        */
00594       node& operator=(const node& other) {
00595         obj  = other.obj;
00596         prev = other.prev;
00597         next = other.next;
00598         return *this;
00599       }
00600 
00601       /**
00602        * The stored element.
00603        */
00604       T obj;
00605 
00606       /**
00607        * Pointer to the previous node.
00608        */
00609       node *prev;
00610 
00611       /**
00612        * Pointer to the next node.
00613        */
00614       node *next;
00615 
00616     };
00617 
00618     /**
00619      * A segment of the heap, used to allocate memory for nodes. Since
00620      * these nodes are used for a linked list, the unused nodes are
00621      * kept in a (singly) linked list of free nodes.
00622      */
00623     class segment {
00624 
00625       friend class heap;
00626 
00627     private:
00628 
00629       /**
00630        * The array of nodes contained in this segment
00631        */
00632       node nodes_[_CVR_PERFORMANCE_SMALLOBJECTLIST_HEAP_SEGMENT_SIZE];
00633 
00634       /**
00635        * A pointer to the first free node of the segment
00636        */
00637       node *firstFree;
00638 
00639       /**
00640        * A pointer to the next segment in the heap
00641        */
00642       segment* next;
00643 
00644       /**
00645        * A pointer to the previous segment in the heap
00646        */
00647       segment* prev;
00648 
00649       /**
00650        * The number of nodes currently allocated in this segment
00651        */
00652       short int nodeCount;
00653 
00654       /**
00655        * don't copy it
00656        */
00657       segment& operator=(const segment& o) {}
00658 
00659       segment(const segment& o) {}
00660 
00661     public:
00662 
00663       /**
00664        * Constructor. Initializes the list of free nodes.
00665        */
00666       segment();
00667 
00668       /**
00669        * Destructor
00670        */
00671       ~segment();
00672 
00673       /**
00674        * Determines if the given node is contained in this segment, that is,
00675        * if the pointer points within the inner node array.
00676        */
00677       inline bool contains(node *node);
00678 
00679       /**
00680        * 'Grabs' (allocates) a node in this segment.
00681        */
00682       inline node* grab();
00683 
00684       /**
00685        * Releases the given node in this segment
00686        */
00687       inline void release(node *n);
00688 
00689     };
00690 
00691     /**
00692      * A heap of nodes.
00693      *
00694      * Stores nodes in dynamically allocated segments.
00695      */
00696     class heap {
00697 
00698     private:
00699 
00700       /**
00701        * A pointer to the first segment in the list of segments
00702        */
00703       segment *first_;
00704 
00705       /**
00706        * A pointer to the segment most recently used for allocation
00707        */
00708       segment *recentAlloc_;
00709 
00710       /**
00711        * A pointer to the segment most recently used for deallocation
00712        */
00713       segment *recentDealloc_;
00714 
00715       /**
00716        * The total object count contained in this heap
00717        */
00718       unsigned long int objectCount_;
00719 
00720       /**
00721        * The number of segments in this heap
00722        */
00723       unsigned long int segmentCount_;
00724 
00725     public:
00726 
00727       /**
00728        * Constructor
00729        */
00730       heap();
00731 
00732       /**
00733        * Destructor
00734        */
00735       ~heap();
00736 
00737       /**
00738        * Disable the copy constructor
00739        */
00740       heap(const heap&);
00741 
00742       /**
00743        * Disable the assignment operator
00744        */
00745       heap& operator= (const heap&);
00746 
00747       /*
00748        * The singleton instance accessor
00749        */
00750       //static heap& instance();
00751 
00752       /**
00753        * Allocates a new node in the heap
00754        */
00755       node *allocate();
00756 
00757       /**
00758        * Frees the given node from the heap
00759        */
00760       void deallocate(node *n);
00761 
00762       /**
00763        * Transfer all data to the other heap
00764        */
00765       void detach(heap& other);
00766 
00767       /**
00768        * Assign all data of the other heap to this one
00769        */
00770       void attach(heap& other);
00771 
00772       /**
00773        * Swap the contents of two heaps
00774        */
00775       void swap(heap& other);
00776     };
00777 
00778     /**
00779      * The heap of nodes, used for memory allocation and management.
00780      */
00781     heap heap_;
00782 
00783     /**
00784      * The 'end' node. This node marks the end of the list, and contains no
00785      * user data. Its 'next' is the first element of the list, and its 'prev'
00786      * is the last. Therefore, for an empty list, both of these pointers point
00787      * at end_;
00788      */
00789     node end_;
00790 
00791     /**
00792      * Quicksort implementation used by sort().
00793      */
00794     void quicksort(iterator front, iterator back);
00795 
00796     /**
00797      * Quicksort implementation used by sort(comp). See sort(Compare
00798      * comp) for details.
00799      */
00800     template <class Compare>
00801     void quicksort(iterator front, iterator back, Compare comp);
00802 
00803     /**
00804      * Moves the elements from [\a first,\a last) before \a position
00805      *
00806      * This is a helper function for splice().
00807      */
00808     /*
00809     void spliceHelper(iterator position,
00810                       smallObjectList<T>& other,
00811                       iterator first,
00812                       iterator last);
00813     */
00814 
00815   };
00816 
00817 }
00818 
00819 #include "cvrSmallObjectList_template.h"
00820 #include "cvrSmallObjectList_inline.h"
00821 
00822 #endif

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8