From b0f1e4f0c69ecdeca0bd2461fc7a19dde94f3ad3 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 8 Sep 2020 15:28:18 +0100 Subject: [PATCH] waste some memory on serialized environment caching. we could live without all that locking --- OpenSim/Framework/ViewerEnvironment.cs | 67 +++++++++++++++++++ .../World/LightShare/EnvironmentModule.cs | 54 ++++++++------- 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/OpenSim/Framework/ViewerEnvironment.cs b/OpenSim/Framework/ViewerEnvironment.cs index 547d7c2952..f617742ecd 100644 --- a/OpenSim/Framework/ViewerEnvironment.cs +++ b/OpenSim/Framework/ViewerEnvironment.cs @@ -98,6 +98,8 @@ namespace OpenSim.Framework Cycle = new DayCycle(); Cycle.FromWLOSD(array); } + + InvalidateCaches(); } public OSD ToWLOSD(UUID message, UUID region) @@ -244,6 +246,8 @@ namespace OpenSim.Framework Cycle.skyframes.Add(sky.Name, sky); track = new DayCycle.TrackEntry(-1, sky.Name); Cycle.skyTrack0.Add(track); + + InvalidateCaches(); } public RegionLightShareData ToLightShare() @@ -346,6 +350,7 @@ namespace OpenSim.Framework } IsLegacy = false; + InvalidateCaches(); } public void SortAltitudes() @@ -380,6 +385,9 @@ namespace OpenSim.Framework return false; Cycle = new DayCycle(); Cycle.FromOSD(map); + + InvalidateCaches(); + return true; } @@ -416,6 +424,8 @@ namespace OpenSim.Framework } if(ok && !string.IsNullOrWhiteSpace(name)) Cycle.Name = name; + + InvalidateCaches(); return ok; } @@ -436,6 +446,63 @@ namespace OpenSim.Framework return env; } + public readonly object m_cachedbytesLock = new object(); + public byte[] m_cachedbytes = null; + public byte[] m_cachedWLbytes = null; + + public void InvalidateCaches() + { + lock (m_cachedbytesLock) + { + m_cachedbytes = null; + m_cachedWLbytes = null; + } + } + + public byte[] ToCapBytes(UUID regionID, int parcelID) + { + //byte[] ret = m_cachedbytes; + //if(ret != null) + // return ret; + + lock (m_cachedbytesLock) + { + byte[] ret = m_cachedbytes; + if (ret == null) + { + OSDMap map = new OSDMap(); + OSDMap cenv = (OSDMap)ToOSD(); + cenv["parcel_id"] = parcelID; + cenv["region_id"] = regionID; + map["environment"] = cenv; + map["parcel_id"] = parcelID; + map["success"] = true; + ret = OSDParser.SerializeLLSDXmlToBytes(map); + m_cachedbytes = ret; + } + return ret; + } + } + + public byte[] ToCapWLBytes(UUID messageID, UUID regionID) + { + //byte[] ret = m_cachedWLbytes; + //if (ret != null) + // return ret; + + lock (m_cachedbytesLock) + { + byte[] ret = m_cachedWLbytes; + if (ret == null) + { + OSD d = ToWLOSD(messageID, regionID); + ret = OSDParser.SerializeLLSDXmlToBytes(d); + m_cachedWLbytes = ret; + } + return ret; + } + } + public static ViewerEnvironment FromOSDString(string s) { try diff --git a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs index ae272d7f8e..9309e3bc76 100644 --- a/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs +++ b/OpenSim/Region/CoreModules/World/LightShare/EnvironmentModule.cs @@ -470,15 +470,15 @@ namespace OpenSim.Region.CoreModules.World.LightShare if(sp != null && sp.Environment != null) { - if (parcelid == -1) + //if (parcelid == -1) VEnv = sp.Environment; - else - { - OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid); - httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def); - httpResponse.StatusCode = (int)HttpStatusCode.OK; - return; - } + //else + //{ + // OSD def = ViewerEnvironment.DefaultToOSD(regionID, parcelid); + // httpResponse.RawBuffer = OSDParser.SerializeLLSDXmlToBytes(def); + // httpResponse.StatusCode = (int)HttpStatusCode.OK; + // return; + //} } else if (parcelid == -1) VEnv = GetRegionEnvironment(); @@ -499,17 +499,19 @@ namespace OpenSim.Region.CoreModules.World.LightShare } } - OSDMap map = new OSDMap(); - OSDMap cenv = (OSDMap)VEnv.ToOSD(); - cenv["parcel_id"] = parcelid; - cenv["region_id"] = regionID; - map["environment"] = cenv; - map["parcel_id"] = parcelid; - map["success"] = true; + //OSDMap map = new OSDMap(); + //OSDMap cenv = (OSDMap)VEnv.ToOSD(); + //cenv["parcel_id"] = parcelid; + //cenv["region_id"] = regionID; + //map["environment"] = cenv; + //map["parcel_id"] = parcelid; + //map["success"] = true; - string env = OSDParser.SerializeLLSDXmlString(map); + //string env = OSDParser.SerializeLLSDXmlString(map); - if (String.IsNullOrEmpty(env)) + //if (String.IsNullOrEmpty(env)) + byte[] envBytes = VEnv.ToCapBytes(regionID, parcelid); + if(envBytes == null) { StringBuilder sb = LLSDxmlEncode.Start(); LLSDxmlEncode.AddArray(sb); @@ -518,10 +520,11 @@ namespace OpenSim.Region.CoreModules.World.LightShare LLSDxmlEncode.AddElem("regionID", regionID, sb); LLSDxmlEncode.AddEndMap(sb); LLSDxmlEncode.AddEndArray(sb); - env = LLSDxmlEncode.End(sb); + httpResponse.RawBuffer = LLSDxmlEncode.EndToNBBytes(sb); } + else + httpResponse.RawBuffer = envBytes; - httpResponse.RawBuffer = Util.UTF8NBGetbytes(env); httpResponse.StatusCode = (int)HttpStatusCode.OK; } @@ -719,10 +722,12 @@ namespace OpenSim.Region.CoreModules.World.LightShare VEnv = GetRegionEnvironment(); } - OSD d = VEnv.ToWLOSD(UUID.Zero, regionID); - string env = OSDParser.SerializeLLSDXmlString(d); + //OSD d = VEnv.ToWLOSD(UUID.Zero, regionID); + //string env = OSDParser.SerializeLLSDXmlString(d); - if (String.IsNullOrEmpty(env)) + //if (String.IsNullOrEmpty(env)) + byte[] envBytes = VEnv.ToCapWLBytes(UUID.Zero, regionID); + if(envBytes == null) { StringBuilder sb = LLSDxmlEncode.Start(); LLSDxmlEncode.AddArray(sb); @@ -731,10 +736,11 @@ namespace OpenSim.Region.CoreModules.World.LightShare LLSDxmlEncode.AddElem("regionID", regionID, sb); LLSDxmlEncode.AddEndMap(sb); LLSDxmlEncode.AddEndArray(sb); - env = LLSDxmlEncode.End(sb); + response.RawBuffer = LLSDxmlEncode.EndToNBBytes(sb); } + else + response.RawBuffer = envBytes; - response.RawBuffer = Util.UTF8NBGetbytes(env); response.StatusCode = (int)HttpStatusCode.OK; }