Skip to content

Commit 89af35b

Browse files
committed
No TupleDescriptor.FieldTypes array usage from outside the type
1 parent b8175f0 commit 89af35b

4 files changed

Lines changed: 69 additions & 54 deletions

File tree

Orm/Xtensive.Orm/Orm/EntitySetBase.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -956,33 +956,23 @@ private static EntitySetTypeState BuildEntitySetTypeState(FieldInfo field, Entit
956956
var targetDescriptor = association.TargetType.Key.TupleDescriptor;
957957
var ownerFieldCount = ownerDescriptor.Count;
958958

959-
Type[] keyFieldTypes;
960959
IReadOnlyList<int> itemColumnOffsets;
961960
if (association.AuxiliaryType == null) {
962-
itemColumnOffsets = Enumerable.Repeat(-1, ownerFieldCount).Concat(
963-
association.UnderlyingIndex.ValueColumns
961+
itemColumnOffsets = Enumerable.Repeat(-1, ownerFieldCount)
962+
.Concat(association.UnderlyingIndex.ValueColumns
964963
.Where(ci => ci.IsPrimaryKey)
965964
.Select(ci => ci.Field.MappingInfo.Offset)).ToList();
966-
var keyFieldCount = itemColumnOffsets.Count;
967-
keyFieldTypes = new Type[keyFieldCount];
968-
Array.Copy(ownerDescriptor.FieldTypes, keyFieldTypes, ownerFieldCount);
969-
for (var index=ownerFieldCount; index<keyFieldCount; index++) {
970-
keyFieldTypes[index] = targetDescriptor[itemColumnOffsets[index]];
971-
}
972965
}
973966
else {
974967
var keyFieldCount = ownerDescriptor.Count + targetDescriptor.Count;
975-
keyFieldTypes = new Type[keyFieldCount];
976-
Array.Copy(ownerDescriptor.FieldTypes, keyFieldTypes, ownerFieldCount);
977-
Array.Copy(targetDescriptor.FieldTypes, 0, keyFieldTypes, ownerFieldCount, targetDescriptor.Count);
978968
var offsetMap = new int[keyFieldCount];
979-
for (var index=0; index < keyFieldCount; index++) {
969+
for (var index = 0; index < keyFieldCount; index++) {
980970
offsetMap[index] = index - ownerFieldCount;
981971
}
982972
itemColumnOffsets = offsetMap;
983-
}
984973

985-
var keyDescriptor = TupleDescriptor.Create(keyFieldTypes);
974+
}
975+
var keyDescriptor = ownerDescriptor.ConcatWith(targetDescriptor);
986976

987977
Func<Tuple, Entity> itemCtor = null;
988978
if (association.AuxiliaryType != null) {

Orm/Xtensive.Orm/Tuples/Transform/ConcatTransform.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,8 @@ public ConcatTransform(bool isReadOnly, TupleDescriptor first, TupleDescriptor s
7474
ArgumentValidator.EnsureArgumentIsNotDefault(first, nameof(first));
7575
ArgumentValidator.EnsureArgumentIsNotDefault(second, nameof(second));
7676

77-
var (firstCount, secondCount) = (first.Count, second.Count);
78-
var types = new Type[firstCount + secondCount];
79-
Array.Copy(first.FieldTypes, types, firstCount);
80-
Array.Copy(second.FieldTypes, 0, types, firstCount, secondCount);
81-
8277
IsReadOnly = isReadOnly;
83-
Descriptor = TupleDescriptor.Create(types);
78+
Descriptor = first.ConcatWith(second);
8479
this.sources = (first, second);
8580
}
8681
}

Orm/Xtensive.Orm/Tuples/Transform/SegmentTransform.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,7 @@ public SegmentTransform(bool isReadOnly, TupleDescriptor sourceDescriptor, in Se
7979

8080
IsReadOnly = isReadOnly;
8181

82-
var fields = new Type[segment.Length];
83-
Array.Copy(sourceDescriptor.FieldTypes, segment.Offset, fields, 0, segment.Length);
84-
Descriptor = TupleDescriptor.Create(fields);
82+
Descriptor = sourceDescriptor.Segment(segment);
8583
this.segment = segment;
8684
}
8785
}

Orm/Xtensive.Orm/Tuples/TupleDescriptor.cs

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ namespace Xtensive.Tuples
3434
internal readonly PackedFieldDescriptor[] FieldDescriptors;
3535

3636
[field: NonSerialized]
37-
internal Type[] FieldTypes { get; }
37+
private Type[] FieldTypes { get; }
3838

39-
#region IList members
39+
#region IReadOnlyList members
4040

4141
/// <inheritdoc/>
4242
public Type this[int fieldIndex]
@@ -69,6 +69,66 @@ IEnumerator IEnumerable.GetEnumerator()
6969

7070
#endregion
7171

72+
/// <summary>
73+
/// Creates tuple descriptor containing head of the current one.
74+
/// </summary>
75+
/// <param name="fieldCount">Head field count.</param>
76+
/// <returns>
77+
/// New tuple descriptor describing the specified set of fields.
78+
/// </returns>
79+
public TupleDescriptor Head(int fieldCount)
80+
{
81+
ArgumentValidator.EnsureArgumentIsInRange(fieldCount, 1, Count, nameof(fieldCount));
82+
var fieldTypes = new Type[fieldCount];
83+
Array.Copy(FieldTypes, 0, fieldTypes, 0, fieldCount);
84+
return new TupleDescriptor(fieldTypes);
85+
}
86+
87+
/// <summary>
88+
/// Creates tuple descriptor containing tail of the current one.
89+
/// </summary>
90+
/// <param name="tailFieldCount">Tail field count.</param>
91+
/// <returns>
92+
/// New tuple descriptor describing the specified set of fields.
93+
/// </returns>
94+
public TupleDescriptor Tail(int tailFieldCount)
95+
{
96+
ArgumentValidator.EnsureArgumentIsInRange(tailFieldCount, 1, Count, nameof(tailFieldCount));
97+
var fieldTypes = new Type[tailFieldCount];
98+
Array.Copy(FieldTypes, Count - tailFieldCount, fieldTypes, 0, tailFieldCount);
99+
return new TupleDescriptor(fieldTypes);
100+
}
101+
102+
/// <summary>
103+
/// Creates tuple descriptor containing segment of the current one
104+
/// </summary>
105+
/// <param name="segment">Offset and length of segment in form of Segment</param>
106+
/// <returns>
107+
/// New tuple descriptor describing the specified set of fields.
108+
/// </returns>
109+
public TupleDescriptor Segment(in Segment<int> segment)
110+
{
111+
var fields = new Type[segment.Length];
112+
Array.Copy(FieldTypes, segment.Offset, fields, 0, segment.Length);
113+
114+
return new TupleDescriptor(fields);
115+
}
116+
117+
/// <summary>
118+
/// Concats fields of the current and the given descriptors to form new one.
119+
/// </summary>
120+
/// <param name="second">Tail fields descriptor.</param>
121+
/// <returns>New tuple descriptor containing fields of the both given source descriptors.</returns>
122+
public TupleDescriptor ConcatWith(in TupleDescriptor second)
123+
{
124+
var (firstCount, secondCount) = (Count, second.Count);
125+
var types = new Type[firstCount + secondCount];
126+
Array.Copy(FieldTypes, types, firstCount);
127+
Array.Copy(second.FieldTypes, 0, types, firstCount, secondCount);
128+
129+
return new TupleDescriptor(types);
130+
}
131+
72132
#region IEquatable members, GetHashCode
73133

74134
/// <inheritdoc/>
@@ -177,34 +237,6 @@ public static TupleDescriptor Create(Type[] fieldTypes)
177237
return new TupleDescriptor(fieldTypes);
178238
}
179239

180-
/// <summary>
181-
/// Creates tuple descriptor containing head of the current one.
182-
/// </summary>
183-
/// <param name="fieldCount">Head field count.</param>
184-
/// <returns>Either new or existing tuple descriptor
185-
/// describing the specified set of fields.</returns>
186-
public TupleDescriptor Head(int fieldCount)
187-
{
188-
ArgumentValidator.EnsureArgumentIsInRange(fieldCount, 1, Count, nameof(fieldCount));
189-
var fieldTypes = new Type[fieldCount];
190-
Array.Copy(FieldTypes, 0, fieldTypes, 0, fieldCount);
191-
return new TupleDescriptor(fieldTypes);
192-
}
193-
194-
/// <summary>
195-
/// Creates tuple descriptor containing tail of the current one.
196-
/// </summary>
197-
/// <param name="tailFieldCount">Tail field count.</param>
198-
/// <returns>Either new or existing tuple descriptor
199-
/// describing the specified set of fields.</returns>
200-
public TupleDescriptor Tail(int tailFieldCount)
201-
{
202-
ArgumentValidator.EnsureArgumentIsInRange(tailFieldCount, 1, Count, nameof(tailFieldCount));
203-
var fieldTypes = new Type[tailFieldCount];
204-
Array.Copy(FieldTypes, Count - tailFieldCount, fieldTypes, 0, tailFieldCount);
205-
return new TupleDescriptor(fieldTypes);
206-
}
207-
208240
#endregion
209241

210242
#region Create<...> methods (generic shortcuts)

0 commit comments

Comments
 (0)