Skip to content

Commit 8640d1f

Browse files
committed
implement native and managed array support
1 parent 7693321 commit 8640d1f

22 files changed

Lines changed: 754 additions & 144 deletions

LinqGen.Benchmarks/Cases/AddVsAddRange.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public List<int> Add()
8888
{
8989
var query = TestData.Specialize().Where(x => x % 2 == 0);
9090

91-
using var temp = new PooledList<int, DynamicArrayManaged<int>>(0);
91+
using var temp = new PooledListNative<int>(0);
9292

9393
using var iter = query.GetEnumerator();
9494

@@ -103,7 +103,7 @@ public List<int> AddRange()
103103
{
104104
var query = TestData.Specialize().Where(x => x % 2 == 0);
105105

106-
using var temp = new PooledList<int, DynamicArrayManaged<int>>(0);
106+
using var temp = new PooledListNative<int>(0);
107107

108108
using var iter = query.GetEnumerator();
109109

LinqGen.Generator/CodeGenUtils.cs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -453,23 +453,16 @@ public static MemberAccessExpressionSyntax EqualityComparerDefault(TypeSyntax ty
453453
GenericName(Identifier("EqualityComparer"), TypeArgumentList(type)), IdentifierName("Default"));
454454
}
455455

456-
public static TypeSyntax DynamicArrayType(TypeSyntax elementType)
456+
public static TypeSyntax PooledListType(TypeSyntax elementType, bool isUnmanaged)
457457
{
458-
return GenericName(Identifier("DynamicArrayManaged"), TypeArgumentList(elementType));
458+
return GenericName(Identifier(isUnmanaged ? "PooledListNative" : "PooledListManaged"),
459+
TypeArgumentList(elementType));
459460
}
460461

461-
public static TypeSyntax PooledListType(TypeSyntax elementType)
462+
public static TypeSyntax PooledSetType(TypeSyntax elementType, TypeSyntax comparerType, bool isUnmanaged)
462463
{
463-
return GenericName(Identifier("PooledList"),
464-
TypeArgumentList(elementType, DynamicArrayType(elementType)));
465-
}
466-
467-
public static TypeSyntax PooledSetType(TypeSyntax elementType, TypeSyntax comparerType)
468-
{
469-
var slotType = GenericName(Identifier("PooledSetSlot"), TypeArgumentList(elementType));
470-
471-
return GenericName(Identifier("PooledSet"),
472-
TypeArgumentList(elementType, DynamicArrayType(slotType), comparerType));
464+
return GenericName(Identifier(isUnmanaged ? "PooledSetNative" : "PooledSetManaged"),
465+
TypeArgumentList(elementType, comparerType));
473466
}
474467

475468
public static TypeSyntax EnumerableInterfaceType(TypeSyntax elementType)

LinqGen.Generator/Instructions/Evaluations/Local/ToArrayEvaluation.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ protected override IEnumerable<StatementSyntax> RenderInitialization()
3030
: LiteralExpression(0);
3131

3232
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
33-
PooledListType(Upstream.OutputElementType), ArgumentList(countExpression), null));
33+
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
34+
ArgumentList(countExpression), null));
3435
}
3536

3637
protected override IEnumerable<StatementSyntax> RenderAccumulation()

LinqGen.Generator/Instructions/Evaluations/Local/ToListEvaluation.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ protected override IEnumerable<StatementSyntax> RenderInitialization()
3030
: LiteralExpression(0);
3131

3232
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
33-
PooledListType(Upstream.OutputElementType), ArgumentList(countExpression), null));
33+
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
34+
ArgumentList(countExpression), null));
3435
}
3536

3637
protected override IEnumerable<StatementSyntax> RenderAccumulation()

LinqGen.Generator/Instructions/Operations/DistinctOperation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ protected override IEnumerable<MemberInfo> GetMemberInfos(bool isLocal)
6868

6969
var countExpression = Upstream.RenderCount() ?? LiteralExpression(0);
7070

71-
var pooledSetType = PooledSetType(OutputElementType, ComparerType);
71+
var pooledSetType = PooledSetType(OutputElementType, ComparerType, OutputElementSymbol.IsUnmanagedType);
7272
var pooledSetCreation = ObjectCreationExpression(
7373
pooledSetType, ArgumentList(countExpression, comparerExpression), null);
7474

LinqGen.Generator/Instructions/Operations/Ordering/OrderingOperation.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,14 @@ public OrderingOperation(in LinqGenExpression expression, int id,
3030
{
3131
WithSelector = true;
3232
SelectorInterfaceType = ParseTypeName(selectorType);
33-
SelectorKeyType = ParseTypeName(selectorType.TypeArguments[1]);
33+
SelectorKeySymbol = selectorType.TypeArguments[1];
34+
SelectorKeyType = ParseTypeName(SelectorKeySymbol);
3435
}
3536
else
3637
{
3738
WithSelector = false;
3839
SelectorInterfaceType = null;
40+
SelectorKeySymbol = null;
3941
SelectorKeyType = null;
4042
}
4143
}
@@ -48,16 +50,25 @@ public OrderingOperation(in LinqGenExpression expression, int id,
4850
protected OrderingOperation RootOrder => UpstreamOrder?.RootOrder ?? this;
4951

5052
private TypeSyntax? SelectorInterfaceType { get; }
53+
private ITypeSymbol? SelectorKeySymbol { get; }
5154
private TypeSyntax? SelectorKeyType { get; }
5255

5356
private TypeSyntax KeyType => WithSelector ? SelectorKeyType! : OutputElementType;
5457

58+
private TypeSyntax KeyListType => WithSelector
59+
? PooledListType(SelectorKeyType!, SelectorKeySymbol!.IsUnmanagedType)
60+
: ElementListType;
61+
5562
private TypeSyntax ComparerInterfaceType =>
5663
GenericName(Identifier("IComparer"), TypeArgumentList(KeyType));
5764

5865
public override TypeSyntax EnumerableInterfaceType =>
5966
GenericName(Identifier("IInternalOrderedStub"), TypeArgumentList(OutputElementType));
6067

68+
public TypeSyntax ElementListType => PooledListType(OutputElementType, OutputElementSymbol.IsUnmanagedType);
69+
70+
public TypeSyntax IndexListType => PooledListType(IntType, true);
71+
6172
public override TypeSyntax? DummyParameterType
6273
{
6374
get
@@ -80,15 +91,11 @@ public override TypeSyntax? DummyParameterType
8091

8192
protected override IEnumerable<MemberInfo> GetMemberInfos(bool isLocal)
8293
{
83-
var elementsType = PooledListType(OutputElementType);
84-
85-
yield return new MemberInfo(MemberKind.Enumerator, elementsType, VarName("elements"),
86-
ObjectCreationExpression(elementsType, ArgumentList(LiteralExpression(0)), null));
87-
88-
var indicesType = PooledListType(IntType);
94+
yield return new MemberInfo(MemberKind.Enumerator, ElementListType, VarName("elements"),
95+
ObjectCreationExpression(ElementListType, ArgumentList(LiteralExpression(0)), null));
8996

90-
yield return new MemberInfo(MemberKind.Enumerator, PooledListType(IntType), VarName("indices"),
91-
ObjectCreationExpression(indicesType, ArgumentList(LiteralExpression(0)), null));
97+
yield return new MemberInfo(MemberKind.Enumerator, IndexListType, VarName("indices"),
98+
ObjectCreationExpression(IndexListType, ArgumentList(LiteralExpression(0)), null));
9299

93100
yield return new MemberInfo(MemberKind.Enumerator, IntType, VarName("index"), LiteralExpression(-1));
94101

@@ -177,7 +184,7 @@ public override IEnumerable<StatementSyntax> RenderInitialization(bool isLocal,
177184
var elementsCount = MemberAccessExpression(elementsName, CountProperty);
178185

179186
yield return ExpressionStatement(SimpleAssignmentExpression(elementsName,
180-
ObjectCreationExpression(PooledListType(OutputElementType), ArgumentList(countExpression), null)));
187+
ObjectCreationExpression(ElementListType, ArgumentList(countExpression), null)));
181188

182189
var addElementStatements = SingletonList<StatementSyntax>(
183190
ExpressionStatement(InvocationExpression(
@@ -205,7 +212,7 @@ public override IEnumerable<StatementSyntax> RenderInitialization(bool isLocal,
205212
var sorterName = IdentifierName("sorter");
206213

207214
sortBody.Add(ExpressionStatement(SimpleAssignmentExpression(indicesName,
208-
ObjectCreationExpression(PooledListType(IntType), ArgumentList(elementsCount), null))));
215+
ObjectCreationExpression(IndexListType, ArgumentList(elementsCount), null))));
209216

210217
var loopVar = IdentifierName("i");
211218

@@ -248,12 +255,12 @@ public IEnumerable<OrderMemberInfo> GetOrderMemberInfos()
248255
if (WithStruct)
249256
{
250257
yield return new OrderMemberInfo(this,
251-
WithSelector ? TypeName("Selector") : null, TypeName("Comparer"), KeyType);
258+
WithSelector ? TypeName("Selector") : null, TypeName("Comparer"), KeyType, KeyListType);
252259
}
253260
else
254261
{
255262
yield return new OrderMemberInfo(this,
256-
WithSelector ? SelectorInterfaceType : null, ComparerInterfaceType, KeyType);
263+
WithSelector ? SelectorInterfaceType : null, ComparerInterfaceType, KeyType, KeyListType);
257264
}
258265
}
259266

LinqGen.Generator/Templates/Ordering/OrderMemberInfo.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ public readonly struct OrderMemberInfo
1414
public readonly TypeSyntax? SelectorType;
1515
public readonly TypeSyntax ComparerType;
1616
public readonly TypeSyntax KeyType;
17+
public readonly TypeSyntax KeyListType;
1718

1819
public OrderMemberInfo(OrderingOperation operation,
19-
TypeSyntax? selectorType, TypeSyntax comparerType, TypeSyntax keyType)
20+
TypeSyntax? selectorType, TypeSyntax comparerType, TypeSyntax keyType, TypeSyntax keyListType)
2021
{
2122
Operation = operation;
2223
SelectorType = selectorType;
2324
ComparerType = comparerType;
2425
KeyType = keyType;
26+
KeyListType = keyListType;
2527
}
2628

2729
public int Id => Operation.Id;

LinqGen.Generator/Templates/Ordering/SorterTemplate.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void Dispose()
3636
}
3737
3838
public void PartialQuickSort(
39-
DynamicArrayManaged<int> indexesToSort, int left, int right, int min, int max)
39+
DynamicArrayNative<int> indexesToSort, int left, int right, int min, int max)
4040
{
4141
do
4242
{
@@ -53,7 +53,7 @@ public void PartialQuickSort(
5353
// Hoare partition scheme
5454
// This implementation is faster when using struct comparer (more comparison and less copy)
5555
private int PartitionHoare(
56-
DynamicArrayManaged<int> indexesToSort, int left, int right)
56+
DynamicArrayNative<int> indexesToSort, int left, int right)
5757
{
5858
// preventing overflow of the pivot
5959
int pivot = left + ((right - left) >> 1);
@@ -97,7 +97,7 @@ public Rewriter(OrderingOperation operation)
9797
switch (node.Identifier.ValueText)
9898
{
9999
case "_PooledList_":
100-
return PooledListType(_operation.OutputElementType);
100+
return _operation.ElementListType;
101101
}
102102

103103
return base.VisitIdentifierName(node);
@@ -149,13 +149,12 @@ private StructDeclarationSyntax RenderComparerStruct(StructDeclarationSyntax nod
149149
}
150150

151151
list.Add(FieldDeclaration(
152-
PrivateTokenList, PooledListType(member.KeyType), member.KeysName.Identifier));
152+
PrivateTokenList, member.KeyListType, member.KeysName.Identifier));
153153
}
154154

155155
if (needElement)
156156
{
157-
list.Add(FieldDeclaration(
158-
PrivateTokenList, PooledListType(_operation.OutputElementType), Identifier("elements")));
157+
list.Add(FieldDeclaration(PrivateTokenList, _operation.ElementListType, Identifier("elements")));
159158
}
160159

161160
return node.AddMembers(list.ToArray());
@@ -191,7 +190,7 @@ private ConstructorDeclarationSyntax RenderConstructor(ConstructorDeclarationSyn
191190
}
192191

193192
list.Add(ExpressionStatement(SimpleAssignmentExpression(member.KeysName,
194-
ObjectCreationExpression(PooledListType(member.KeyType), ArgumentList(elementCount), null))));
193+
ObjectCreationExpression(member.KeyListType, ArgumentList(elementCount), null))));
195194

196195
var indexName = IdentifierName("i");
197196

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// LinqGen, Maxwell Keonwoo Kang <code.athei@gmail.com>, 2022
2+
3+
using System;
4+
using System.Runtime.CompilerServices;
5+
6+
namespace Cathei.LinqGen.Hidden
7+
{
8+
/// <summary>
9+
/// This interface is guideline for dynamic array implementation
10+
/// </summary>
11+
public interface IDynamicArray<T> : IDisposable
12+
{
13+
void SetCapacity(int newSize, bool clear = false);
14+
15+
void IncreaseCapacity(int newSize, int copyCount = 0);
16+
17+
void Clear();
18+
19+
void CopyTo(T[] array, int count);
20+
21+
ref T this[int index] { get; }
22+
23+
ref T this[uint index] { get; }
24+
25+
int Length { get; }
26+
}
27+
}

LinqGen/Core/Collections/DynamicArrayManaged.cs renamed to LinqGen/Core/Collections/Managed/DynamicArrayManaged.cs

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,6 @@
66

77
namespace Cathei.LinqGen.Hidden
88
{
9-
public interface IDynamicArray<T> : IDisposable
10-
{
11-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
12-
void SetCapacity(int newSize, bool clear = false);
13-
14-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
15-
void IncreaseCapacity(int newSize, int copyCount = 0);
16-
17-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
18-
void Clear(int start, int end);
19-
20-
void CopyTo(T[] array, int count);
21-
22-
ref T this[int index]
23-
{
24-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
25-
get;
26-
}
27-
28-
ref T this[uint index]
29-
{
30-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
31-
get;
32-
}
33-
34-
int Length
35-
{
36-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
37-
get;
38-
}
39-
}
40-
419
public struct DynamicArrayManaged<T> : IDynamicArray<T>
4210
{
4311
private T[] _array;
@@ -68,7 +36,7 @@ public void SetCapacity(int newSize, bool clear = false)
6836
_array = SharedArrayPool<T>.Rent(newSize);
6937

7038
if (clear)
71-
Array.Clear(_array, 0, _array.Length);
39+
Clear();
7240
}
7341

7442
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -82,9 +50,9 @@ public void IncreaseCapacity(int newSize, int copyCount = 0)
8250
}
8351

8452
[MethodImpl(MethodImplOptions.AggressiveInlining)]
85-
public void Clear(int start, int end)
53+
public void Clear()
8654
{
87-
Array.Clear(_array, start, end);
55+
Array.Clear(_array, 0, _array.Length);
8856
}
8957

9058
[MethodImpl(MethodImplOptions.AggressiveInlining)]

0 commit comments

Comments
 (0)