Interns strings for aliases, etc... for when content is deserialized from the contentNu table so we aren't duplicating strings when cold booting.

This commit is contained in:
Shannon
2020-07-03 00:26:55 +10:00
parent d2042e28e1
commit e75c9d2273
11 changed files with 193 additions and 10 deletions

View File

@@ -18,8 +18,13 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
var dict = new Dictionary<string, CultureVariation>(StringComparer.InvariantCultureIgnoreCase);
for (var i = 0; i < pcount; i++)
{
var languageId = PrimitiveSerializer.String.ReadFrom(stream);
var cultureVariation = new CultureVariation { Name = ReadStringObject(stream), UrlSegment = ReadStringObject(stream), Date = ReadDateTime(stream) };
var languageId = string.Intern(PrimitiveSerializer.String.ReadFrom(stream));
var cultureVariation = new CultureVariation
{
Name = ReadStringObject(stream),
UrlSegment = ReadStringObject(stream),
Date = ReadDateTime(stream)
};
dict[languageId] = cultureVariation;
}
return dict;

View File

@@ -38,8 +38,8 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
// the 'current' value, and string.Empty should be used to represent the invariant or
// neutral values - PropertyData throws when getting nulls, so falling back to
// string.Empty here - what else?
pdata.Culture = string.Intern(ReadStringObject(stream)) ?? string.Empty;
pdata.Segment = string.Intern(ReadStringObject(stream)) ?? string.Empty;
pdata.Culture = ReadStringObject(stream, true) ?? string.Empty;
pdata.Segment = ReadStringObject(stream, true) ?? string.Empty;
pdata.Value = ReadObject(stream);
}

View File

@@ -11,11 +11,11 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
//dont serialize empty properties
[JsonProperty("pd")]
[JsonConverter(typeof(CaseInsensitiveDictionaryConverter<PropertyData[]>))]
[JsonConverter(typeof(AutoInterningStringKeyCaseInsensitiveDictionaryConverter<PropertyData[]>))]
public Dictionary<string, PropertyData[]> PropertyData { get; set; }
[JsonProperty("cd")]
[JsonConverter(typeof(CaseInsensitiveDictionaryConverter<CultureVariation>))]
[JsonConverter(typeof(AutoInterningStringKeyCaseInsensitiveDictionaryConverter<CultureVariation>))]
public Dictionary<string, CultureVariation> CultureData { get; set; }
[JsonProperty("us")]

View File

@@ -1,6 +1,7 @@
using System;
using System.ComponentModel;
using Newtonsoft.Json;
using Umbraco.Core.Serialization;
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
@@ -9,6 +10,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
private string _culture;
private string _segment;
[JsonConverter(typeof(AutoInterningStringConverter))]
[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, PropertyName = "c")]
public string Culture
@@ -17,6 +19,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
set => _culture = value ?? throw new ArgumentNullException(nameof(value)); // TODO: or fallback to string.Empty? CANNOT be null
}
[JsonConverter(typeof(AutoInterningStringConverter))]
[DefaultValue("")]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate, PropertyName = "s")]
public string Segment
@@ -28,7 +31,6 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
[JsonProperty("v")]
public object Value { get; set; }
//Legacy properties used to deserialize existing nucache db entries
[JsonProperty("culture")]
private string LegacyCulture

View File

@@ -23,13 +23,15 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
return read(stream);
}
protected string ReadStringObject(Stream stream) // required 'cos string is not a struct
protected string ReadStringObject(Stream stream, bool intern = false) // required 'cos string is not a struct
{
var type = PrimitiveSerializer.Char.ReadFrom(stream);
if (type == 'N') return null;
if (type != 'S')
throw new NotSupportedException($"Cannot deserialize type '{type}', expected 'S'.");
return PrimitiveSerializer.String.ReadFrom(stream);
return intern
? string.Intern(PrimitiveSerializer.String.ReadFrom(stream))
: PrimitiveSerializer.String.ReadFrom(stream);
}
protected int? ReadIntObject(Stream stream) => ReadObject(stream, 'I', ReadInt);