llindexedqueue.h

Go to the documentation of this file.
00001 
00033 #ifndef LL_LLINDEXEDQUEUE_H
00034 #define LL_LLINDEXEDQUEUE_H
00035 
00036 // An indexed FIFO queue, where only one element with each key can be in the queue.
00037 // This is ONLY used in the interest list, you'll probably want to review this code
00038 // carefully if you want to use it elsewhere - Doug
00039 
00040 template <typename Type> 
00041 class LLIndexedQueue
00042 {
00043 protected:
00044         typedef std::deque<Type> type_deque;
00045         type_deque mQueue;
00046         std::set<Type> mKeySet;
00047 
00048 public:
00049         LLIndexedQueue() {}
00050 
00051         // move_if_there is an O(n) operation
00052         bool push_back(const Type &value, bool move_if_there = false)
00053         {
00054                 if (mKeySet.find(value) != mKeySet.end())
00055                 {
00056                         // Already on the queue
00057                         if (move_if_there)
00058                         {
00059                                 // Remove the existing entry.
00060                                 typename type_deque::iterator it;
00061                                 for (it = mQueue.begin(); it != mQueue.end(); ++it)
00062                                 {
00063                                         if (*it == value)
00064                                         {
00065                                                 break;
00066                                         }
00067                                 }
00068 
00069                                 // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
00070                                 // (although this isn't thread safe, at all)
00071 
00072                                 mQueue.erase(it);
00073                         }
00074                         else
00075                         {
00076                                 // We're not moving it, leave it alone
00077                                 return false;
00078                         }
00079                 }
00080                 else
00081                 {
00082                         // Doesn't exist, add it to the key set
00083                         mKeySet.insert(value);
00084                 }
00085 
00086                 mQueue.push_back(value);
00087 
00088                 // We succeeded in adding the new element.
00089                 return true;
00090         }
00091 
00092         bool push_front(const Type &value, bool move_if_there = false)
00093         {
00094                 if (mKeySet.find(value) != mKeySet.end())
00095                 {
00096                         // Already on the queue
00097                         if (move_if_there)
00098                         {
00099                                 // Remove the existing entry.
00100                                 typename type_deque::iterator it;
00101                                 for (it = mQueue.begin(); it != mQueue.end(); ++it)
00102                                 {
00103                                         if (*it == value)
00104                                         {
00105                                                 break;
00106                                         }
00107                                 }
00108 
00109                                 // This HAS to succeed, otherwise there's a serious bug in the keyset implementation
00110                                 // (although this isn't thread safe, at all)
00111 
00112                                 mQueue.erase(it);
00113                         }
00114                         else
00115                         {
00116                                 // We're not moving it, leave it alone
00117                                 return false;
00118                         }
00119                 }
00120                 else
00121                 {
00122                         // Doesn't exist, add it to the key set
00123                         mKeySet.insert(value);
00124                 }
00125 
00126                 mQueue.push_front(value);
00127                 return true;
00128         }
00129 
00130         void pop()
00131         {
00132                 Type value = mQueue.front();
00133                 mKeySet.erase(value);
00134                 mQueue.pop_front();
00135         }
00136 
00137         Type &front()
00138         {
00139                 return mQueue.front();
00140         }
00141 
00142         S32 size() const
00143         {
00144                 return mQueue.size();
00145         }
00146 
00147         bool empty() const
00148         {
00149                 return mQueue.empty();
00150         }
00151 
00152         void clear()
00153         {
00154                 // Clear out all elements on the queue
00155                 mQueue.clear();
00156                 mKeySet.clear();
00157         }
00158 };
00159 
00160 #endif // LL_LLINDEXEDQUEUE_H

Generated on Thu Jul 1 06:08:44 2010 for Second Life Viewer by  doxygen 1.4.7