-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Regenerate bindings for 2.18. * Bump Core to 2.18.0. * Run nightly builds on release-2.18. * Bump version to 5.8.0. * Add APIs to delete fragments from arrays. * Add safe handle types for the newly introduced handles. `tiledb_channel_operator` does not have a free function so it does not need a safe handle. * Add APIs to evolve enumerations. * Add a `QueryField` type and simplify the query data buffer type validation. * Add query aggregate APIs. * Add documentation. * Add an aggregate query example. * Test that all expected file system backends are supported. * Add a test for aggregate queries. * Update documentation. * Add one more assertion. * Test min/max aggregates. * Update documentation. * Fix error handling. * Test null count aggregate.
- Loading branch information
1 parent
133e31b
commit c9a8023
Showing
28 changed files
with
1,031 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System; | ||
using System.IO; | ||
|
||
namespace TileDB.CSharp.Examples | ||
{ | ||
static class ExampleAggregateQuery | ||
{ | ||
private static readonly string ArrayPath = ExampleUtil.MakeExamplePath("aggregate-array"); | ||
private static readonly Context Ctx = Context.GetDefault(); | ||
|
||
private static void CreateArray() | ||
{ | ||
// Create array | ||
var dim1 = Dimension.Create(Ctx, "rows", boundLower: 1, boundUpper: 4, extent: 4); | ||
var dim2 = Dimension.Create(Ctx, "cols", boundLower: 1, boundUpper: 4, extent: 4); | ||
var domain = new Domain(Ctx); | ||
domain.AddDimension(dim1); | ||
domain.AddDimension(dim2); | ||
var array_schema = new ArraySchema(Ctx, ArrayType.Sparse); | ||
var attr = new Attribute(Ctx, "a", DataType.Int32); | ||
array_schema.AddAttribute(attr); | ||
array_schema.SetDomain(domain); | ||
array_schema.Check(); | ||
|
||
Array.Create(Ctx, ArrayPath, array_schema); | ||
} | ||
|
||
private static void WriteArray() | ||
{ | ||
using (var array_write = new Array(Ctx, ArrayPath)) | ||
{ | ||
array_write.Open(QueryType.Write); | ||
using (var query_write = new Query(array_write)) | ||
{ | ||
query_write.SetLayout(LayoutType.GlobalOrder); | ||
query_write.SetDataBuffer("rows", new int[] { 1, 2 }); | ||
query_write.SetDataBuffer("cols", new int[] { 1, 4 }); | ||
query_write.SetDataBuffer("a", new int[] { 1, 2 }); | ||
query_write.Submit(); | ||
query_write.SetDataBuffer("rows", new int[] { 3 }); | ||
query_write.SetDataBuffer("cols", new int[] { 3 }); | ||
query_write.SetDataBuffer("a", new int[] { 3 }); | ||
query_write.SubmitAndFinalize(); | ||
} | ||
array_write.Close(); | ||
} | ||
} | ||
|
||
private static void ReadArray() | ||
{ | ||
ulong[] count = { 0 }; | ||
long[] sum = { 0 }; | ||
|
||
using (var array_read = new Array(Ctx, ArrayPath)) | ||
{ | ||
array_read.Open(QueryType.Read); | ||
using var query_read = new Query(array_read); | ||
query_read.SetLayout(LayoutType.Unordered); | ||
using var channel = query_read.GetDefaultChannel(); | ||
channel.ApplyAggregate(AggregateOperation.Count, "Count"); | ||
channel.ApplyAggregate(AggregateOperation.Unary(AggregateOperator.Sum, "a"), "Sum"); | ||
query_read.SetDataBuffer("Count", count); | ||
query_read.SetDataBuffer("Sum", sum); | ||
query_read.Submit(); | ||
array_read.Close(); | ||
} | ||
|
||
Console.WriteLine($"Count: {count[0]}"); | ||
Console.WriteLine($"Sum: {sum[0]}"); | ||
} | ||
|
||
public static void Run() | ||
{ | ||
if (Directory.Exists(ArrayPath)) | ||
{ | ||
Directory.Delete(ArrayPath, true); | ||
} | ||
|
||
CreateArray(); | ||
WriteArray(); | ||
ReadArray(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
using TileDB.CSharp.Marshalling.SafeHandles; | ||
using TileDB.Interop; | ||
|
||
namespace TileDB.CSharp; | ||
|
||
/// <summary> | ||
/// Represents an aggregate operation. | ||
/// </summary> | ||
/// <remarks> | ||
/// This class abstracts the <c>tiledb_channel_operation_t</c> type of the TileDB C API. | ||
/// </remarks> | ||
public abstract class AggregateOperation | ||
{ | ||
// Prevent inheriting the class outside of this assembly. | ||
private protected AggregateOperation() { } | ||
|
||
/// <summary> | ||
/// Creates a unary aggregate operation. | ||
/// </summary> | ||
/// <param name="op">The <see cref="AggregateOperator"/> to apply.</param> | ||
/// <param name="fieldName">The name of the field to apply the operator to.</param> | ||
public static AggregateOperation Unary(AggregateOperator op, string fieldName) => new UnaryAggregateOperation(op, fieldName); | ||
|
||
/// <summary> | ||
/// An <see cref="AggregateOperation"/> returning the number of values in the channel. | ||
/// </summary> | ||
public static AggregateOperation Count { get; } = new CountAggregateOperation(); | ||
|
||
internal abstract unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q); | ||
|
||
private sealed class UnaryAggregateOperation : AggregateOperation | ||
{ | ||
private readonly AggregateOperator _operator; | ||
|
||
private readonly string _fieldName; | ||
|
||
public UnaryAggregateOperation(AggregateOperator op, string fieldName) | ||
{ | ||
_operator = op; | ||
_fieldName = fieldName; | ||
} | ||
|
||
internal override unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q) | ||
{ | ||
var handle = new ChannelOperationHandle(); | ||
bool successful = false; | ||
tiledb_channel_operation_t* op = null; | ||
try | ||
{ | ||
using var ctxHandle = ctx.Handle.Acquire(); | ||
using var queryHandle = q.Handle.Acquire(); | ||
using var ms_fieldName = new MarshaledString(_fieldName); | ||
ctx.handle_error(Methods.tiledb_create_unary_aggregate(ctxHandle, queryHandle, _operator.GetHandle(ctxHandle), ms_fieldName, &op)); | ||
successful = true; | ||
} | ||
finally | ||
{ | ||
if (successful) | ||
{ | ||
handle.InitHandle(ctx, op); | ||
} | ||
else | ||
{ | ||
handle.SetHandleAsInvalid(); | ||
} | ||
} | ||
return handle; | ||
} | ||
} | ||
|
||
private sealed class CountAggregateOperation : AggregateOperation | ||
{ | ||
internal override unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q) | ||
{ | ||
var handle = new ChannelOperationHandle(); | ||
bool successful = false; | ||
tiledb_channel_operation_t* op = null; | ||
try | ||
{ | ||
using var ctxHandle = ctx.Handle.Acquire(); | ||
ctx.handle_error(Methods.tiledb_aggregate_count_get(ctxHandle, &op)); | ||
successful = true; | ||
} | ||
finally | ||
{ | ||
if (successful) | ||
{ | ||
handle.InitHandle(ctx, op); | ||
} | ||
else | ||
{ | ||
handle.SetHandleAsInvalid(); | ||
} | ||
} | ||
return handle; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using System; | ||
using TileDB.Interop; | ||
|
||
namespace TileDB.CSharp; | ||
|
||
/// <summary> | ||
/// Represents an aggregate operator that can be applied over a query field. | ||
/// </summary> | ||
/// <remarks> | ||
/// This class abstracts the <c>tiledb_channel_operator_t</c> type of the TileDB C API. | ||
/// </remarks> | ||
public abstract class AggregateOperator | ||
{ | ||
// Prevent inheriting the class outside of this assembly. | ||
private protected AggregateOperator() { } | ||
|
||
internal abstract unsafe tiledb_channel_operator_t* GetHandle(tiledb_ctx_t* ctx); | ||
|
||
/// <summary> | ||
/// Computes the sum of all values in the field. | ||
/// </summary> | ||
public static AggregateOperator Sum { get; } = new SimpleAggregateOperator(OperatorKind.Sum); | ||
|
||
/// <summary> | ||
/// Computes the minimum value in the field. | ||
/// </summary> | ||
public static AggregateOperator Min { get; } = new SimpleAggregateOperator(OperatorKind.Min); | ||
|
||
/// <summary> | ||
/// Computes the maximum value in the field. | ||
/// </summary> | ||
public static AggregateOperator Max { get; } = new SimpleAggregateOperator(OperatorKind.Max); | ||
|
||
/// <summary> | ||
/// Computes the mean of all values in the field. | ||
/// </summary> | ||
public static AggregateOperator Mean { get; } = new SimpleAggregateOperator(OperatorKind.Mean); | ||
|
||
/// <summary> | ||
/// Counts the number of null values in the field. | ||
/// </summary> | ||
public static AggregateOperator NullCount { get; } = new SimpleAggregateOperator(OperatorKind.NullCount); | ||
|
||
private enum OperatorKind | ||
{ | ||
Sum, | ||
Min, | ||
Max, | ||
Mean, | ||
NullCount | ||
} | ||
|
||
private sealed class SimpleAggregateOperator : AggregateOperator | ||
{ | ||
private readonly OperatorKind _kind; | ||
|
||
public SimpleAggregateOperator(OperatorKind kind) | ||
{ | ||
_kind = kind; | ||
} | ||
|
||
internal override unsafe tiledb_channel_operator_t* GetHandle(tiledb_ctx_t* ctx) | ||
{ | ||
tiledb_channel_operator_t* op; | ||
var ret = _kind switch | ||
{ | ||
OperatorKind.Sum => Methods.tiledb_channel_operator_sum_get(ctx, &op), | ||
OperatorKind.Min => Methods.tiledb_channel_operator_min_get(ctx, &op), | ||
OperatorKind.Max => Methods.tiledb_channel_operator_max_get(ctx, &op), | ||
OperatorKind.Mean => Methods.tiledb_channel_operator_mean_get(ctx, &op), | ||
OperatorKind.NullCount => Methods.tiledb_channel_operator_null_count_get(ctx, &op), | ||
_ => throw new InvalidOperationException(), | ||
}; | ||
ErrorHandling.ThrowOnError(ret); | ||
return op; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.