Skip to content

Commit c85fee9

Browse files
AlexUstinovSergeiPavlov
authored andcommitted
Introduce better solution for readonly access to PackedFieldDescriptor structure by reference
1 parent a6b9352 commit c85fee9

File tree

8 files changed

+122
-121
lines changed

8 files changed

+122
-121
lines changed

Orm/Xtensive.Orm/Tuples/AccessorDelegates.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// Copyright (C) 2003-2010 Xtensive LLC.
2-
// All rights reserved.
3-
// For conditions of distribution and use, see license.
1+
// Copyright (C) 2009-2021 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
44
// Created by: Alexis Kochetov
55
// Created: 2009.09.17
66

Orm/Xtensive.Orm/Tuples/Packed/PackedFieldAccessor.cs

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,18 @@ public void SetValue<T>(PackedTuple tuple, in PackedFieldDescriptor descriptor,
5151
public T GetValue<T>(PackedTuple tuple, in PackedFieldDescriptor descriptor, bool isNullable, out TupleFieldState fieldState)
5252
{
5353
var getter = (isNullable ? NullableGetter : Getter) as GetValueDelegate<T>;
54-
if (getter!=null)
54+
if (getter != null) {
5555
return getter.Invoke(tuple, descriptor, out fieldState);
56-
var targetType = typeof (T);
56+
}
57+
var targetType = typeof(T);
5758

5859
//Dirty hack of nullable enum reading
59-
if (isNullable)
60+
if (isNullable) {
6061
targetType = Nullable.GetUnderlyingType(targetType) ?? targetType;
61-
if (targetType.IsEnum)
62+
}
63+
if (targetType.IsEnum) {
6264
return (T) Enum.ToObject(targetType, GetUntypedValue(tuple, descriptor, out fieldState));
65+
}
6366
return (T) GetUntypedValue(tuple, descriptor, out fieldState);
6467
}
6568

@@ -106,32 +109,30 @@ public override object GetUntypedValue(PackedTuple tuple, in PackedFieldDescript
106109
{
107110
var state = tuple.GetFieldState(descriptor);
108111
fieldState = state;
109-
return state==TupleFieldState.Available ? tuple.Objects[descriptor.ObjectIndex] : null;
112+
return state == TupleFieldState.Available ? tuple.Objects[descriptor.GetObjectIndex()] : null;
110113
}
111114

112115
public override void SetUntypedValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, object value)
113116
{
114-
tuple.Objects[descriptor.ObjectIndex] = value;
117+
tuple.Objects[descriptor.GetObjectIndex()] = value;
115118
tuple.SetFieldState(descriptor, value != null ? TupleFieldState.Available : (TupleFieldState.Available | TupleFieldState.Null));
116119
}
117120

118121
public override void CopyValue(PackedTuple source, in PackedFieldDescriptor sourceDescriptor,
119122
PackedTuple target, in PackedFieldDescriptor targetDescriptor)
120123
{
121-
target.Objects[targetDescriptor.ObjectIndex] = source.Objects[sourceDescriptor.ObjectIndex];
124+
target.Objects[targetDescriptor.GetObjectIndex()] = source.Objects[sourceDescriptor.GetObjectIndex()];
122125
}
123126

124127
public override bool ValueEquals(PackedTuple left, in PackedFieldDescriptor leftDescriptor,
125128
PackedTuple right, in PackedFieldDescriptor rightDescriptor)
126129
{
127-
var leftValue = left.Objects[leftDescriptor.ObjectIndex];
128-
var rightValue = right.Objects[rightDescriptor.ObjectIndex];
129-
return leftValue.Equals(rightValue);
130+
return Equals(left.Objects[leftDescriptor.GetObjectIndex()], right.Objects[rightDescriptor.GetObjectIndex()]);
130131
}
131132

132133
public override int GetValueHashCode(PackedTuple tuple, in PackedFieldDescriptor descriptor)
133134
{
134-
return tuple.Objects[descriptor.ObjectIndex].GetHashCode();
135+
return tuple.Objects[descriptor.GetObjectIndex()]?.GetHashCode() ?? 0;
135136
}
136137

137138
public ObjectFieldAccessor()
@@ -167,14 +168,13 @@ internal abstract class ValueFieldAccessor<T> : ValueFieldAccessor
167168

168169
public override object GetUntypedValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, out TupleFieldState fieldState)
169170
{
170-
var state = tuple.GetFieldState(descriptor);
171-
fieldState = state;
172-
return state==TupleFieldState.Available ? (object) Load(tuple, descriptor) : null;
171+
fieldState = tuple.GetFieldState(descriptor);
172+
return fieldState == TupleFieldState.Available ? (object) Load(tuple, descriptor) : null;
173173
}
174174

175175
public override void SetUntypedValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, object value)
176176
{
177-
if (value!=null) {
177+
if (value != null) {
178178
Store(tuple, descriptor, (T) value);
179179
tuple.SetFieldState(descriptor, TupleFieldState.Available);
180180
}
@@ -190,12 +190,8 @@ public override void CopyValue(PackedTuple source, in PackedFieldDescriptor sour
190190
}
191191

192192
public override bool ValueEquals(PackedTuple left, in PackedFieldDescriptor leftDescriptor,
193-
PackedTuple right, in PackedFieldDescriptor rightDescriptor)
194-
{
195-
var leftValue = Load(left, leftDescriptor);
196-
var rightValue = Load(right, rightDescriptor);
197-
return leftValue.Equals(rightValue);
198-
}
193+
PackedTuple right, in PackedFieldDescriptor rightDescriptor) =>
194+
Load(left, leftDescriptor).Equals(Load(right, rightDescriptor));
199195

200196
public override int GetValueHashCode(PackedTuple tuple, in PackedFieldDescriptor descriptor)
201197
{
@@ -204,16 +200,14 @@ public override int GetValueHashCode(PackedTuple tuple, in PackedFieldDescriptor
204200

205201
private T GetValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, out TupleFieldState fieldState)
206202
{
207-
var state = tuple.GetFieldState(descriptor);
208-
fieldState = state;
209-
return state==TupleFieldState.Available ? Load(tuple, descriptor) : DefaultValue;
203+
fieldState = tuple.GetFieldState(descriptor);
204+
return fieldState == TupleFieldState.Available ? Load(tuple, descriptor) : DefaultValue;
210205
}
211206

212207
private T? GetNullableValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, out TupleFieldState fieldState)
213208
{
214-
var state = tuple.GetFieldState(descriptor);
215-
fieldState = state;
216-
return state==TupleFieldState.Available ? Load(tuple, descriptor) : NullValue;
209+
fieldState = tuple.GetFieldState(descriptor);
210+
return fieldState == TupleFieldState.Available ? Load(tuple, descriptor) : NullValue;
217211
}
218212

219213
private void SetValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, T value)
@@ -224,37 +218,38 @@ private void SetValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, T
224218

225219
private void SetNullableValue(PackedTuple tuple, in PackedFieldDescriptor descriptor, T? value)
226220
{
227-
if (value!=null) {
221+
if (value != null) {
228222
Store(tuple, descriptor, value.Value);
229223
tuple.SetFieldState(descriptor, TupleFieldState.Available);
230224
}
231-
else
225+
else {
232226
tuple.SetFieldState(descriptor, TupleFieldState.Available | TupleFieldState.Null);
227+
}
233228
}
234229

235230
private void Store(PackedTuple tuple, in PackedFieldDescriptor d, T value)
236231
{
237-
var valueIndex = d.ValueIndex;
232+
var valueIndex = d.GetValueIndex();
238233
if (Rank > 6) {
239234
Encode(value, tuple.Values, valueIndex);
240235
return;
241236
}
242237

243238
var encoded = Encode(value);
244239
ref var block = ref tuple.Values[valueIndex];
245-
var valueBitOffset = d.ValueBitOffset;
240+
var valueBitOffset = d.GetValueBitOffset();
246241
var mask = ValueBitMask << valueBitOffset;
247242
block = (block & ~mask) | ((encoded << valueBitOffset) & mask);
248243
}
249244

250245
private T Load(PackedTuple tuple, in PackedFieldDescriptor d)
251246
{
252-
var valueIndex = d.ValueIndex;
247+
var valueIndex = d.GetValueIndex();
253248
if (Rank > 6) {
254249
return Decode(tuple.Values, valueIndex);
255250
}
256251

257-
var encoded = (tuple.Values[valueIndex] >> d.ValueBitOffset) & ValueBitMask;
252+
var encoded = (tuple.Values[valueIndex] >> d.GetValueBitOffset()) & ValueBitMask;
258253
return Decode(encoded);
259254
}
260255

@@ -279,7 +274,7 @@ protected override long Encode(bool value)
279274

280275
protected override bool Decode(long value)
281276
{
282-
return value!=0;
277+
return value != 0;
283278
}
284279

285280
public BooleanFieldAccessor()
@@ -299,7 +294,7 @@ protected override long Encode(float value)
299294

300295
protected override float Decode(long value)
301296
{
302-
var intValue = unchecked ((int) value);
297+
var intValue = unchecked((int) value);
303298
unsafe {
304299
return *(float*) &intValue;
305300
}
@@ -374,7 +369,7 @@ protected override long Encode(byte value)
374369

375370
protected override byte Decode(long value)
376371
{
377-
return unchecked ((byte) value);
372+
return unchecked((byte) value);
378373
}
379374

380375
public ByteFieldAccessor()
@@ -392,15 +387,15 @@ protected override long Encode(sbyte value)
392387

393388
protected override sbyte Decode(long value)
394389
{
395-
return unchecked ((sbyte) value);
390+
return unchecked((sbyte) value);
396391
}
397392

398393
public SByteFieldAccessor()
399394
: base(sizeof(sbyte) * 8, 8)
400395
{
401396
}
402397
}
403-
398+
404399
internal sealed class ShortFieldAccessor : ValueFieldAccessor<short>
405400
{
406401
protected override long Encode(short value)
@@ -410,15 +405,15 @@ protected override long Encode(short value)
410405

411406
protected override short Decode(long value)
412407
{
413-
return unchecked ((short) value);
408+
return unchecked((short) value);
414409
}
415410

416411
public ShortFieldAccessor()
417412
: base(sizeof(short) * 8, 9)
418413
{
419414
}
420415
}
421-
416+
422417
internal sealed class UShortFieldAccessor : ValueFieldAccessor<ushort>
423418
{
424419
protected override long Encode(ushort value)
@@ -428,15 +423,15 @@ protected override long Encode(ushort value)
428423

429424
protected override ushort Decode(long value)
430425
{
431-
return unchecked ((ushort) value);
426+
return unchecked((ushort) value);
432427
}
433428

434429
public UShortFieldAccessor()
435430
: base(sizeof(ushort) * 8, 10)
436431
{
437432
}
438433
}
439-
434+
440435
internal sealed class IntFieldAccessor : ValueFieldAccessor<int>
441436
{
442437
protected override long Encode(int value)
@@ -446,15 +441,15 @@ protected override long Encode(int value)
446441

447442
protected override int Decode(long value)
448443
{
449-
return unchecked ((int) value);
444+
return unchecked((int) value);
450445
}
451446

452447
public IntFieldAccessor()
453448
: base(sizeof(int) * 8, 11)
454449
{
455450
}
456451
}
457-
452+
458453
internal sealed class UIntFieldAccessor : ValueFieldAccessor<uint>
459454
{
460455
protected override long Encode(uint value)
@@ -464,15 +459,15 @@ protected override long Encode(uint value)
464459

465460
protected override uint Decode(long value)
466461
{
467-
return unchecked ((uint) value);
462+
return unchecked((uint) value);
468463
}
469464

470465
public UIntFieldAccessor()
471466
: base(sizeof(uint) * 8, 12)
472467
{
473468
}
474469
}
475-
470+
476471
internal sealed class LongFieldAccessor : ValueFieldAccessor<long>
477472
{
478473
protected override long Encode(long value)
@@ -490,7 +485,7 @@ public LongFieldAccessor()
490485
{
491486
}
492487
}
493-
488+
494489
internal sealed class ULongFieldAccessor : ValueFieldAccessor<ulong>
495490
{
496491
protected override long Encode(ulong value)
@@ -529,7 +524,7 @@ protected override void Encode(Guid value, long[] values, int offset)
529524

530525
private static unsafe int GetSize()
531526
{
532-
return sizeof (Guid);
527+
return sizeof(Guid);
533528
}
534529

535530
public GuidFieldAccessor()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (C) 2021 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
namespace Xtensive.Tuples.Packed
6+
{
7+
internal static class PackedFieldDescriptorExtensions
8+
{
9+
private const int OffsetBitCount = 6;
10+
private const int OffsetMask = (1 << OffsetBitCount) - 1;
11+
12+
public static PackedFieldAccessor GetAccessor(in this PackedFieldDescriptor descriptor) => PackedFieldAccessor.All[descriptor.AccessorIndex];
13+
public static bool IsObjectField(in this PackedFieldDescriptor descriptor) => descriptor.GetAccessor().Rank < 0;
14+
public static int GetObjectIndex(in this PackedFieldDescriptor descriptor) => descriptor.DataPosition;
15+
public static int GetValueIndex(in this PackedFieldDescriptor descriptor) => descriptor.DataPosition >> OffsetBitCount;
16+
public static int GetValueBitOffset(in this PackedFieldDescriptor descriptor) => descriptor.DataPosition & OffsetMask;
17+
public static int GetStateIndex(in this PackedFieldDescriptor descriptor) => descriptor.StatePosition >> OffsetBitCount;
18+
public static int GetStateBitOffset(in this PackedFieldDescriptor descriptor) => descriptor.StatePosition & OffsetMask;
19+
}
20+
}

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

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,10 @@ namespace Xtensive.Tuples.Packed
1111
[Serializable]
1212
internal struct PackedFieldDescriptor
1313
{
14-
private const int OffsetBitCount = 6;
15-
private const int OffsetMask = (1 << OffsetBitCount) - 1;
16-
1714
internal int DataPosition;
1815
internal ushort StatePosition;
1916

2017
[NonSerialized]
2118
internal byte AccessorIndex;
22-
23-
public PackedFieldAccessor Accessor => PackedFieldAccessor.All[AccessorIndex];
24-
25-
public bool IsObjectField => Accessor.Rank < 0;
26-
27-
public int ObjectIndex => DataPosition;
28-
29-
public int ValueIndex => DataPosition >> OffsetBitCount;
30-
public int ValueBitOffset => DataPosition & OffsetMask;
31-
32-
public int StateIndex => StatePosition >> OffsetBitCount;
33-
public int StateBitOffset => StatePosition & OffsetMask;
3419
}
35-
}
20+
}

0 commit comments

Comments
 (0)