Skip to content

Commit 8cfbc20

Browse files
committed
Directly write to PackedFieldDescriptor fields to save on setter calls
1 parent bb7a67c commit 8cfbc20

2 files changed

Lines changed: 69 additions & 83 deletions

File tree

Orm/Xtensive.Orm/Tuples/Packed/PackedFieldDescriptor.cs

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// Created: 2012.12.29
66

77
using System;
8-
using System.Runtime.CompilerServices;
98

109
namespace Xtensive.Tuples.Packed
1110
{
@@ -15,32 +14,20 @@ internal struct PackedFieldDescriptor
1514
private const int OffsetBitCount = 6;
1615
private const int OffsetMask = (1 << OffsetBitCount) - 1;
1716

18-
private int indexField;
19-
private int stateField;
17+
internal int DataPosition;
18+
internal int StatePosition;
2019

2120
[NonSerialized]
2221
public PackedFieldAccessor Accessor;
2322

2423
public bool IsObjectField => Accessor.Rank < 0;
2524

26-
public int ObjectIndex
27-
{
28-
get => indexField;
29-
set => indexField = value;
30-
}
25+
public int ObjectIndex => DataPosition;
3126

32-
public int ValueIndex => indexField >> OffsetBitCount;
33-
public int ValueBitOffset => indexField & OffsetMask;
27+
public int ValueIndex => DataPosition >> OffsetBitCount;
28+
public int ValueBitOffset => DataPosition & OffsetMask;
3429

35-
public int StateIndex => stateField >> OffsetBitCount;
36-
public int StateBitOffset => stateField & OffsetMask;
37-
38-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
39-
public void SetValueBitOffset(int totalBitOffset)
40-
=> indexField = totalBitOffset;
41-
42-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
43-
public void SetStateTotalBitOffset(int stateBitOffset)
44-
=> stateField = stateBitOffset;
30+
public int StateIndex => StatePosition >> OffsetBitCount;
31+
public int StateBitOffset => StatePosition & OffsetMask;
4532
}
4633
}

Orm/Xtensive.Orm/Tuples/Packed/TupleLayout.cs

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal static class TupleLayout
1919

2020
private const int Val064BitCount = 1 << Val064Rank;
2121

22-
private ref struct ValCounters
22+
private ref struct Counters
2323
{
2424
public int ObjectCounter;
2525

@@ -118,15 +118,15 @@ ValueFieldAccessor ResolveByNullableType(Type type) =>
118118
ReferenceEquals(type, NullableDecimalType) ? DecimalAccessor :
119119
ReferenceEquals(type, NullableGuidType) ? GuidAccessor : null;
120120

121-
return (probeType.MetadataToken ^ NullableTypeMetadataToken)==0
121+
return (probeType.MetadataToken ^ NullableTypeMetadataToken) == 0
122122
? ResolveByNullableType(probeType)
123123
: ResolveByType(probeType);
124124
}
125125
}
126126

127-
private delegate void CounterIncrementer(ref ValCounters valCounters);
127+
private delegate void CounterIncrementer(ref Counters counters);
128128

129-
private delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters);
129+
private delegate void PositionUpdater(ref PackedFieldDescriptor descriptor, ref Counters counters);
130130

131131
private static readonly ObjectFieldAccessor ObjectAccessor = new ObjectFieldAccessor();
132132
private static readonly CounterIncrementer[] IncrementerByRank;
@@ -143,9 +143,9 @@ public static void ConfigureLen1(Type[] fieldTypes, ref PackedFieldDescriptor de
143143
var valueAccessor = ValueFieldAccessorResolver.GetValue(fieldTypes[0]);
144144
if (valueAccessor != null) {
145145
descriptor.Accessor = valueAccessor;
146-
descriptor.SetValueBitOffset(Val064BitCount);
146+
descriptor.DataPosition = Val064BitCount;
147147

148-
valuesLength = ((1 << valueAccessor.Rank) + ((Val064BitCount * 2) - 1)) >> Val064Rank;
148+
valuesLength = (valueAccessor.ValueBitCount + ((Val064BitCount * 2) - 1)) >> Val064Rank;
149149
objectsLength = 0;
150150
fieldTypes[0] = valueAccessor.FieldType;
151151
return;
@@ -159,22 +159,22 @@ public static void ConfigureLen1(Type[] fieldTypes, ref PackedFieldDescriptor de
159159
public static void ConfigureLen2(Type[] fieldTypes, ref PackedFieldDescriptor descriptor1,
160160
ref PackedFieldDescriptor descriptor2, out int valuesLength, out int objectsLength)
161161
{
162-
var valCounters = new ValCounters();
163-
ConfigureFieldPhase1(ref descriptor1, ref valCounters, fieldTypes, 0);
164-
ConfigureFieldPhase1(ref descriptor2, ref valCounters, fieldTypes, 1);
165-
objectsLength = valCounters.ObjectCounter;
162+
var counters = new Counters();
163+
ConfigureFieldPhase1(ref descriptor1, ref counters, fieldTypes, 0);
164+
ConfigureFieldPhase1(ref descriptor2, ref counters, fieldTypes, 1);
165+
objectsLength = counters.ObjectCounter;
166166
int val1BitCount, val2BitCount;
167167
switch (objectsLength) {
168168
case 2:
169169
valuesLength = 1;
170170
return;
171171
case 1: {
172172
if (descriptor1.IsObjectField) {
173-
descriptor2.SetValueBitOffset(Val064BitCount);
173+
descriptor2.DataPosition = Val064BitCount;
174174
val1BitCount = descriptor2.Accessor.ValueBitCount;
175175
}
176176
else {
177-
descriptor1.SetValueBitOffset(Val064BitCount);
177+
descriptor1.DataPosition = Val064BitCount;
178178
val1BitCount = descriptor1.Accessor.ValueBitCount;
179179
}
180180
valuesLength = (val1BitCount + ((Val064BitCount * 2) - 1)) >> Val064Rank;
@@ -185,12 +185,12 @@ public static void ConfigureLen2(Type[] fieldTypes, ref PackedFieldDescriptor de
185185
val1BitCount = descriptor1.Accessor.ValueBitCount;
186186
val2BitCount = descriptor2.Accessor.ValueBitCount;
187187
if (val2BitCount > val1BitCount) {
188-
descriptor2.SetValueBitOffset(Val064BitCount);
189-
descriptor1.SetValueBitOffset(Val064BitCount + val2BitCount);
188+
descriptor2.DataPosition = Val064BitCount;
189+
descriptor1.DataPosition = Val064BitCount + val2BitCount;
190190
}
191191
else {
192-
descriptor1.SetValueBitOffset(Val064BitCount);
193-
descriptor2.SetValueBitOffset(Val064BitCount + val1BitCount);
192+
descriptor1.DataPosition = Val064BitCount;
193+
descriptor2.DataPosition = Val064BitCount + val1BitCount;
194194
}
195195
valuesLength = (val1BitCount + val2BitCount + ((Val064BitCount * 2) - 1)) >> Val064Rank;
196196
}
@@ -200,59 +200,59 @@ public static void Configure(Type[] fieldTypes, PackedFieldDescriptor[] fieldDes
200200
out int objectsLength)
201201
{
202202
var fieldCount = fieldTypes.Length;
203-
var valCounters = new ValCounters();
203+
var counters = new Counters();
204204
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
205-
ConfigureFieldPhase1(ref fieldDescriptors[fieldIndex], ref valCounters, fieldTypes, fieldIndex);
205+
ConfigureFieldPhase1(ref fieldDescriptors[fieldIndex], ref counters, fieldTypes, fieldIndex);
206206
}
207207

208208
const int statesPerLong = Val064BitCount / 2;
209209

210210
var totalBitCount = ((fieldCount + (statesPerLong - 1)) >> Val032Rank) << Val064Rank;
211-
var prevCount = valCounters.Val128Counter;
212-
valCounters.Val128Counter = totalBitCount;
211+
var prevCount = counters.Val128Counter;
212+
counters.Val128Counter = totalBitCount;
213213

214214
totalBitCount += prevCount << Val128Rank;
215-
prevCount = valCounters.Val064Counter;
216-
valCounters.Val064Counter = totalBitCount;
215+
prevCount = counters.Val064Counter;
216+
counters.Val064Counter = totalBitCount;
217217

218218
totalBitCount += prevCount << Val064Rank;
219-
prevCount = valCounters.Val032Counter;
220-
valCounters.Val032Counter = totalBitCount;
219+
prevCount = counters.Val032Counter;
220+
counters.Val032Counter = totalBitCount;
221221

222222
totalBitCount += prevCount << Val032Rank;
223-
prevCount = valCounters.Val016Counter;
224-
valCounters.Val016Counter = totalBitCount;
223+
prevCount = counters.Val016Counter;
224+
counters.Val016Counter = totalBitCount;
225225

226226
totalBitCount += prevCount << Val016Rank;
227-
prevCount = valCounters.Val008Counter;
228-
valCounters.Val008Counter = totalBitCount;
227+
prevCount = counters.Val008Counter;
228+
counters.Val008Counter = totalBitCount;
229229

230230
totalBitCount += prevCount << Val008Rank;
231-
prevCount = valCounters.Val001Counter;
232-
valCounters.Val001Counter = totalBitCount;
231+
prevCount = counters.Val001Counter;
232+
counters.Val001Counter = totalBitCount;
233233

234234
totalBitCount += prevCount;
235235

236236
for (var fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++) {
237-
ConfigureFieldPhase2(ref fieldDescriptors[fieldIndex], ref valCounters);
237+
ConfigureFieldPhase2(ref fieldDescriptors[fieldIndex], ref counters);
238238
}
239239

240240
valuesLength = (totalBitCount + (Val064BitCount - 1)) >> Val064Rank;
241-
objectsLength = valCounters.ObjectCounter;
241+
objectsLength = counters.ObjectCounter;
242242
}
243243

244244
[MethodImpl(MethodImplOptions.AggressiveInlining)]
245-
private static void UpdateDescriptorPosition(ref PackedFieldDescriptor descriptor, ref int valPointer)
245+
private static void UpdateDescriptorPosition(ref PackedFieldDescriptor descriptor, ref int bitCounter)
246246
{
247-
descriptor.SetValueBitOffset(valPointer);
248-
valPointer += descriptor.Accessor.ValueBitCount;
247+
descriptor.DataPosition = bitCounter;
248+
bitCounter += descriptor.Accessor.ValueBitCount;
249249
}
250250

251251
[MethodImpl(MethodImplOptions.AggressiveInlining)]
252-
private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, ref ValCounters counters,
252+
private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, ref Counters counters,
253253
Type[] fieldTypes, int fieldIndex)
254254
{
255-
descriptor.SetStateTotalBitOffset(fieldIndex << 1);
255+
descriptor.StatePosition = fieldIndex << 1;
256256

257257
var valueAccessor = ValueFieldAccessorResolver.GetValue(fieldTypes[fieldIndex]);
258258
if (valueAccessor != null) {
@@ -265,50 +265,49 @@ private static void ConfigureFieldPhase1(ref PackedFieldDescriptor descriptor, r
265265
}
266266

267267
descriptor.Accessor = ObjectAccessor;
268-
descriptor.ObjectIndex = counters.ObjectCounter++;
268+
descriptor.DataPosition = counters.ObjectCounter++;
269269
}
270270

271271
[MethodImpl(MethodImplOptions.AggressiveInlining)]
272-
private static void ConfigureFieldPhase2(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
272+
private static void ConfigureFieldPhase2(ref PackedFieldDescriptor descriptor, ref Counters counters)
273273
{
274274
if (descriptor.IsObjectField) {
275275
return;
276276
}
277277

278-
// d.PackingType == FieldPackingType.Value
279-
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref valCounters);
278+
PositionUpdaterByRank[descriptor.Accessor.Rank].Invoke(ref descriptor, ref counters);
280279
}
281280

282281
static TupleLayout()
283282
{
284283
IncrementerByRank = new CounterIncrementer[] {
285-
(ref ValCounters valueCounters) => valueCounters.Val001Counter++,
286-
(ref ValCounters valueCounters) => throw new NotSupportedException(),
287-
(ref ValCounters valueCounters) => throw new NotSupportedException(),
288-
(ref ValCounters valueCounters) => valueCounters.Val008Counter++,
289-
(ref ValCounters valueCounters) => valueCounters.Val016Counter++,
290-
(ref ValCounters valueCounters) => valueCounters.Val032Counter++,
291-
(ref ValCounters valueCounters) => valueCounters.Val064Counter++,
292-
(ref ValCounters valueCounters) => valueCounters.Val128Counter++
284+
(ref Counters counters) => counters.Val001Counter++,
285+
(ref Counters counters) => throw new NotSupportedException(),
286+
(ref Counters counters) => throw new NotSupportedException(),
287+
(ref Counters counters) => counters.Val008Counter++,
288+
(ref Counters counters) => counters.Val016Counter++,
289+
(ref Counters counters) => counters.Val032Counter++,
290+
(ref Counters counters) => counters.Val064Counter++,
291+
(ref Counters counters) => counters.Val128Counter++
293292
};
294293

295294
PositionUpdaterByRank = new PositionUpdater[] {
296-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
297-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val001Counter),
298-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
295+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
296+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val001Counter),
297+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
299298
=> throw new NotSupportedException(),
300-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
299+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
301300
=> throw new NotSupportedException(),
302-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
303-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val008Counter),
304-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
305-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val016Counter),
306-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
307-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val032Counter),
308-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
309-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val064Counter),
310-
(ref PackedFieldDescriptor descriptor, ref ValCounters valCounters)
311-
=> UpdateDescriptorPosition(ref descriptor, ref valCounters.Val128Counter)
301+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
302+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val008Counter),
303+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
304+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val016Counter),
305+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
306+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val032Counter),
307+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
308+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val064Counter),
309+
(ref PackedFieldDescriptor descriptor, ref Counters counters)
310+
=> UpdateDescriptorPosition(ref descriptor, ref counters.Val128Counter)
312311
};
313312
}
314313
}

0 commit comments

Comments
 (0)