Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/common/addressable_queues.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2010-2011 Raoul Steffen <R-Steffen@gmx.de> 00007 * 00008 * Distributed under the Boost Software License, Version 1.0. 00009 * (See accompanying file LICENSE_1_0.txt or copy at 00010 * http://www.boost.org/LICENSE_1_0.txt) 00011 **************************************************************************/ 00012 00013 #ifndef STXXL_ADDRESSABLE_QUEUES_HEADER 00014 #define STXXL_ADDRESSABLE_QUEUES_HEADER 00015 00016 #include <set> 00017 #include <list> 00018 #include <map> 00019 00020 #include <stxxl/bits/namespace.h> 00021 00022 __STXXL_BEGIN_NAMESPACE 00023 00024 //! \brief An internal fifo queue that allows removing elements addressed with (a copy of) themselves. 00025 //! \tparam KeyType Type of contained elements. 00026 template <typename KeyType> 00027 class addressable_fifo_queue 00028 { 00029 typedef std::list<KeyType> container_t; 00030 typedef typename container_t::iterator container_iter_t; 00031 typedef std::map<KeyType, container_iter_t> meta_t; 00032 typedef typename meta_t::iterator meta_iter_t; 00033 00034 container_t vals; 00035 meta_t meta; 00036 00037 public: 00038 //! \brief Type of handle to an entry. For use with insert and remove. 00039 typedef meta_iter_t handle; 00040 00041 //! \brief Create an empty queue. 00042 addressable_fifo_queue() {} 00043 ~addressable_fifo_queue() {} 00044 00045 //! \brief Check if queue is empty. 00046 //! \return If queue is empty. 00047 bool empty() const 00048 { return vals.empty(); } 00049 00050 //! \brief Insert new element. If the element is already in, it is moved to the back. 00051 //! \param e Element to insert. 00052 //! \return pair<handle, bool> Iterator to element; if element was newly inserted. 00053 std::pair<handle, bool> insert(const KeyType & e) 00054 { 00055 container_iter_t ei = vals.insert(vals.end(), e); 00056 std::pair<handle, bool> r = meta.insert(std::make_pair(e, ei)); 00057 if (! r.second) 00058 { 00059 // element was already in 00060 vals.erase(r.first->second); 00061 r.first->second = ei; 00062 } 00063 return r; 00064 } 00065 00066 //! \brief Erase element from the queue. 00067 //! \param e Element to remove. 00068 //! \return If element was in. 00069 bool erase(const KeyType & e) 00070 { 00071 handle mi = meta.find(e); 00072 if (mi == meta.end()) 00073 return false; 00074 vals.erase(mi->second); 00075 meta.erase(mi); 00076 return true; 00077 } 00078 00079 //! \brief Erase element from the queue. 00080 //! \param i Iterator to element to remove. 00081 void erase(handle i) 00082 { 00083 vals.erase(i->second); 00084 meta.erase(i); 00085 } 00086 00087 //! \brief Access top element in the queue. 00088 //! \return Const reference to top element. 00089 const KeyType & top() const 00090 { return vals.front(); } 00091 00092 //! \brief Remove top element from the queue. 00093 //! \return Top element. 00094 KeyType pop() 00095 { 00096 assert(! empty()); 00097 const KeyType e = top(); 00098 meta.erase(e); 00099 vals.pop_front(); 00100 return e; 00101 } 00102 }; 00103 00104 //! \brief An internal priority queue that allows removing elements addressed with (a copy of) themselves. 00105 //! \tparam KeyType Type of contained elements. 00106 //! \tparam PriorityType Type of Priority. 00107 template < typename KeyType, typename PriorityType, class Cmp = std::less<PriorityType> > 00108 class addressable_priority_queue 00109 { 00110 struct cmp // like < for pair, but uses Cmp for < on first 00111 { 00112 bool operator()(const std::pair<PriorityType, KeyType> & left, 00113 const std::pair<PriorityType, KeyType> & right) const 00114 { 00115 Cmp c; 00116 return c(left.first, right.first) || 00117 ((! c(right.first, left.first)) && left.second < right.second); 00118 } 00119 }; 00120 00121 typedef std::set<std::pair<PriorityType, KeyType>, cmp> container_t; 00122 typedef typename container_t::iterator container_iter_t; 00123 typedef std::map<KeyType, container_iter_t> meta_t; 00124 typedef typename meta_t::iterator meta_iter_t; 00125 00126 container_t vals; 00127 meta_t meta; 00128 00129 public: 00130 //! \brief Type of handle to an entry. For use with insert and remove. 00131 typedef meta_iter_t handle; 00132 00133 //! \brief Create an empty queue. 00134 addressable_priority_queue() {} 00135 ~addressable_priority_queue() {} 00136 00137 //! \brief Check if queue is empty. 00138 //! \return If queue is empty. 00139 bool empty() const 00140 { return vals.empty(); } 00141 00142 //! \brief Insert new element. If the element is already in, it's priority is updated. 00143 //! \param e Element to insert. 00144 //! \param o Priority of element. 00145 //! \return pair<handle, bool> Iterator to element; if element was newly inserted. 00146 std::pair<handle, bool> insert(const KeyType & e, const PriorityType o) 00147 { 00148 std::pair<container_iter_t ,bool> s = vals.insert(std::make_pair(o, e)); 00149 std::pair<handle, bool> r = meta.insert(std::make_pair(e, s.first)); 00150 if (! r.second && s.second) 00151 { 00152 // was already in with different priority 00153 vals.erase(r.first->second); 00154 r.first->second = s.first; 00155 } 00156 return r; 00157 } 00158 00159 //! \brief Erase element from the queue. 00160 //! \param e Element to remove. 00161 //! \return If element was in. 00162 bool erase(const KeyType & e) 00163 { 00164 handle mi = meta.find(e); 00165 if (mi == meta.end()) 00166 return false; 00167 vals.erase(mi->second); 00168 meta.erase(mi); 00169 return true; 00170 } 00171 00172 //! \brief Erase element from the queue. 00173 //! \param i Iterator to element to remove. 00174 void erase(handle i) 00175 { 00176 vals.erase(i->second); 00177 meta.erase(i); 00178 } 00179 00180 //! \brief Access top (= min) element in the queue. 00181 //! \return Const reference to top element. 00182 const KeyType & top() const 00183 { return vals.begin()->second; } 00184 00185 //! \brief Remove top (= min) element from the queue. 00186 //! \return Top element. 00187 KeyType pop() 00188 { 00189 assert(! empty()); 00190 const KeyType e = top(); 00191 meta.erase(e); 00192 vals.erase(vals.begin()); 00193 return e; 00194 } 00195 }; 00196 00197 __STXXL_END_NAMESPACE 00198 00199 #endif /* STXXL_ADDRESSABLE_QUEUES_HEADER */