llmessagethrottle.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llhash.h"
00035 
00036 #include "llmessagethrottle.h"
00037 #include "llframetimer.h"
00038 
00039 // This is used for the stl search_n function.
00040 #if _MSC_VER >= 1500 // VC9 has a bug in search_n
00041 struct eq_message_throttle_entry : public std::binary_function< LLMessageThrottleEntry, LLMessageThrottleEntry, bool >
00042 {
00043         bool operator()(const LLMessageThrottleEntry& a, const LLMessageThrottleEntry& b) const
00044         {
00045                 return a.getHash() == b.getHash();
00046         }
00047 };
00048 #else
00049 bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b)
00050                 { return a.getHash() == b.getHash(); }
00051 #endif
00052 
00053 const U64 SEC_TO_USEC = 1000000;
00054                 
00055 // How long (in microseconds) each type of message stays in its throttle list.
00056 const U64 MAX_MESSAGE_AGE[MTC_EOF] =
00057 {
00058         10 * SEC_TO_USEC,       // MTC_VIEWER_ALERT
00059         10 * SEC_TO_USEC        // MTC_AGENT_ALERT
00060 };
00061 
00062 LLMessageThrottle::LLMessageThrottle()
00063 {
00064 }
00065 
00066 LLMessageThrottle::~LLMessageThrottle()
00067 {
00068 }
00069 
00070 void LLMessageThrottle::pruneEntries()
00071 {
00072         // Go through each message category, and prune entries older than max age.
00073         S32 cat;
00074         for (cat = 0; cat < MTC_EOF; cat++)
00075         {
00076                 message_list_t* message_list = &(mMessageList[cat]);
00077 
00078                 // Use a reverse iterator, since entries on the back will be the oldest.
00079                 message_list_reverse_iterator_t r_iterator      = message_list->rbegin();
00080                 message_list_reverse_iterator_t r_last          = message_list->rend();
00081 
00082                 // Look for the first entry younger than the maximum age.
00083                 F32 max_age = (F32)MAX_MESSAGE_AGE[cat]; 
00084                 BOOL found = FALSE;
00085                 while (r_iterator != r_last && !found)
00086                 {
00087                         if ( LLFrameTimer::getTotalTime() - (*r_iterator).getEntryTime() < max_age )
00088                         {
00089                                 // We found a young enough entry.
00090                                 found = TRUE;
00091 
00092                                 // Did we find at least one entry to remove?
00093                                 if (r_iterator != message_list->rbegin())
00094                                 {
00095                                         // Yes, remove it.
00096                                         message_list->erase(r_iterator.base(), message_list->end());
00097                                 }
00098                         }
00099                         else
00100                         {
00101                                 r_iterator++;
00102                         }
00103                 }
00104 
00105                 // If we didn't find any entries young enough to keep, remove them all.
00106                 if (!found)
00107                 {
00108                         message_list->clear();
00109                 }
00110         }
00111 }
00112 
00113 BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const char* mesg)
00114 {
00115         message_list_t* message_list = &(mMessageList[MTC_VIEWER_ALERT]);
00116 
00117         // Concatenate from,to,mesg into one string.
00118         std::ostringstream full_mesg;
00119         full_mesg << to << mesg;
00120 
00121         // Create an entry for this message.
00122         size_t hash = llhash<const char*> (full_mesg.str().c_str());
00123         LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
00124 
00125         // Check if this message is already in the list.
00126 #if _MSC_VER >= 1500 // VC9 has a bug in search_n
00127         // SJB: This *should* work but has not been tested yet *TODO: Test!
00128         message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
00129                                                                                                  std::bind2nd(eq_message_throttle_entry(), entry));
00130 #else
00131         message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
00132                                                                                                   1, entry, eq_message_throttle_entry);
00133 #endif
00134         if (found == message_list->end())
00135         {
00136                 // This message was not found.  Add it to the list.
00137                 message_list->push_front(entry);
00138                 return TRUE;
00139         }
00140         else
00141         {
00142                 // This message was already in the list.
00143                 return FALSE;
00144         }
00145 }
00146 
00147 BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, const char* mesg)
00148 {
00149         message_list_t* message_list = &(mMessageList[MTC_AGENT_ALERT]);
00150 
00151         // Concatenate from,to,mesg into one string.
00152         std::ostringstream full_mesg;
00153         full_mesg << agent << task << mesg;
00154 
00155         // Create an entry for this message.
00156         size_t hash = llhash<const char*> (full_mesg.str().c_str());
00157         LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
00158 
00159         // Check if this message is already in the list.
00160 #if _MSC_VER >= 1500 // VC9 has a bug in search_n
00161         // SJB: This *should* work but has not been tested yet *TODO: Test!
00162         message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
00163                                                                                                  std::bind2nd(eq_message_throttle_entry(), entry));
00164 #else
00165         message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
00166                                                                                                   1, entry, eq_message_throttle_entry);
00167 #endif
00168         
00169         if (found == message_list->end())
00170         {
00171                 // This message was not found.  Add it to the list.
00172                 message_list->push_front(entry);
00173                 return TRUE;
00174         }
00175         else
00176         {
00177                 // This message was already in the list.
00178                 return FALSE;
00179         }
00180 }
00181 

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