Skip to content

Commit c9a8023

Browse files
Update Core to 2.18 (#325)
* 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.
1 parent 133e31b commit c9a8023

28 files changed

+1031
-29
lines changed

.github/workflows/nightly.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
platform: windows-x86_64
3030
BOOTSTRAP: ../bootstrap.ps1 -EnableS3 -EnableSerialization -EnableBuildDeps -EnableVcpkg
3131
- tag: dev
32-
tag: [release-2.17, dev]
32+
tag: [release-2.18, dev]
3333
runs-on: ${{ matrix.os }}
3434
steps:
3535
- name: Checkout TileDB
@@ -67,7 +67,7 @@ jobs:
6767
strategy:
6868
fail-fast: false
6969
matrix:
70-
tag: [release-2.17, dev]
70+
tag: [release-2.18, dev]
7171
runs-on: ubuntu-latest
7272
steps:
7373
- name: Checkout TileDB-CSharp
@@ -107,7 +107,7 @@ jobs:
107107
fail-fast: false
108108
matrix:
109109
os: [ubuntu-latest, macos-latest, windows-latest]
110-
tag: [release-2.17, dev]
110+
tag: [release-2.18, dev]
111111
runs-on: ${{ matrix.os }}
112112
steps:
113113
- name: Checkout TileDB-CSharp

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
<TileDBNativePackageName>TileDB.Native</TileDBNativePackageName>
5-
<TileDBNativePackageVersion>[2.17.0,2.18.0)</TileDBNativePackageVersion>
5+
<TileDBNativePackageVersion>[2.18.0,2.19.0)</TileDBNativePackageVersion>
66

77
<!-- The DevelopmentBuild property switches to the locally built native packages.
88
They have a different name to avoid publishing them by mistake, and to
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System;
2+
using System.IO;
3+
4+
namespace TileDB.CSharp.Examples
5+
{
6+
static class ExampleAggregateQuery
7+
{
8+
private static readonly string ArrayPath = ExampleUtil.MakeExamplePath("aggregate-array");
9+
private static readonly Context Ctx = Context.GetDefault();
10+
11+
private static void CreateArray()
12+
{
13+
// Create array
14+
var dim1 = Dimension.Create(Ctx, "rows", boundLower: 1, boundUpper: 4, extent: 4);
15+
var dim2 = Dimension.Create(Ctx, "cols", boundLower: 1, boundUpper: 4, extent: 4);
16+
var domain = new Domain(Ctx);
17+
domain.AddDimension(dim1);
18+
domain.AddDimension(dim2);
19+
var array_schema = new ArraySchema(Ctx, ArrayType.Sparse);
20+
var attr = new Attribute(Ctx, "a", DataType.Int32);
21+
array_schema.AddAttribute(attr);
22+
array_schema.SetDomain(domain);
23+
array_schema.Check();
24+
25+
Array.Create(Ctx, ArrayPath, array_schema);
26+
}
27+
28+
private static void WriteArray()
29+
{
30+
using (var array_write = new Array(Ctx, ArrayPath))
31+
{
32+
array_write.Open(QueryType.Write);
33+
using (var query_write = new Query(array_write))
34+
{
35+
query_write.SetLayout(LayoutType.GlobalOrder);
36+
query_write.SetDataBuffer("rows", new int[] { 1, 2 });
37+
query_write.SetDataBuffer("cols", new int[] { 1, 4 });
38+
query_write.SetDataBuffer("a", new int[] { 1, 2 });
39+
query_write.Submit();
40+
query_write.SetDataBuffer("rows", new int[] { 3 });
41+
query_write.SetDataBuffer("cols", new int[] { 3 });
42+
query_write.SetDataBuffer("a", new int[] { 3 });
43+
query_write.SubmitAndFinalize();
44+
}
45+
array_write.Close();
46+
}
47+
}
48+
49+
private static void ReadArray()
50+
{
51+
ulong[] count = { 0 };
52+
long[] sum = { 0 };
53+
54+
using (var array_read = new Array(Ctx, ArrayPath))
55+
{
56+
array_read.Open(QueryType.Read);
57+
using var query_read = new Query(array_read);
58+
query_read.SetLayout(LayoutType.Unordered);
59+
using var channel = query_read.GetDefaultChannel();
60+
channel.ApplyAggregate(AggregateOperation.Count, "Count");
61+
channel.ApplyAggregate(AggregateOperation.Unary(AggregateOperator.Sum, "a"), "Sum");
62+
query_read.SetDataBuffer("Count", count);
63+
query_read.SetDataBuffer("Sum", sum);
64+
query_read.Submit();
65+
array_read.Close();
66+
}
67+
68+
Console.WriteLine($"Count: {count[0]}");
69+
Console.WriteLine($"Sum: {sum[0]}");
70+
}
71+
72+
public static void Run()
73+
{
74+
if (Directory.Exists(ArrayPath))
75+
{
76+
Directory.Delete(ArrayPath, true);
77+
}
78+
79+
CreateArray();
80+
WriteArray();
81+
ReadArray();
82+
}
83+
}
84+
}

examples/TileDB.CSharp.Example/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static void Main(string[] args)
1616
ExampleWritingDenseGlobal.Run();
1717
ExampleWritingSparseGlobal.Run();
1818
ExampleDataframe.Run();
19+
ExampleAggregateQuery.Run();
1920

2021
ExampleFile.RunLocal();
2122
// ExampleFile.RunCloud("tiledb_api_token", "tiledb_namespace", "new_cloud_array_name", "s3://bucket/prefix/");

scripts/generate-bindings/GenerateBindings.proj

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,26 @@
1818
<InputFile Include="tiledb/tiledb_experimental.h" />
1919
<TraversePaths Include="$(InputDir)/**/*.h" />
2020
<RemapHandleType Include="attribute" />
21-
<RemapHandleType Include="buffer" />
2221
<RemapHandleType Include="buffer_list" />
23-
<RemapHandleType Include="config" />
22+
<RemapHandleType Include="buffer" />
23+
<RemapHandleType Include="channel_operation" />
24+
<RemapHandleType Include="channel_operator" />
2425
<RemapHandleType Include="config_iter" />
26+
<RemapHandleType Include="config" />
2527
<RemapHandleType Include="ctx" />
26-
<RemapHandleType Include="dimension" />
2728
<RemapHandleType Include="dimension_label" />
29+
<RemapHandleType Include="dimension" />
2830
<RemapHandleType Include="domain" />
2931
<RemapHandleType Include="enumeration" />
3032
<RemapHandleType Include="error" />
31-
<RemapHandleType Include="filter" />
3233
<RemapHandleType Include="filter_list" />
34+
<RemapHandleType Include="filter" />
3335
<RemapHandleType Include="group" />
36+
<RemapHandleType Include="query_channel" />
37+
<RemapHandleType Include="query_field" />
3438
<RemapHandleType Include="string" />
35-
<RemapHandleType Include="vfs" />
3639
<RemapHandleType Include="vfs_fh" />
40+
<RemapHandleType Include="vfs" />
3741
<Remap Include="@(RemapHandleType->'tiledb_%(Identity)_handle_t=tiledb_%(Identity)_t')" />
3842
<Remap Include="tiledb_experimental_query_status_details_t=tiledb_query_status_details_t" />
3943
<ExcludeDump Include="array_schema" />
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using TileDB.CSharp.Marshalling.SafeHandles;
2+
using TileDB.Interop;
3+
4+
namespace TileDB.CSharp;
5+
6+
/// <summary>
7+
/// Represents an aggregate operation.
8+
/// </summary>
9+
/// <remarks>
10+
/// This class abstracts the <c>tiledb_channel_operation_t</c> type of the TileDB C API.
11+
/// </remarks>
12+
public abstract class AggregateOperation
13+
{
14+
// Prevent inheriting the class outside of this assembly.
15+
private protected AggregateOperation() { }
16+
17+
/// <summary>
18+
/// Creates a unary aggregate operation.
19+
/// </summary>
20+
/// <param name="op">The <see cref="AggregateOperator"/> to apply.</param>
21+
/// <param name="fieldName">The name of the field to apply the operator to.</param>
22+
public static AggregateOperation Unary(AggregateOperator op, string fieldName) => new UnaryAggregateOperation(op, fieldName);
23+
24+
/// <summary>
25+
/// An <see cref="AggregateOperation"/> returning the number of values in the channel.
26+
/// </summary>
27+
public static AggregateOperation Count { get; } = new CountAggregateOperation();
28+
29+
internal abstract unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q);
30+
31+
private sealed class UnaryAggregateOperation : AggregateOperation
32+
{
33+
private readonly AggregateOperator _operator;
34+
35+
private readonly string _fieldName;
36+
37+
public UnaryAggregateOperation(AggregateOperator op, string fieldName)
38+
{
39+
_operator = op;
40+
_fieldName = fieldName;
41+
}
42+
43+
internal override unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q)
44+
{
45+
var handle = new ChannelOperationHandle();
46+
bool successful = false;
47+
tiledb_channel_operation_t* op = null;
48+
try
49+
{
50+
using var ctxHandle = ctx.Handle.Acquire();
51+
using var queryHandle = q.Handle.Acquire();
52+
using var ms_fieldName = new MarshaledString(_fieldName);
53+
ctx.handle_error(Methods.tiledb_create_unary_aggregate(ctxHandle, queryHandle, _operator.GetHandle(ctxHandle), ms_fieldName, &op));
54+
successful = true;
55+
}
56+
finally
57+
{
58+
if (successful)
59+
{
60+
handle.InitHandle(ctx, op);
61+
}
62+
else
63+
{
64+
handle.SetHandleAsInvalid();
65+
}
66+
}
67+
return handle;
68+
}
69+
}
70+
71+
private sealed class CountAggregateOperation : AggregateOperation
72+
{
73+
internal override unsafe ChannelOperationHandle CreateHandle(Context ctx, Query q)
74+
{
75+
var handle = new ChannelOperationHandle();
76+
bool successful = false;
77+
tiledb_channel_operation_t* op = null;
78+
try
79+
{
80+
using var ctxHandle = ctx.Handle.Acquire();
81+
ctx.handle_error(Methods.tiledb_aggregate_count_get(ctxHandle, &op));
82+
successful = true;
83+
}
84+
finally
85+
{
86+
if (successful)
87+
{
88+
handle.InitHandle(ctx, op);
89+
}
90+
else
91+
{
92+
handle.SetHandleAsInvalid();
93+
}
94+
}
95+
return handle;
96+
}
97+
}
98+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
using System;
2+
using TileDB.Interop;
3+
4+
namespace TileDB.CSharp;
5+
6+
/// <summary>
7+
/// Represents an aggregate operator that can be applied over a query field.
8+
/// </summary>
9+
/// <remarks>
10+
/// This class abstracts the <c>tiledb_channel_operator_t</c> type of the TileDB C API.
11+
/// </remarks>
12+
public abstract class AggregateOperator
13+
{
14+
// Prevent inheriting the class outside of this assembly.
15+
private protected AggregateOperator() { }
16+
17+
internal abstract unsafe tiledb_channel_operator_t* GetHandle(tiledb_ctx_t* ctx);
18+
19+
/// <summary>
20+
/// Computes the sum of all values in the field.
21+
/// </summary>
22+
public static AggregateOperator Sum { get; } = new SimpleAggregateOperator(OperatorKind.Sum);
23+
24+
/// <summary>
25+
/// Computes the minimum value in the field.
26+
/// </summary>
27+
public static AggregateOperator Min { get; } = new SimpleAggregateOperator(OperatorKind.Min);
28+
29+
/// <summary>
30+
/// Computes the maximum value in the field.
31+
/// </summary>
32+
public static AggregateOperator Max { get; } = new SimpleAggregateOperator(OperatorKind.Max);
33+
34+
/// <summary>
35+
/// Computes the mean of all values in the field.
36+
/// </summary>
37+
public static AggregateOperator Mean { get; } = new SimpleAggregateOperator(OperatorKind.Mean);
38+
39+
/// <summary>
40+
/// Counts the number of null values in the field.
41+
/// </summary>
42+
public static AggregateOperator NullCount { get; } = new SimpleAggregateOperator(OperatorKind.NullCount);
43+
44+
private enum OperatorKind
45+
{
46+
Sum,
47+
Min,
48+
Max,
49+
Mean,
50+
NullCount
51+
}
52+
53+
private sealed class SimpleAggregateOperator : AggregateOperator
54+
{
55+
private readonly OperatorKind _kind;
56+
57+
public SimpleAggregateOperator(OperatorKind kind)
58+
{
59+
_kind = kind;
60+
}
61+
62+
internal override unsafe tiledb_channel_operator_t* GetHandle(tiledb_ctx_t* ctx)
63+
{
64+
tiledb_channel_operator_t* op;
65+
var ret = _kind switch
66+
{
67+
OperatorKind.Sum => Methods.tiledb_channel_operator_sum_get(ctx, &op),
68+
OperatorKind.Min => Methods.tiledb_channel_operator_min_get(ctx, &op),
69+
OperatorKind.Max => Methods.tiledb_channel_operator_max_get(ctx, &op),
70+
OperatorKind.Mean => Methods.tiledb_channel_operator_mean_get(ctx, &op),
71+
OperatorKind.NullCount => Methods.tiledb_channel_operator_null_count_get(ctx, &op),
72+
_ => throw new InvalidOperationException(),
73+
};
74+
ErrorHandling.ThrowOnError(ret);
75+
return op;
76+
}
77+
}
78+
}

sources/TileDB.CSharp/Array.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,34 @@ public void DeleteMetadata(string key)
737737
_metadata.DeleteMetadata(key);
738738
}
739739

740+
/// <summary>
741+
/// Deletes fragments from an array that fall within the given timestamp range.
742+
/// </summary>
743+
/// <param name="ctx">The <see cref="Context"/> to use.</param>
744+
/// <param name="uri">The URI to the array.</param>
745+
/// <param name="timestampStart">The start of the timestamp range, inclusive.</param>
746+
/// <param name="timestampEnd">The end of the timestamp range, inclusive.</param>
747+
public static void DeleteFragments(Context ctx, string uri, ulong timestampStart, ulong timestampEnd)
748+
{
749+
using var ms_uri = new MarshaledString(uri);
750+
using var ctxHandle = ctx.Handle.Acquire();
751+
ctx.handle_error(Methods.tiledb_array_delete_fragments_v2(ctxHandle, ms_uri, timestampStart, timestampEnd));
752+
}
753+
754+
/// <summary>
755+
/// Deletes fragments from an array that fall within the given timestamp range.
756+
/// </summary>
757+
/// <param name="ctx">The <see cref="Context"/> to use.</param>
758+
/// <param name="uri">The URI to the array.</param>
759+
/// <param name="fragmentUris">A list with the URIs of the fragments to delete.</param>
760+
public static void DeleteFragments(Context ctx, string uri, IReadOnlyList<string> fragmentUris)
761+
{
762+
using var ms_uri = new MarshaledString(uri);
763+
using var msc_fragmentUris = new MarshaledStringCollection(fragmentUris);
764+
using var ctxHandle = ctx.Handle.Acquire();
765+
ctx.handle_error(Methods.tiledb_array_delete_fragments_list(ctxHandle, ms_uri, (sbyte**)msc_fragmentUris.Strings, (nuint)msc_fragmentUris.Count));
766+
}
767+
740768
/// <summary>
741769
/// Gets metadata from the <see cref="Array"/>.
742770
/// </summary>

sources/TileDB.CSharp/ArraySchemaEvolution.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ public void AddEnumeration(Enumeration enumeration)
7676
_ctx.handle_error(Methods.tiledb_array_schema_evolution_add_enumeration(ctxHandle, handle, enumHandle));
7777
}
7878

79+
/// <summary>
80+
/// Adds an <see cref="Enumeration"/> to the <see cref="ArraySchemaEvolution"/>.
81+
/// </summary>
82+
/// <param name="enumeration">A fully constructed <see cref="Enumeration"/> that will be added to the schema.</param>
83+
/// <seealso cref="DropEnumeration"/>
84+
public void ExtendEnumeration(Enumeration enumeration)
85+
{
86+
using var ctxHandle = _ctx.Handle.Acquire();
87+
using var handle = _handle.Acquire();
88+
using var enumHandle = enumeration.Handle.Acquire();
89+
_ctx.handle_error(Methods.tiledb_array_schema_evolution_extend_enumeration(ctxHandle, handle, enumHandle));
90+
}
91+
7992
/// <summary>
8093
/// Drops an enumeration with the given name from the <see cref="ArraySchemaEvolution"/>.
8194
/// </summary>

0 commit comments

Comments
 (0)