summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llui/llkeywords.cpp56
1 files changed, 20 insertions, 36 deletions
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index 19376ad8fa..bec9819cde 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -37,35 +37,14 @@
inline bool LLKeywordToken::isHead(const llwchar* s) const
{
- // strncmp is much faster than string compare
- bool res = true;
- const llwchar* t = mToken.c_str();
- auto len = mToken.size();
- for (S32 i=0; i<len; i++)
- {
- if (s[i] != t[i])
- {
- res = false;
- break;
- }
- }
- return res;
+ size_t bytes = mToken.size() * sizeof(llwchar);
+ return std::memcmp(s, mToken.c_str(), bytes) == 0;
}
inline bool LLKeywordToken::isTail(const llwchar* s) const
{
- bool res = true;
- const llwchar* t = mDelimiter.c_str();
- auto len = mDelimiter.size();
- for (S32 i=0; i<len; i++)
- {
- if (s[i] != t[i])
- {
- res = false;
- break;
- }
- }
- return res;
+ size_t len_bytes = mDelimiter.size() * sizeof(llwchar);
+ return std::memcmp(s, mDelimiter.c_str(), len_bytes) == 0;
}
LLKeywords::LLKeywords()
@@ -531,10 +510,20 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
return;
}
+ // Reserve capacity for segments based on an estimated average of 8 characters per segment.
+ constexpr size_t AVERAGE_SEGMENT_LENGTH = 8;
+ seg_list->reserve(wtext.size() / AVERAGE_SEGMENT_LENGTH);
+
S32 text_len = static_cast<S32>(wtext.size()) + 1;
seg_list->push_back( new LLNormalTextSegment( style, 0, text_len, editor ) );
+ std::string text_to_search;
+ text_to_search.reserve(wtext.size());
+
+ bool has_regex = !mRegexTokenList.empty();
+ auto& delimiters = mDelimiterTokenList;
+
const llwchar* base = wtext.c_str();
const llwchar* cur = base;
while( *cur )
@@ -606,11 +595,11 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
{
// Check for regex matches first
bool regex_matched = false;
- if (!mRegexTokenList.empty())
+ if (has_regex)
{
S32 seg_start = (S32)(cur - base);
- std::string text_to_search(wtext.begin() + seg_start, wtext.end());
+ text_to_search.assign(wtext.begin() + seg_start, wtext.end());
for (LLKeywordToken* regex_token : mRegexTokenList)
{
@@ -731,10 +720,8 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
{
S32 seg_start = 0;
LLKeywordToken* cur_delimiter = NULL;
- for (token_list_t::iterator iter = mDelimiterTokenList.begin();
- iter != mDelimiterTokenList.end(); ++iter)
+ for (auto* delimiter : delimiters)
{
- LLKeywordToken* delimiter = *iter;
if( delimiter->isHead( cur ) )
{
cur_delimiter = delimiter;
@@ -846,8 +833,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
S32 seg_end = seg_start + seg_len;
// First try to match the whole token (including dots for Lua namespaces)
- WStringMapIndex whole_token(word_start, seg_len);
- word_token_map_t::iterator map_iter = mWordTokenMap.find(whole_token);
+ word_token_map_t::iterator map_iter = mWordTokenMap.find(WStringMapIndex(word_start, seg_len));
if (map_iter != mWordTokenMap.end())
{
@@ -863,8 +849,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
{
// Get the namespace prefix (part before the first dot)
S32 prefix_len = (S32)(last_dot - word_start);
- WStringMapIndex prefix_token(word_start, prefix_len);
- map_iter = mWordTokenMap.find(prefix_token);
+ map_iter = mWordTokenMap.find(WStringMapIndex(word_start, prefix_len));
if (map_iter != mWordTokenMap.end())
{
@@ -879,8 +864,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
if (func_len > 0)
{
// Look for complete function matches
- WStringMapIndex func_token(func_part, func_len);
- map_iter = mWordTokenMap.find(func_token);
+ map_iter = mWordTokenMap.find(WStringMapIndex(func_part, func_len));
if (map_iter != mWordTokenMap.end())
{