Skip to content

Commit d3b6ea9

Browse files
committed
After-merge changes
- Fix index building by using ChainedBufffer to cache IndexInfoCollection.Find() resilts - IndexBuilder: Less enumerations - TypeInfo.GetVersionFields() and .GetVersionColumns() cache results as ReadOnlyCollection - Code imrovements + updated formatting
1 parent 02e34a6 commit d3b6ea9

File tree

6 files changed

+168
-105
lines changed

6 files changed

+168
-105
lines changed

Orm/Xtensive.Orm/Orm/Building/Builders/IndexBuilder.ClassTable.cs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313

1414
namespace Xtensive.Orm.Building.Builders
1515
{
16-
partial class IndexBuilder
16+
internal partial class IndexBuilder
1717
{
1818
private void BuildClassTableIndexes(TypeInfo type)
1919
{
20-
if (type.Indexes.Count > 0)
21-
return;
22-
if (type.IsStructure)
20+
if (type.Indexes.Count > 0 || type.IsStructure) {
2321
return;
22+
}
2423

2524
var root = type.Hierarchy.Root;
2625
var typeDef = context.ModelDef.Types[type.UnderlyingType];
@@ -33,8 +32,10 @@ private void BuildClassTableIndexes(TypeInfo type)
3332
var hasInheritedFields = indexDescriptor.KeyFields
3433
.Select(kvp => type.Fields[kvp.Key])
3534
.Any(f => f.IsInherited);
36-
if (hasInheritedFields)
35+
if (hasInheritedFields) {
3736
continue;
37+
}
38+
3839
var declaredIndex = BuildIndex(type, indexDescriptor, false);
3940

4041
type.Indexes.Add(declaredIndex);
@@ -53,16 +54,21 @@ private void BuildClassTableIndexes(TypeInfo type)
5354

5455
// Building inherited from interfaces indexes
5556
foreach (var @interface in interfaces) {
56-
foreach (var interfaceIndex in @interface.Indexes.Find(IndexAttributes.Primary, MatchType.None)) {
57+
foreach (var interfaceIndex in @interface.Indexes.Find(IndexAttributes.Primary, MatchType.None).ToChainedBuffer()) {
5758
if (interfaceIndex.DeclaringIndex != interfaceIndex &&
5859
parent != null &&
59-
parent.Indexes.Any(i => i.DeclaringIndex == interfaceIndex))
60+
parent.Indexes.Any(i => i.DeclaringIndex == interfaceIndex)) {
6061
continue;
61-
if (type.Indexes.Any(i => i.DeclaringIndex == interfaceIndex))
62+
}
63+
64+
if (type.Indexes.Any(i => i.DeclaringIndex == interfaceIndex)) {
6265
continue;
66+
}
67+
6368
var index = BuildInheritedIndex(type, interfaceIndex, false);
64-
if (IndexBuiltOverInheritedFields(index))
69+
if (IndexBuiltOverInheritedFields(index)) {
6570
BuildLog.Warning(string.Format(Strings.ExUnableToBuildIndexXBecauseItWasBuiltOverInheritedFields, index.Name));
71+
}
6672
else {
6773
type.Indexes.Add(index);
6874
context.Model.RealIndexes.Add(index);
@@ -71,37 +77,44 @@ private void BuildClassTableIndexes(TypeInfo type)
7177
}
7278

7379
// Build typed indexes
74-
if (type == root)
75-
foreach (var realIndex in type.Indexes.Find(IndexAttributes.Real)) {
76-
if (!untypedIndexes.Contains(realIndex))
80+
if (type == root) {
81+
foreach (var realIndex in type.Indexes.Find(IndexAttributes.Real).ToChainedBuffer()) {
82+
if (!untypedIndexes.Contains(realIndex)) {
7783
continue;
84+
}
7885
var typedIndex = BuildTypedIndex(type, realIndex);
7986
type.Indexes.Add(typedIndex);
8087
}
88+
}
8189

8290
// Build indexes for descendants
83-
foreach (var descendant in type.DirectDescendants)
91+
foreach (var descendant in type.DirectDescendants) {
8492
BuildClassTableIndexes(descendant);
93+
}
8594

8695
// Import inherited indexes
8796
var primaryIndex = type.Indexes.FindFirst(IndexAttributes.Primary | IndexAttributes.Real);
88-
if (untypedIndexes.Contains(primaryIndex) && primaryIndex.ReflectedType == root)
97+
if (untypedIndexes.Contains(primaryIndex) && primaryIndex.ReflectedType == root) {
8998
primaryIndex = type.Indexes.Single(i => i.DeclaringIndex == primaryIndex.DeclaringIndex && i.IsTyped);
99+
}
90100
var filterByTypes = type.AllDescendants.Append(type).ToList(type.AllDescendants.Count + 1);
91101

92102
// Build virtual primary index
93103
if (ancestors.Count > 0) {
94104
var baseIndexes = new Stack<IndexInfo>();
95105
foreach (var ancestor in ancestors.Where(t => t.Fields.Any(f => !f.IsPrimaryKey && !f.IsTypeId && f.IsDeclared))) {
96106
var ancestorIndex = ancestor.Indexes.Single(i => i.IsPrimary && !i.IsVirtual);
97-
if (untypedIndexes.Contains(ancestorIndex) && ancestorIndex.ReflectedType == root)
107+
if (untypedIndexes.Contains(ancestorIndex) && ancestorIndex.ReflectedType == root) {
98108
ancestorIndex = ancestor.Indexes.Single(i => i.DeclaringIndex == ancestorIndex.DeclaringIndex && i.IsTyped);
99-
if (ancestorIndex.ValueColumns.Count > 0)
109+
}
110+
if (ancestorIndex.ValueColumns.Count > 0) {
100111
baseIndexes.Push(ancestorIndex);
112+
}
101113
}
102114
if (baseIndexes.Count > 0) {
103-
if (primaryIndex.ValueColumns.Count > 0 && type.Fields.Any(f => !f.IsPrimaryKey && !f.IsTypeId && f.IsDeclared))
115+
if (primaryIndex.ValueColumns.Count > 0 && type.Fields.Any(f => !f.IsPrimaryKey && !f.IsTypeId && f.IsDeclared)) {
104116
baseIndexes.Push(primaryIndex);
117+
}
105118
else {
106119
var ancestorIndex = baseIndexes.Pop();
107120
var filteredIndex = BuildFilterIndex(type, ancestorIndex, filterByTypes);
@@ -115,9 +128,15 @@ private void BuildClassTableIndexes(TypeInfo type)
115128
}
116129

117130
// Build virtual secondary index
118-
foreach (var ancestorIndex in ancestors.SelectMany(ancestor => ancestor.Indexes.Find(IndexAttributes.Primary | IndexAttributes.Virtual, MatchType.None))) {
119-
if (ancestorIndex.DeclaringIndex != ancestorIndex)
131+
var primaryOrVirtualIndexes = ancestors
132+
.SelectMany(
133+
ancestor => ancestor.Indexes.Find(IndexAttributes.Primary | IndexAttributes.Virtual, MatchType.None).ToChainedBuffer());
134+
135+
foreach (var ancestorIndex in primaryOrVirtualIndexes) {
136+
if (ancestorIndex.DeclaringIndex != ancestorIndex) {
120137
continue;
138+
}
139+
121140
var ancestorType = ancestorIndex.ReflectedType;
122141
var indexToFilter = untypedIndexes.Contains(ancestorIndex) && ancestorIndex.ReflectedType == root
123142
? ancestorType.Indexes.Single(i => i.DeclaringIndex == ancestorIndex.DeclaringIndex && i.IsTyped)
@@ -127,7 +146,7 @@ private void BuildClassTableIndexes(TypeInfo type)
127146
}
128147
}
129148

130-
static bool IndexBuiltOverInheritedFields(IndexInfo index)
149+
private static bool IndexBuiltOverInheritedFields(IndexInfo index)
131150
{
132151
if (index.IsVirtual)
133152
return false;

Orm/Xtensive.Orm/Orm/Building/Builders/IndexBuilder.ConcreteTable.cs

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111

1212
namespace Xtensive.Orm.Building.Builders
1313
{
14-
partial class IndexBuilder
14+
internal partial class IndexBuilder
1515
{
1616
private void BuildConcreteTableIndexes(TypeInfo type)
1717
{
18-
if (type.Indexes.Count > 0)
19-
return;
20-
if (type.IsStructure)
18+
if (type.Indexes.Count > 0 || type.IsStructure) {
2119
return;
20+
}
2221

2322
var typeDef = context.ModelDef.Types[type.UnderlyingType];
2423
var root = type.Hierarchy.Root;
@@ -31,13 +30,15 @@ private void BuildConcreteTableIndexes(TypeInfo type)
3130
// and if they have some indexes then IndexDef.IsInherited of them will be true and it's truth actually,
3231
// but fields inherited from removed entities will have FieldInfo.IsInherited = false.
3332
// So, if we check only IndexDef.IsInherited then some indexes will be ignored.
34-
if (indexDescriptor.IsInherited && indexDescriptor.KeyFields.Select(kf=> type.Fields[kf.Key]).Any(f=>f.IsInherited))
33+
if (indexDescriptor.IsInherited && indexDescriptor.KeyFields.Select(kf=> type.Fields[kf.Key]).Any(f=>f.IsInherited)) {
3534
continue;
36-
var declaredIndex = BuildIndex(type, indexDescriptor, type.IsAbstract);
35+
}
3736

37+
var declaredIndex = BuildIndex(type, indexDescriptor, type.IsAbstract);
3838
type.Indexes.Add(declaredIndex);
39-
if (!declaredIndex.IsAbstract)
39+
if (!declaredIndex.IsAbstract) {
4040
context.Model.RealIndexes.Add(declaredIndex);
41+
}
4142
}
4243

4344
// Building primary index for non root entities
@@ -48,42 +49,50 @@ private void BuildConcreteTableIndexes(TypeInfo type)
4849

4950
// Registering built primary index
5051
type.Indexes.Add(inheritedIndex);
51-
if (!inheritedIndex.IsAbstract)
52+
if (!inheritedIndex.IsAbstract) {
5253
context.Model.RealIndexes.Add(inheritedIndex);
54+
}
5355
}
5456

5557
// Building inherited from interfaces indexes
5658
foreach (var @interface in type.AllInterfaces) {
57-
foreach (var parentIndex in @interface.Indexes.Find(IndexAttributes.Primary, MatchType.None)) {
58-
if (parentIndex.DeclaringIndex != parentIndex)
59+
foreach (var parentIndex in @interface.Indexes.Find(IndexAttributes.Primary, MatchType.None).ToChainedBuffer()) {
60+
if (parentIndex.DeclaringIndex != parentIndex) {
5961
continue;
62+
}
63+
6064
var index = BuildInheritedIndex(type, parentIndex, type.IsAbstract);
61-
if ((parent != null && parent.Indexes.Contains(index.Name)) || type.Indexes.Contains(index.Name))
65+
if ((parent != null && parent.Indexes.Contains(index.Name)) || type.Indexes.Contains(index.Name)) {
6266
continue;
67+
}
68+
6369
type.Indexes.Add(index);
64-
if (!index.IsAbstract)
70+
if (!index.IsAbstract) {
6571
context.Model.RealIndexes.Add(index);
72+
}
6673
}
6774
}
6875

6976
// Build typed indexes
70-
foreach (var realIndex in type.Indexes.Find(IndexAttributes.Real)) {
71-
if (!untypedIndexes.Contains(realIndex))
77+
foreach (var realIndex in type.Indexes.Find(IndexAttributes.Real).ToChainedBuffer()) {
78+
if (!untypedIndexes.Contains(realIndex)) {
7279
continue;
80+
}
7381
var typedIndex = BuildTypedIndex(type, realIndex);
7482
type.Indexes.Add(typedIndex);
7583
}
7684

7785
// Build indexes for descendants
78-
foreach (var descendant in type.DirectDescendants)
86+
foreach (var descendant in type.DirectDescendants) {
7987
BuildConcreteTableIndexes(descendant);
88+
}
8089

8190
var ancestors = type.Ancestors;
8291
var descendants = type.AllDescendants;
8392

8493
// Build primary virtual union index
8594
if (descendants.Count > 0) {
86-
var indexesToUnion = new List<IndexInfo>(){type.Indexes.PrimaryIndex};
95+
var indexesToUnion = new List<IndexInfo>() { type.Indexes.PrimaryIndex };
8796
foreach (var index in descendants.Select(t => t.Indexes.PrimaryIndex)) {
8897
var indexView = BuildViewIndex(type, index);
8998
indexesToUnion.Add(indexView);
@@ -94,34 +103,45 @@ private void BuildConcreteTableIndexes(TypeInfo type)
94103
}
95104

96105
// Build inherited secondary indexes
97-
foreach (var ancestorIndex in ancestors.SelectMany(ancestor => ancestor.Indexes.Find(IndexAttributes.Primary | IndexAttributes.Virtual, MatchType.None))) {
98-
if (ancestorIndex.DeclaringIndex != ancestorIndex)
106+
var primaryOrVirtualIndexes = ancestors
107+
.SelectMany(
108+
ancestor => ancestor.Indexes.Find(IndexAttributes.Primary | IndexAttributes.Virtual, MatchType.None).ToChainedBuffer());
109+
110+
foreach (var ancestorIndex in primaryOrVirtualIndexes) {
111+
if (ancestorIndex.DeclaringIndex != ancestorIndex) {
99112
continue;
113+
}
114+
100115
var secondaryIndex = BuildInheritedIndex(type, ancestorIndex, type.IsAbstract);
101116
type.Indexes.Add(secondaryIndex);
102-
if (!secondaryIndex.IsAbstract)
117+
if (!secondaryIndex.IsAbstract) {
103118
context.Model.RealIndexes.Add(secondaryIndex);
119+
}
104120
// Build typed index for secondary one
105-
if (!untypedIndexes.Contains(secondaryIndex))
121+
if (!untypedIndexes.Contains(secondaryIndex)) {
106122
continue;
123+
}
124+
107125
var typedIndex = BuildTypedIndex(type, secondaryIndex);
108126
type.Indexes.Add(typedIndex);
109127
}
110128

111129
// Build virtual secondary indexes
112-
if (descendants.Count > 0)
130+
if (descendants.Count > 0) {
113131
foreach (var index in type.Indexes.Where(i => !i.IsPrimary && !i.IsVirtual).ToList()) {
114132
var isUntyped = untypedIndexes.Contains(index);
115133
var indexToUnion = isUntyped
116134
? type.Indexes.Single(i => i.DeclaringIndex == index.DeclaringIndex && i.IsTyped)
117135
: index;
118136

119-
var indexesToUnion = new List<IndexInfo>() {indexToUnion};
120-
indexesToUnion.AddRange(descendants
121-
.Select(t => t.Indexes.Single(i => i.DeclaringIndex == index.DeclaringIndex && (isUntyped ? i.IsTyped : !i.IsVirtual))));
137+
var indexesToUnion = descendants
138+
.Select(t => t.Indexes.Single(i => i.DeclaringIndex == index.DeclaringIndex && (isUntyped ? i.IsTyped : !i.IsVirtual)))
139+
.Prepend(indexToUnion);
140+
122141
var virtualSecondaryIndex = BuildUnionIndex(type, indexesToUnion);
123142
type.Indexes.Add(virtualSecondaryIndex);
124143
}
144+
}
125145
}
126146
}
127147
}

0 commit comments

Comments
 (0)