llpriqueuemap.h

Go to the documentation of this file.
00001 
00031 #ifndef LL_LLPRIQUEUEMAP_H
00032 #define LL_LLPRIQUEUEMAP_H
00033 
00034 #include <map>
00035 
00036 //
00037 // Priority queue, implemented under the hood as a
00038 // map.  Needs to be done this way because none of the
00039 // standard STL containers provide a representation
00040 // where it's easy to reprioritize.
00041 //
00042 
00043 template <class DATA>
00044 class LLPQMKey
00045 {
00046 public:
00047         LLPQMKey(const F32 priority, DATA data) : mPriority(priority), mData(data)
00048         {
00049         }
00050 
00051         bool operator<(const LLPQMKey &b) const
00052         {
00053                 if (mPriority > b.mPriority)
00054                 {
00055                         return TRUE;
00056                 }
00057                 if (mPriority < b.mPriority)
00058                 {
00059                         return FALSE;
00060                 }
00061                 if (mData > b.mData)
00062                 {
00063                         return TRUE;
00064                 }
00065                 return FALSE;
00066         }
00067 
00068         F32 mPriority;
00069         DATA mData;
00070 };
00071 
00072 template <class DATA_TYPE>
00073 class LLPriQueueMap
00074 {
00075 public:
00076         typedef typename std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE>::iterator pqm_iter;
00077         typedef std::pair<LLPQMKey<DATA_TYPE>, DATA_TYPE> pqm_pair;
00078         typedef void (*set_pri_fn)(DATA_TYPE &data, const F32 priority);
00079         typedef F32 (*get_pri_fn)(DATA_TYPE &data);
00080 
00081 
00082         LLPriQueueMap(set_pri_fn set_pri, get_pri_fn get_pri) : mSetPriority(set_pri), mGetPriority(get_pri)
00083         {
00084         }
00085 
00086         void push(const F32 priority, DATA_TYPE data)
00087         {
00088 #ifdef _DEBUG
00089                 pqm_iter iter = mMap.find(LLPQMKey<DATA_TYPE>(priority, data));
00090                 if (iter != mMap.end())
00091                 {
00092                         llerrs << "Pushing already existing data onto queue!" << llendl;
00093                 }
00094 #endif
00095                 mMap.insert(pqm_pair(LLPQMKey<DATA_TYPE>(priority, data), data));
00096         }
00097 
00098         BOOL pop(DATA_TYPE *datap)
00099         {
00100                 pqm_iter iter;
00101                 iter = mMap.begin();
00102                 if (iter == mMap.end())
00103                 {
00104                         return FALSE;
00105                 }
00106                 *datap = (*(iter)).second;
00107                 mMap.erase(iter);
00108 
00109                 return TRUE;
00110         }
00111 
00112         void reprioritize(const F32 new_priority, DATA_TYPE data)
00113         {
00114                 pqm_iter iter;
00115                 F32 cur_priority = mGetPriority(data);
00116                 LLPQMKey<DATA_TYPE> cur_key(cur_priority, data);
00117                 iter = mMap.find(cur_key);
00118                 if (iter == mMap.end())
00119                 {
00120                         llwarns << "Data not on priority queue!" << llendl;
00121                         // OK, try iterating through all of the data and seeing if we just screwed up the priority
00122                         // somehow.
00123                         for (iter = mMap.begin(); iter != mMap.end(); iter++)
00124                         {
00125                                 if ((*(iter)).second == data)
00126                                 {
00127                                         llerrs << "Data on priority queue but priority not matched!" << llendl;
00128                                 }
00129                         }
00130                         return;
00131                 }
00132 
00133                 mMap.erase(iter);
00134                 mSetPriority(data, new_priority);
00135                 push(new_priority, data);
00136         }
00137 
00138         S32 getLength() const
00139         {
00140                 return (S32)mMap.size();
00141         }
00142 
00143         // Hack: public for use by the transfer manager, ugh.
00144         std::map<LLPQMKey<DATA_TYPE>, DATA_TYPE> mMap;
00145 protected:
00146         void (*mSetPriority)(DATA_TYPE &data, const F32 priority);
00147         F32 (*mGetPriority)(DATA_TYPE &data);
00148 };
00149 
00150 #endif // LL_LLPRIQUEUEMAP_H

Generated on Fri May 16 08:32:04 2008 for SecondLife by  doxygen 1.5.5