Skip to content

Commit 0b5700f

Browse files
committed
Draft for intern
1 parent 03becf5 commit 0b5700f

17 files changed

+288
-68
lines changed

src/NHibernate/Cfg/Environment.cs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,15 @@ public static string Version
270270
/// </summary>
271271
public const string TrackSessionId = "track_session_id";
272272

273+
public const string StringMetadataInternLevel = "intern_level";
274+
273275
private static readonly Dictionary<string, string> GlobalProperties;
274276

275277
private static IBytecodeProvider BytecodeProviderInstance;
276278
private static bool EnableReflectionOptimizer;
277-
279+
278280
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(Environment));
281+
private static InternLevel _internLevel;
279282

280283
/// <summary>
281284
/// Issue warnings to user when any obsolete property names are used.
@@ -299,13 +302,37 @@ static Environment()
299302

300303
BytecodeProviderInstance = BuildBytecodeProvider(GlobalProperties);
301304
EnableReflectionOptimizer = PropertiesHelper.GetBoolean(PropertyUseReflectionOptimizer, GlobalProperties);
305+
306+
//TODO: Proper configuration
307+
SetInternLevelFromConfig();
302308

303309
if (EnableReflectionOptimizer)
304310
{
305311
log.Info("Using reflection optimizer");
306312
}
307313
}
308314

315+
//TODO:
316+
private static InternLevel SetInternLevelFromConfig()
317+
{
318+
return InternLevel.Default;
319+
//string value = System.Configuration.ConfigurationManager.AppSettings["InternLevel"];
320+
//Console.WriteLine("Path to config file: " + ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath);
321+
322+
//if (string.IsNullOrEmpty(value))
323+
//{
324+
// return InternLevel.Default;
325+
//}
326+
327+
//if (!Enum.TryParse<InternLevel>(value, true, out var valueParsed))
328+
//{
329+
// Console.WriteLine("Intern level setting is invalid: " + value);
330+
//}
331+
//Console.WriteLine("Intern level " + valueParsed);
332+
//Console.WriteLine();
333+
//return valueParsed;
334+
}
335+
309336
private static void LoadGlobalPropertiesFromAppConfig()
310337
{
311338
object config = ConfigurationManager.GetSection(CfgXmlHelper.CfgSectionName);
@@ -388,6 +415,32 @@ public static IBytecodeProvider BytecodeProvider
388415
set { BytecodeProviderInstance = value; }
389416
}
390417

418+
/// <summary>
419+
/// The bytecode provider to use.
420+
/// </summary>
421+
/// <remarks>
422+
/// This property is read from the <c>&lt;nhibernate&gt;</c> section
423+
/// of the application configuration file by default. Since it is not
424+
/// always convenient to configure NHibernate through the application
425+
/// configuration file, it is also possible to set the property value
426+
/// manually. This should only be done before a configuration object
427+
/// is created, otherwise the change may not take effect.
428+
/// </remarks>
429+
public static InternLevel InternLevel
430+
{
431+
get { return _internLevel; }
432+
set
433+
{
434+
435+
if (value != _internLevel)
436+
{
437+
Console.WriteLine("Intern level " + value);
438+
}
439+
_internLevel = value;
440+
441+
}
442+
}
443+
391444
/// <summary>
392445
/// Whether to enable the use of reflection optimizer
393446
/// </summary>

src/NHibernate/Dialect/Lock/SelectLockingStrategy.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private SqlString GenerateLockString()
4747
{
4848
select.SetComment(lockMode + " lock " + lockable.EntityName);
4949
}
50-
return select.ToSqlString();
50+
return select.ToSqlString(true);
5151
}
5252

5353
#region ILockingStrategy Members
@@ -110,4 +110,4 @@ public void Lock(object id, object version, object obj, ISessionImplementor sess
110110

111111
#endregion
112112
}
113-
}
113+
}

src/NHibernate/Loader/BasicLoader.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public abstract class BasicLoader : Loader
1313
private IEntityAliases[] descriptors;
1414
private ICollectionAliases[] collectionDescriptors;
1515

16-
public BasicLoader(ISessionFactoryImplementor factory) : base(factory) {}
16+
public BasicLoader(ISessionFactoryImplementor factory) : base(factory) { }
1717

1818
protected override sealed IEntityAliases[] EntityAliases
1919
{
@@ -28,14 +28,16 @@ protected override sealed ICollectionAliases[] CollectionAliases
2828
protected abstract string[] Suffixes { get; }
2929
protected abstract string[] CollectionSuffixes { get; }
3030

31+
protected virtual bool InternStringMetadata => false;
32+
3133
protected override void PostInstantiate()
3234
{
3335
ILoadable[] persisters = EntityPersisters;
3436
string[] suffixes = Suffixes;
3537
descriptors = new IEntityAliases[persisters.Length];
3638
for (int i = 0; i < descriptors.Length; i++)
3739
{
38-
descriptors[i] = new DefaultEntityAliases(persisters[i], suffixes[i]);
40+
descriptors[i] = new DefaultEntityAliases(persisters[i], suffixes[i], InternStringMetadata);
3941
}
4042

4143
ICollectionPersister[] collectionPersisters = CollectionPersisters;
@@ -69,7 +71,7 @@ protected override void PostInstantiate()
6971
private static bool IsBag(ICollectionPersister collectionPersister)
7072
{
7173
var type = collectionPersister.CollectionType.GetType();
72-
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof (GenericBagType<>);
74+
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(GenericBagType<>);
7375
}
7476

7577
/// <summary>

src/NHibernate/Loader/DefaultEntityAliases.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using NHibernate.Persister.Entity;
3+
using NHibernate.Util;
34

45
namespace NHibernate.Loader
56
{
@@ -34,6 +35,34 @@ public DefaultEntityAliases(IDictionary<string, string[]> userProvidedAliases, I
3435
//rowIdAlias is generated on demand in property
3536
}
3637

38+
/// <summary>
39+
/// Calculate and cache select-clause aliases.
40+
/// </summary>
41+
public DefaultEntityAliases(ILoadable persister, string suffix, bool internAliases) : this(persister, suffix)
42+
{
43+
if (internAliases == false)
44+
return;
45+
46+
const InternLevel internLevel = InternLevel.EntityAlias;
47+
48+
SuffixedKeyAliases = StringHelper.Intern(SuffixedKeyAliases, internLevel);
49+
SuffixedPropertyAliases = InternPropertiesAliases(SuffixedPropertyAliases, internLevel);
50+
SuffixedVersionAliases = StringHelper.Intern(SuffixedVersionAliases, internLevel);
51+
SuffixedDiscriminatorAlias = StringHelper.Intern(SuffixedDiscriminatorAlias, internLevel);
52+
if (persister.HasRowId)
53+
RowIdAlias = StringHelper.Intern(RowIdAlias, internLevel);
54+
}
55+
56+
private string[][] InternPropertiesAliases(string[][] propertiesAliases, InternLevel internLevel)
57+
{
58+
foreach (string[] values in propertiesAliases)
59+
{
60+
StringHelper.Intern(values, internLevel);
61+
}
62+
63+
return propertiesAliases;
64+
}
65+
3766
/// <summary>
3867
/// Returns aliases for subclass persister
3968
/// </summary>
@@ -63,7 +92,11 @@ public string[][] GetSuffixedPropertyAliases(ILoadable persister)
6392
public string[] SuffixedKeyAliases { get; }
6493

6594
// TODO: not visible to the user!
66-
public string RowIdAlias => _rowIdAlias ?? (_rowIdAlias = Loadable.RowIdAlias + _suffix);
95+
public string RowIdAlias
96+
{
97+
get => _rowIdAlias ?? (_rowIdAlias = Loadable.RowIdAlias + _suffix);
98+
private set => _rowIdAlias = value;
99+
}
67100

68101
/// <summary>
69102
/// Returns default aliases for all the properties
@@ -100,32 +133,32 @@ private string[] DetermineKeyAliases(ILoadable persister)
100133
if (_userProvidedAliases != null)
101134
{
102135
var result = SafeGetUserProvidedAliases(persister.IdentifierPropertyName) ??
103-
GetUserProvidedAliases(EntityPersister.EntityID);
136+
GetUserProvidedAliases(EntityPersister.EntityID);
104137

105138
if (result != null)
106139
return result;
107140
}
108141

109142
return GetIdentifierAliases(persister, _suffix);
110143
}
111-
144+
112145
private string[][] DeterminePropertyAliases(ILoadable persister)
113146
{
114147
return GetSuffixedPropertyAliases(persister);
115148
}
116-
149+
117150
private string DetermineDiscriminatorAlias(ILoadable persister)
118151
{
119152
if (_userProvidedAliases != null)
120153
{
121154
var columns = GetUserProvidedAliases(AbstractEntityPersister.EntityClass);
122-
if (columns != null)
155+
if (columns != null)
123156
return columns[0];
124157
}
125158

126159
return GetDiscriminatorAlias(persister, _suffix);
127160
}
128-
161+
129162
private string[] SafeGetUserProvidedAliases(string propertyPath)
130163
{
131164
if (propertyPath == null)

src/NHibernate/Loader/Entity/CascadeEntityLoader.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ public CascadeEntityLoader(IOuterJoinLoadable persister, CascadingAction action,
1616

1717
log.Debug("Static select for action {0} on entity {1}: {2}", action, entityName, SqlString);
1818
}
19+
20+
protected override bool InternStringMetadata => true;
1921
}
2022
}

src/NHibernate/Loader/Entity/EntityLoader.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,7 @@ protected override bool IsSingleRowLoader
4848
{
4949
get { return !batchLoader; }
5050
}
51+
52+
protected override bool InternStringMetadata => true;
5153
}
5254
}

src/NHibernate/Mapping/Collection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public bool IsLazy
176176
public string Role
177177
{
178178
get { return role; }
179-
set { role = StringHelper.InternedIfPossible(value); }
179+
set { role = StringHelper.Intern(value, InternLevel.CollectionRole); }
180180
}
181181

182182
public IEnumerable<ISelectable> ColumnIterator

src/NHibernate/Mapping/Column.cs

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Text;
23
using NHibernate.Dialect.Function;
34
using NHibernate.Engine;
45
using NHibernate.SqlTypes;
@@ -13,6 +14,8 @@ namespace NHibernate.Mapping
1314
[Serializable]
1415
public class Column : ISelectable, ICloneable
1516
{
17+
private const char QuoteChar = '`';
18+
1619
public const int DefaultLength = 255;
1720
public const int DefaultPrecision = 19;
1821
public const int DefaultScale = 2;
@@ -82,18 +85,21 @@ public string Name
8285
get { return _name; }
8386
set
8487
{
85-
if (value[0] == '`')
86-
{
87-
_quoted = true;
88-
_name = value.Substring(1, value.Length - 2);
89-
}
90-
else
91-
{
92-
_name = value;
93-
}
88+
_name = StringHelper.Intern(GetName(value, out _quoted), InternLevel.ColumnName);
9489
}
9590
}
9691

92+
private string GetName(string value, out bool quoted)
93+
{
94+
quoted = false;
95+
if (value[0] == QuoteChar)
96+
{
97+
quoted = true;
98+
return value.Substring(1, value.Length - 2);
99+
}
100+
return value;
101+
}
102+
97103
public string CanonicalName
98104
{
99105
get { return _quoted ? _name : _name.ToLowerInvariant(); }
@@ -154,8 +160,9 @@ private string GetAlias(int maxAliasLength)
154160
// those checks, then the double checks for total length can be reduced to one.
155161
// But I will leave it like this for now to make it look similar. /Oskar 2016-08-20
156162
bool useRawName = name.Length + suffix.Length <= usableLength &&
157-
!_quoted &&
158-
!StringHelper.EqualsCaseInsensitive(name, "rowid");
163+
!_quoted &&
164+
!string.Equals(name, "rowid", StringComparison.OrdinalIgnoreCase);
165+
159166
if (!useRawName)
160167
{
161168
if (suffix.Length >= usableLength)
@@ -428,15 +435,15 @@ public SqlType GetSqlTypeCode(IMapping mapping)
428435
}
429436
catch (Exception e)
430437
{
431-
throw new MappingException(string.Format("Could not determine type for column {0} of type {1}: {2}",
438+
throw new MappingException(string.Format("Could not determine type for column {0} of type {1}: {2}",
432439
_name, type.GetType().FullName, e.GetType().FullName), e);
433440
}
434441
}
435442

436443
/// <summary>returns quoted name as it would be in the mapping file. </summary>
437444
public string GetQuotedName()
438445
{
439-
return _quoted ? '`' + _name + '`' : _name;
446+
return _quoted ? QuoteChar + _name + QuoteChar : _name;
440447
}
441448

442449
public bool IsCaracteristicsDefined()
@@ -463,24 +470,24 @@ public bool IsLengthDefined()
463470
/// <summary> Shallow copy, the value is not copied</summary>
464471
public object Clone()
465472
{
466-
Column copy = new Column();
467-
if (_length.HasValue)
468-
copy.Length = Length;
469-
if (_precision.HasValue)
470-
copy.Precision = Precision;
471-
if (_scale.HasValue)
472-
copy.Scale = Scale;
473-
copy.Value = _value;
474-
copy.TypeIndex = _typeIndex;
475-
copy.Name = GetQuotedName();
476-
copy.IsNullable = _nullable;
477-
copy.Unique = _unique;
478-
copy.SqlType = _sqlType;
479-
copy.SqlTypeCode = _sqlTypeCode;
480-
copy.UniqueInteger = UniqueInteger; //usually useless
481-
copy.CheckConstraint = _checkConstraint;
482-
copy.Comment = _comment;
483-
copy.DefaultValue = _defaultValue;
473+
Column copy = new Column()
474+
{
475+
_length = _length,
476+
_name = _name,
477+
_quoted = _quoted,
478+
_checkConstraint = _checkConstraint,
479+
_comment = _comment,
480+
_defaultValue = _defaultValue,
481+
_nullable = _nullable,
482+
_unique = _unique,
483+
_precision = _precision,
484+
_scale = _scale,
485+
_sqlType = _sqlType,
486+
_sqlTypeCode = _sqlTypeCode,
487+
_typeIndex = _typeIndex,
488+
_value = _value,
489+
UniqueInteger = UniqueInteger,
490+
};
484491
return copy;
485492
}
486493

0 commit comments

Comments
 (0)