PageRenderTime 39ms CodeModel.GetById 15ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/llmessagethrottle.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 176 lines | 107 code | 23 blank | 46 comment | 14 complexity | 9dd384d2426cc8a447b3cc6d9ae6266d MD5 | raw file
  1/** 
  2 * @file llmessagethrottle.cpp
  3 * @brief LLMessageThrottle class used for throttling messages.
  4 *
  5 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "linden_common.h"
 28
 29#include "llhash.h"
 30
 31#include "llmessagethrottle.h"
 32#include "llframetimer.h"
 33
 34// This is used for the stl search_n function.
 35#if _MSC_VER >= 1500 // VC9 has a bug in search_n
 36struct eq_message_throttle_entry : public std::binary_function< LLMessageThrottleEntry, LLMessageThrottleEntry, bool >
 37{
 38	bool operator()(const LLMessageThrottleEntry& a, const LLMessageThrottleEntry& b) const
 39	{
 40		return a.getHash() == b.getHash();
 41	}
 42};
 43#else
 44bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b)
 45 		{ return a.getHash() == b.getHash(); }
 46#endif
 47
 48const U64 SEC_TO_USEC = 1000000;
 49		
 50// How long (in microseconds) each type of message stays in its throttle list.
 51const U64 MAX_MESSAGE_AGE[MTC_EOF] =
 52{
 53	10 * SEC_TO_USEC,	// MTC_VIEWER_ALERT
 54	10 * SEC_TO_USEC	// MTC_AGENT_ALERT
 55};
 56
 57LLMessageThrottle::LLMessageThrottle()
 58{
 59}
 60
 61LLMessageThrottle::~LLMessageThrottle()
 62{
 63}
 64
 65void LLMessageThrottle::pruneEntries()
 66{
 67	// Go through each message category, and prune entries older than max age.
 68	S32 cat;
 69	for (cat = 0; cat < MTC_EOF; cat++)
 70	{
 71		message_list_t* message_list = &(mMessageList[cat]);
 72
 73		// Use a reverse iterator, since entries on the back will be the oldest.
 74		message_list_reverse_iterator_t r_iterator 	= message_list->rbegin();
 75		message_list_reverse_iterator_t r_last 		= message_list->rend();
 76
 77		// Look for the first entry younger than the maximum age.
 78		F32 max_age = (F32)MAX_MESSAGE_AGE[cat]; 
 79		BOOL found = FALSE;
 80		while (r_iterator != r_last && !found)
 81		{
 82			if ( LLFrameTimer::getTotalTime() - (*r_iterator).getEntryTime() < max_age )
 83			{
 84				// We found a young enough entry.
 85				found = TRUE;
 86
 87				// Did we find at least one entry to remove?
 88				if (r_iterator != message_list->rbegin())
 89				{
 90					// Yes, remove it.
 91					message_list->erase(r_iterator.base(), message_list->end());
 92				}
 93			}
 94			else
 95			{
 96				r_iterator++;
 97			}
 98		}
 99
100		// If we didn't find any entries young enough to keep, remove them all.
101		if (!found)
102		{
103			message_list->clear();
104		}
105	}
106}
107
108BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg)
109{
110	message_list_t* message_list = &(mMessageList[MTC_VIEWER_ALERT]);
111
112	// Concatenate from,to,mesg into one string.
113	std::ostringstream full_mesg;
114	full_mesg << to << mesg;
115
116	// Create an entry for this message.
117	size_t hash = llhash(full_mesg.str().c_str());
118	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
119
120	// Check if this message is already in the list.
121#if _MSC_VER >= 1500 // VC9 has a bug in search_n
122	// SJB: This *should* work but has not been tested yet *TODO: Test!
123	message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
124												 std::bind2nd(eq_message_throttle_entry(), entry));
125#else
126 	message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
127 												  1, entry, eq_message_throttle_entry);
128#endif
129	if (found == message_list->end())
130	{
131		// This message was not found.  Add it to the list.
132		message_list->push_front(entry);
133		return TRUE;
134	}
135	else
136	{
137		// This message was already in the list.
138		return FALSE;
139	}
140}
141
142BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, const std::string& mesg)
143{
144	message_list_t* message_list = &(mMessageList[MTC_AGENT_ALERT]);
145
146	// Concatenate from,to,mesg into one string.
147	std::ostringstream full_mesg;
148	full_mesg << agent << task << mesg;
149
150	// Create an entry for this message.
151	size_t hash = llhash(full_mesg.str().c_str());
152	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
153
154	// Check if this message is already in the list.
155#if _MSC_VER >= 1500 // VC9 has a bug in search_n
156	// SJB: This *should* work but has not been tested yet *TODO: Test!
157	message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
158												 std::bind2nd(eq_message_throttle_entry(), entry));
159#else
160	message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
161												  1, entry, eq_message_throttle_entry);
162#endif
163	
164	if (found == message_list->end())
165	{
166		// This message was not found.  Add it to the list.
167		message_list->push_front(entry);
168		return TRUE;
169	}
170	else
171	{
172		// This message was already in the list.
173		return FALSE;
174	}
175}
176