Skip to content

Commit

Permalink
Use ValueTasks instead of Tasks (#81)
Browse files Browse the repository at this point in the history
* Use ValueTask to go Faster.

* More ValueTasks, more Fast.

* Fix build.

* Revert "Auxiliary commit to revert individual files from c9f13c9"

This reverts commit 784c94d4c41e44a50b43c466758eedf2106aba80.
  • Loading branch information
HarryCordewener authored Nov 30, 2024
1 parent 1b87fab commit 1e70b2f
Show file tree
Hide file tree
Showing 45 changed files with 296 additions and 318 deletions.
25 changes: 9 additions & 16 deletions Core.Arango.Tests/LinqTest_BasicOperations.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Core.Arango.Protocol;
Expand Down Expand Up @@ -46,14 +44,9 @@ class InnerChain
public string F { get; set; }
}

public class LinqTest_BasicOperations : TestBase
public class LinqTest_BasicOperations(ITestOutputHelper output) : TestBase
{
private const string D = "test";
private readonly ITestOutputHelper _output;
public LinqTest_BasicOperations(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public void Any()
Expand Down Expand Up @@ -81,7 +74,7 @@ public async Task GroupBy()

var result = await q.ToListAsync();

_output.WriteLine(q.ToAql().aql);
output.WriteLine(q.ToAql().aql);
}

/*[Fact]
Expand Down Expand Up @@ -192,7 +185,7 @@ public async Task Count_In_Filter()
var q = Arango.Query<Activity>("test")
.Where(x => x.Notes.Count() == 3);

_output.WriteLine(q.ToAql().aql);
output.WriteLine(q.ToAql().aql);

var activities = await q.ToListAsync();

Expand All @@ -205,7 +198,7 @@ public async Task Count_In_Select()
var q = Arango.Query<Activity>("test")
.Select(x => x.Notes.Count());

_output.WriteLine(q.ToAql().aql);
output.WriteLine(q.ToAql().aql);

var activitiesNotesCount = await q.ToListAsync();

Expand All @@ -227,7 +220,7 @@ public async Task Contains()
{
var p = await Arango.Query<Activity>("test").FirstOrDefaultAsync();

_output.WriteLine(JsonConvert.SerializeObject(p));
output.WriteLine(JsonConvert.SerializeObject(p));

var boolean = Arango.Query<Activity>("test").Contains(p); // This should work: does `p` not get serialized the same way is it gets de-serialized? This operations should be inverse of each other.

Expand Down Expand Up @@ -283,7 +276,7 @@ public async Task Except_Compare_Keys()
.Select(x => x.Key)
.Except(list);

PrintQuery(q, _output);
PrintQuery(q, output);

var p = await q.ToListAsync();

Expand All @@ -298,7 +291,7 @@ public async Task Combine_Skip_Take()
.Take(1)
.Select(x => x.Key);

PrintQuery(q, _output);
PrintQuery(q, output);

var p = await q.ToListAsync();

Expand Down Expand Up @@ -357,8 +350,8 @@ public async Task Union()

var aql = q.ToAql();

_output.WriteLine(aql.aql);
_output.WriteLine(JsonConvert.SerializeObject(aql.bindVars));
output.WriteLine(aql.aql);
output.WriteLine(JsonConvert.SerializeObject(aql.bindVars));

var p = await q.ToListAsync();

Expand Down
18 changes: 5 additions & 13 deletions Core.Arango.Tests/LinqTest_String.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Core.Arango.Protocol;
using Core.Arango.Linq;
using Core.Arango.Tests.Core;
using Newtonsoft.Json;
using Xunit;
using Xunit.Abstractions;

namespace Core.Arango.Tests
{
public class LinqTest_String : TestBase
public class LinqTest_String(ITestOutputHelper output) : TestBase
{
private const string D = "test";
private readonly ITestOutputHelper _output;
public LinqTest_String(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public async Task StringConcat()
Expand Down Expand Up @@ -201,8 +193,8 @@ public async Task StringSubstring()
Assert.Equal("Project A", p1.Name);
Assert.Equal("Project A", p2.Name);

_output.WriteLine(q1.ToAql().aql);
_output.WriteLine(q2.ToAql().aql);
output.WriteLine(q1.ToAql().aql);
output.WriteLine(q2.ToAql().aql);
}

[Fact]
Expand All @@ -212,7 +204,7 @@ public async Task StringToLower()
var p = await q.FirstOrDefaultAsync();

Assert.Equal("Project A", p.Name);
_output.WriteLine(q.ToAql().aql);
output.WriteLine(q.ToAql().aql);
}

[Fact]
Expand All @@ -222,7 +214,7 @@ public async Task StringToUpper()
var p = await q.FirstOrDefaultAsync();

Assert.Equal("Project A", p.Name);
_output.WriteLine(q.ToAql().aql);
output.WriteLine(q.ToAql().aql);
}

public override async Task InitializeAsync()
Expand Down
11 changes: 2 additions & 9 deletions Core.Arango.Tests/QueryStatisticTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,8 @@

namespace Core.Arango.Tests
{
public class QueryStatisticTest : TestBase
public class QueryStatisticTest(ITestOutputHelper output) : TestBase
{
private readonly ITestOutputHelper _output;

public QueryStatisticTest(ITestOutputHelper output)
{
_output = output;
}

public override async Task InitializeAsync()
{
Arango =
Expand All @@ -31,7 +24,7 @@ public override async Task InitializeAsync()
foreach (var p in bindVars.OrderByDescending(x => x.Key.Length))
boundQuery = boundQuery.Replace("@" + p.Key, JsonConvert.SerializeObject(p.Value));

_output.WriteLine(
output.WriteLine(
$"{boundQuery}\n{JsonConvert.SerializeObject(stats, Formatting.Indented)}");
}
});
Expand Down
2 changes: 1 addition & 1 deletion Core.Arango.Tests/TransactionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public async Task StreamTransactionQuery(string serializer)
Assert.Equal(3, (await Arango.Query.FindAsync<Entity>("test", "test", $"true")).Count);

var exception =
await Assert.ThrowsAsync<ArangoException>(() => Arango.Query.FindAsync<Entity>(t2, "test", $"true"));
await Assert.ThrowsAsync<ArangoException>(() => Arango.Query.FindAsync<Entity>(t2, "test", $"true").AsTask());

Assert.NotNull(exception.ErrorNumber);
Assert.NotNull(exception.Code);
Expand Down
4 changes: 2 additions & 2 deletions Core.Arango/ArangoContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public ArangoContext(string cs, IArangoConfiguration settings = null)
public IArangoPregelModule Pregel { get; }

/// <inheritdoc />
public async Task<ArangoVersion> GetVersionAsync(CancellationToken cancellationToken = default)
public async ValueTask<ArangoVersion> GetVersionAsync(CancellationToken cancellationToken = default)
{
var res = await Configuration.Transport.SendAsync<ArangoVersion>(HttpMethod.Get,
"/_db/_system/_api/version",
Expand All @@ -123,7 +123,7 @@ public async Task<ArangoVersion> GetVersionAsync(CancellationToken cancellationT
}

/// <inheritdoc />
public async Task<IReadOnlyCollection<string>> GetEndpointsAsync(CancellationToken cancellationToken = default)
public async ValueTask<IReadOnlyCollection<string>> GetEndpointsAsync(CancellationToken cancellationToken = default)
{
var res = await Configuration.Transport.SendAsync<EndpointResponse>(HttpMethod.Get,
"/_api/cluster/endpoints", cancellationToken: cancellationToken);
Expand Down
4 changes: 2 additions & 2 deletions Core.Arango/IArangoContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ public interface IArangoContext
/// <summary>
/// Get Arango server version and license
/// </summary>
Task<ArangoVersion> GetVersionAsync(CancellationToken cancellationToken = default);
ValueTask<ArangoVersion> GetVersionAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Get Arango cluster endpoints
/// </summary>
Task<IReadOnlyCollection<string>> GetEndpointsAsync(CancellationToken cancellationToken = default);
ValueTask<IReadOnlyCollection<string>> GetEndpointsAsync(CancellationToken cancellationToken = default);
}
}
22 changes: 11 additions & 11 deletions Core.Arango/Linq/ArangoQueryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,29 @@ public static (string aql, IDictionary<string, object> bindVars) ToAql<T>(this I
return (data.Query.Trim(), data.BindVars);
}

public static Task<TSource> FirstAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)
public static ValueTask<TSource> FirstAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)

Check warning on line 54 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.FirstAsync<TSource>(IQueryable<TSource>, CancellationToken)'
{
return FirstOrDefaultAsync(source, false, null, cancellationToken);
}

public static Task<TSource> FirstAsync<TSource>(this IQueryable<TSource> source,
public static ValueTask<TSource> FirstAsync<TSource>(this IQueryable<TSource> source,

Check warning on line 59 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.FirstAsync<TSource>(IQueryable<TSource>, Expression<Func<TSource, bool>>, CancellationToken)'
Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
{
return FirstOrDefaultAsync(source, false, predicate, cancellationToken);
}

public static Task<TSource> FirstOrDefaultAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)
public static ValueTask<TSource> FirstOrDefaultAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)

Check warning on line 65 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.FirstOrDefaultAsync<TSource>(IQueryable<TSource>, CancellationToken)'
{
return FirstOrDefaultAsync(source, true, null, cancellationToken);
}

public static Task<TSource> FirstOrDefaultAsync<TSource>(this IQueryable<TSource> source,
public static ValueTask<TSource> FirstOrDefaultAsync<TSource>(this IQueryable<TSource> source,

Check warning on line 70 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.FirstOrDefaultAsync<TSource>(IQueryable<TSource>, Expression<Func<TSource, bool>>, CancellationToken)'
Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
{
return FirstOrDefaultAsync(source, true, predicate, cancellationToken);
}

private static Task<T> FirstOrDefaultAsync<T>(this IQueryable<T> source, bool returnDefaultWhenEmpty,
private static ValueTask<T> FirstOrDefaultAsync<T>(this IQueryable<T> source, bool returnDefaultWhenEmpty,
Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
if (predicate != null)
Expand All @@ -85,29 +85,29 @@ private static Task<T> FirstOrDefaultAsync<T>(this IQueryable<T> source, bool re
: source.AsArangoQueryable().FirstAsync(cancellationToken);
}

public static Task<TSource> SingleAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)
public static ValueTask<TSource> SingleAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)

Check warning on line 88 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.SingleAsync<TSource>(IQueryable<TSource>, CancellationToken)'
{
return SingleOrDefaultAsync(source, false, null, cancellationToken);
}

public static Task<TSource> SingleAsync<TSource>(this IQueryable<TSource> source,
public static ValueTask<TSource> SingleAsync<TSource>(this IQueryable<TSource> source,

Check warning on line 93 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.SingleAsync<TSource>(IQueryable<TSource>, Expression<Func<TSource, bool>>, CancellationToken)'
Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
{
return SingleOrDefaultAsync(source, false, predicate, cancellationToken);
}

public static Task<TSource> SingleOrDefaultAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)
public static ValueTask<TSource> SingleOrDefaultAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default)

Check warning on line 99 in Core.Arango/Linq/ArangoQueryExtensions.cs

View workflow job for this annotation

GitHub Actions / build (9.x, arangodb:3.11, single)

Missing XML comment for publicly visible type or member 'ArangoQueryableExtensions.SingleOrDefaultAsync<TSource>(IQueryable<TSource>, CancellationToken)'
{
return SingleOrDefaultAsync(source, true, null, cancellationToken);
}

public static Task<TSource> SingleOrDefaultAsync<TSource>(this IQueryable<TSource> source,
public static ValueTask<TSource> SingleOrDefaultAsync<TSource>(this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate, CancellationToken cancellationToken = default)
{
return SingleOrDefaultAsync(source, true, predicate, cancellationToken);
}

private static Task<T> SingleOrDefaultAsync<T>(this IQueryable<T> source, bool returnDefaultWhenEmpty,
private static ValueTask<T> SingleOrDefaultAsync<T>(this IQueryable<T> source, bool returnDefaultWhenEmpty,
Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default)
{
if (predicate != null)
Expand All @@ -119,7 +119,7 @@ private static Task<T> SingleOrDefaultAsync<T>(this IQueryable<T> source, bool r
: source.AsArangoQueryable().SingleAsync(cancellationToken);
}

public static Task<List<T>> ToListAsync<T>(this IQueryable<T> source, CancellationToken cancellationToken = default)
public static ValueTask<List<T>> ToListAsync<T>(this IQueryable<T> source, CancellationToken cancellationToken = default)
{
return source.AsArangoQueryable().ToListAsync(cancellationToken);
}
Expand Down
2 changes: 1 addition & 1 deletion Core.Arango/Linq/Interface/IArangoLinq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ internal interface IArangoLinq
public string ResolvePropertyName(Type t, string s);
public string ResolveCollectionName(Type t);
public IAsyncEnumerable<T> StreamAsync<T>(string query, IDictionary<string, object> bindVars, CancellationToken cancellationToken = default);
public Task<ArangoList<T>> ExecuteAsync<T>(string query, IDictionary<string, object> bindVars, CancellationToken cancellationToken = default);
public ValueTask<ArangoList<T>> ExecuteAsync<T>(string query, IDictionary<string, object> bindVars, CancellationToken cancellationToken = default);
}
}
2 changes: 1 addition & 1 deletion Core.Arango/Linq/Internal/ArangoLinq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public IAsyncEnumerable<T> StreamAsync<T>(string query, IDictionary<string, obje
return _context.Query.ExecuteStreamAsync<T>(_handle, query, bindVars, cancellationToken: cancellationToken);
}

public async Task<ArangoList<T>> ExecuteAsync<T>(string query, IDictionary<string, object> bindVars, CancellationToken cancellationToken = default)
public async ValueTask<ArangoList<T>> ExecuteAsync<T>(string query, IDictionary<string, object> bindVars, CancellationToken cancellationToken = default)
{
return await _context.Query.ExecuteAsync<T>(_handle, query, bindVars, cancellationToken: cancellationToken).ConfigureAwait(false);
}
Expand Down
10 changes: 5 additions & 5 deletions Core.Arango/Linq/Query/ArangoQueryable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,34 +29,34 @@ public ArangoQueryable(IQueryProvider provider, Expression expression, IArangoLi
this.db = db;
}

public async Task<List<T>> ToListAsync(CancellationToken cancellationToken = default)
public async ValueTask<List<T>> ToListAsync(CancellationToken cancellationToken = default)
{
var data = GetQueryData();
return await db.ExecuteAsync<T>(data.Query, data.BindVars, cancellationToken).ConfigureAwait(false);
}

public async Task<T> SingleOrDefaultAsync(CancellationToken cancellationToken = default)
public async ValueTask<T> SingleOrDefaultAsync(CancellationToken cancellationToken = default)
{
var data = GetQueryData();
var list = await db.ExecuteAsync<T>(data.Query, data.BindVars, cancellationToken).ConfigureAwait(false);
return list.SingleOrDefault();
}

public async Task<T> SingleAsync(CancellationToken cancellationToken = default)
public async ValueTask<T> SingleAsync(CancellationToken cancellationToken = default)
{
var data = GetQueryData();
var list = await db.ExecuteAsync<T>(data.Query, data.BindVars, cancellationToken).ConfigureAwait(false);
return list.Single();
}

public async Task<T> FirstOrDefaultAsync(CancellationToken cancellationToken = default)
public async ValueTask<T> FirstOrDefaultAsync(CancellationToken cancellationToken = default)
{
var data = GetQueryData();
var list = await db.ExecuteAsync<T>(data.Query, data.BindVars, cancellationToken).ConfigureAwait(false);
return list.FirstOrDefault();
}

public async Task<T> FirstAsync(CancellationToken cancellationToken = default)
public async ValueTask<T> FirstAsync(CancellationToken cancellationToken = default)
{
var data = GetQueryData();
var list = await db.ExecuteAsync<T>(data.Query, data.BindVars, cancellationToken).ConfigureAwait(false);
Expand Down
8 changes: 4 additions & 4 deletions Core.Arango/Modules/IArangoAnalyzerModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface IArangoAnalyzerModule
/// <summary>
/// creates a new Analyzer based on the provided definition
/// </summary>
Task CreateAsync(ArangoHandle database, ArangoAnalyzer analyzer, CancellationToken cancellationToken = default);
ValueTask CreateAsync(ArangoHandle database, ArangoAnalyzer analyzer, CancellationToken cancellationToken = default);

/// <summary>
/// removes an Analyzer configuration
Expand All @@ -22,19 +22,19 @@ public interface IArangoAnalyzerModule
/// <param name="analyzer">The name of the Analyzer to remove.</param>
/// <param name="force">The Analyzer configuration should be removed even if it is in-use. The default value is false.</param>
/// <param name="cancellationToken"></param>
Task DeleteAsync(ArangoHandle database, string analyzer, bool force = false,
ValueTask DeleteAsync(ArangoHandle database, string analyzer, bool force = false,
CancellationToken cancellationToken = default);

/// <summary>
/// returns a listing of available Analyzer definitions
/// </summary>
Task<IReadOnlyCollection<ArangoAnalyzer>> ListAsync(ArangoHandle database,
ValueTask<IReadOnlyCollection<ArangoAnalyzer>> ListAsync(ArangoHandle database,
CancellationToken cancellationToken = default);

/// <summary>
/// returns an Analyzer definition
/// </summary>
Task<ArangoAnalyzer> GetDefinitionAsync(ArangoHandle database, string analyzer,
ValueTask<ArangoAnalyzer> GetDefinitionAsync(ArangoHandle database, string analyzer,
CancellationToken cancellationToken = default);
}
}
Loading

0 comments on commit 1e70b2f

Please sign in to comment.