00001
00032 #include "linden_common.h"
00033
00034 #include "llhash.h"
00035
00036 #include "llmessagethrottle.h"
00037 #include "llframetimer.h"
00038
00039
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
00056 const U64 MAX_MESSAGE_AGE[MTC_EOF] =
00057 {
00058 10 * SEC_TO_USEC,
00059 10 * SEC_TO_USEC
00060 };
00061
00062 LLMessageThrottle::LLMessageThrottle()
00063 {
00064 }
00065
00066 LLMessageThrottle::~LLMessageThrottle()
00067 {
00068 }
00069
00070 void LLMessageThrottle::pruneEntries()
00071 {
00072
00073 S32 cat;
00074 for (cat = 0; cat < MTC_EOF; cat++)
00075 {
00076 message_list_t* message_list = &(mMessageList[cat]);
00077
00078
00079 message_list_reverse_iterator_t r_iterator = message_list->rbegin();
00080 message_list_reverse_iterator_t r_last = message_list->rend();
00081
00082
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
00090 found = TRUE;
00091
00092
00093 if (r_iterator != message_list->rbegin())
00094 {
00095
00096 message_list->erase(r_iterator.base(), message_list->end());
00097 }
00098 }
00099 else
00100 {
00101 r_iterator++;
00102 }
00103 }
00104
00105
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
00118 std::ostringstream full_mesg;
00119 full_mesg << to << mesg;
00120
00121
00122 size_t hash = llhash<const char*> (full_mesg.str().c_str());
00123 LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
00124
00125
00126 #if _MSC_VER >= 1500 // VC9 has a bug in search_n
00127
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
00137 message_list->push_front(entry);
00138 return TRUE;
00139 }
00140 else
00141 {
00142
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
00152 std::ostringstream full_mesg;
00153 full_mesg << agent << task << mesg;
00154
00155
00156 size_t hash = llhash<const char*> (full_mesg.str().c_str());
00157 LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
00158
00159
00160 #if _MSC_VER >= 1500 // VC9 has a bug in search_n
00161
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
00172 message_list->push_front(entry);
00173 return TRUE;
00174 }
00175 else
00176 {
00177
00178 return FALSE;
00179 }
00180 }
00181