From 1aa62cebbdd811d75fdb0bfd563cd75a2f87897c Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Wed, 29 Jul 2020 09:46:45 -0400
Subject: [PATCH] Make LLSD use hashmaps as the map type

---
 indra/llcommon/llsd.cpp              | 14 +++++++-------
 indra/llcommon/llsd.h                | 10 +++++-----
 indra/llcommon/llsdserialize.cpp     | 18 ++++++++----------
 indra/llcommon/llsdserialize_xml.cpp |  9 ++++-----
 4 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 14fb7cc64a7..a55d2397ca8 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -141,8 +141,8 @@ class LLSD::Impl
 	virtual void erase(Integer)					{ }
 	virtual const LLSD& ref(Integer) const		{ return undef(); }
 
-	virtual const std::map<String, LLSD>& map() const { static const std::map<String, LLSD> empty; return empty; }
-	virtual std::map<String, LLSD>& map() { static std::map<String, LLSD> empty; return empty; }
+	virtual const absl::node_hash_map<String, LLSD>& map() const { static const absl::node_hash_map<String, LLSD> empty; return empty; }
+	virtual absl::node_hash_map<String, LLSD>& map() { static absl::node_hash_map<String, LLSD> empty; return empty; }
 	LLSD::map_const_iterator beginMap() const { return endMap(); }
 	LLSD::map_const_iterator endMap() const { return map().end(); }
 	virtual const std::vector<LLSD>& array() const { static const std::vector<LLSD> empty; return empty; }
@@ -364,7 +364,7 @@ namespace
 	class ImplMap : public LLSD::Impl
 	{
 	private:
-		typedef std::map<LLSD::String, LLSD>	DataMap;
+		typedef absl::node_hash_map<LLSD::String, LLSD>	DataMap;
 		
 		DataMap mData;
 		
@@ -456,8 +456,8 @@ namespace
 	
 	const LLSD& ImplMap::ref(const LLSD::String& k) const
 	{
-		DataMap::const_iterator i = mData.lower_bound(k);
-		if (i == mData.end()  ||  mData.key_comp()(k, i->first))
+		DataMap::const_iterator i = mData.find(k);
+		if (i == mData.end())
 		{
 			return undef();
 		}
@@ -956,8 +956,8 @@ const char *LLSD::dump(const LLSD &llsd)
 	return llsd_dump(llsd, false);
 }
 
-std::map<LLSD::String, LLSD>& LLSD::map() { return makeMap(impl).map(); }
-const std::map<LLSD::String, LLSD>& LLSD::map() const { return safe(impl).map(); }
+absl::node_hash_map<LLSD::String, LLSD>& LLSD::map() { return makeMap(impl).map(); }
+const absl::node_hash_map<LLSD::String, LLSD>& LLSD::map() const { return safe(impl).map(); }
 
 LLSD::map_iterator			LLSD::beginMap()		{ return map().begin(); }
 LLSD::map_iterator			LLSD::endMap()			{ return map().end(); }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 1d4826c6386..7aa610a1968 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLSD_NEW_H
 #define LL_LLSD_NEW_H
 
-#include <map>
+#include <absl/container/node_hash_map.h>
 #include <string>
 #include <vector>
 
@@ -314,11 +314,11 @@ class LL_COMMON_API LLSD
 	//@{
 		int size() const;
 
-		typedef std::map<String, LLSD>::iterator		map_iterator;
-		typedef std::map<String, LLSD>::const_iterator	map_const_iterator;
+		typedef absl::node_hash_map<String, LLSD>::iterator		map_iterator;
+		typedef absl::node_hash_map<String, LLSD>::const_iterator	map_const_iterator;
 		
-		std::map<String, LLSD>& map();
-		const std::map<String, LLSD>& map() const;
+		absl::node_hash_map<String, LLSD>& map();
+		const absl::node_hash_map<String, LLSD>& map() const;
 
 		map_iterator		beginMap();
 		map_iterator		endMap();
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 1424132f84b..55b338d2f2c 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1323,16 +1323,15 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr,
 		}
 
 		bool need_comma = false;
-		LLSD::map_const_iterator iter = data.beginMap();
-		LLSD::map_const_iterator end = data.endMap();
-		for(; iter != end; ++iter)
+		std::map<std::string, LLSD> sorted_map(data.beginMap(), data.endMap());
+		for(const auto& out_pair : sorted_map)
 		{
 			if(need_comma) ostr << ",";
 			need_comma = true;
 			ostr << post << inner_pre << '\'';
-			serialize_string((*iter).first, ostr);
+			serialize_string(out_pair.first, ostr);
 			ostr << "':";
-			format_count += format_impl((*iter).second, ostr, options, level + 2);
+			format_count += format_impl(out_pair.second, ostr, options, level + 2);
 		}
 		ostr << post << pre << "}";
 		break;
@@ -1484,13 +1483,12 @@ S32 LLSDBinaryFormatter::format_impl(const LLSD& data, std::ostream& ostr,
 		ostr.put('{');
 		U32 size_nbo = htonl(data.size());
 		ostr.write((const char*)(&size_nbo), sizeof(U32));
-		LLSD::map_const_iterator iter = data.beginMap();
-		LLSD::map_const_iterator end = data.endMap();
-		for(; iter != end; ++iter)
+		std::map<std::string, LLSD> sorted_map(data.beginMap(), data.endMap());
+		for (const auto& out_pair : sorted_map)
 		{
 			ostr.put('k');
-			formatString((*iter).first, ostr);
-			format_count += format_impl((*iter).second, ostr, options, level+1);
+			formatString(out_pair.first, ostr);
+			format_count += format_impl(out_pair.second, ostr, options, level+1);
 		}
 		ostr.put('}');
 		break;
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 0da824d6945..772924397df 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -101,12 +101,11 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr,
 		else
 		{
 			ostr << pre << "<map>" << post;
-			LLSD::map_const_iterator iter = data.beginMap();
-			LLSD::map_const_iterator end = data.endMap();
-			for(; iter != end; ++iter)
+			std::map<std::string, LLSD> sorted_map(data.beginMap(), data.endMap());
+			for(const auto& out_pair : sorted_map)
 			{
-				ostr << pre << "<key>" << escapeString((*iter).first) << "</key>" << post;
-				format_count += format_impl((*iter).second, ostr, options, level + 1);
+				ostr << pre << "<key>" << escapeString(out_pair.first) << "</key>" << post;
+				format_count += format_impl(out_pair.second, ostr, options, level + 1);
 			}
 			ostr << pre <<  "</map>" << post;
 		}
-- 
GitLab