Skip to content

Commit

Permalink
Update to the .NET 8 SDK and use some new C# features. (#362)
Browse files Browse the repository at this point in the history
* Update SDK to .NET 8.

* Use collection expressions.

* Suppress two Sonar warnings in an example.

* Use file-scoped namespaces.
  • Loading branch information
teo-tsirpanis authored Jan 10, 2024
1 parent 404bf86 commit 8526f4a
Show file tree
Hide file tree
Showing 99 changed files with 14,032 additions and 14,119 deletions.
129 changes: 64 additions & 65 deletions examples/TileDB.CSharp.Example/ExampleAggregateQuery.cs
Original file line number Diff line number Diff line change
@@ -1,84 +1,83 @@
using System;
using System.IO;

namespace TileDB.CSharp.Examples
namespace TileDB.CSharp.Examples;

static class ExampleAggregateQuery
{
static class ExampleAggregateQuery
{
private static readonly string ArrayPath = ExampleUtil.MakeExamplePath("aggregate-array");
private static readonly Context Ctx = Context.GetDefault();
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();
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);
}
Array.Create(Ctx, ArrayPath, array_schema);
}

private static void WriteArray()
private static void WriteArray()
{
using (var array_write = new Array(Ctx, ArrayPath))
{
using (var array_write = new Array(Ctx, ArrayPath))
array_write.Open(QueryType.Write);
using (var query_write = new Query(array_write))
{
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();
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();
}
private static void ReadArray()
{
ulong[] count = [0];
long[] sum = [0];

Console.WriteLine($"Count: {count[0]}");
Console.WriteLine($"Sum: {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();
}

public static void Run()
{
if (Directory.Exists(ArrayPath))
{
Directory.Delete(ArrayPath, true);
}
Console.WriteLine($"Count: {count[0]}");
Console.WriteLine($"Sum: {sum[0]}");
}

CreateArray();
WriteArray();
ReadArray();
public static void Run()
{
if (Directory.Exists(ArrayPath))
{
Directory.Delete(ArrayPath, true);
}

CreateArray();
WriteArray();
ReadArray();
}
}
195 changes: 102 additions & 93 deletions examples/TileDB.CSharp.Example/ExampleDataframe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,114 +4,123 @@
using System.Linq;
using System.Text;

namespace TileDB.CSharp.Examples
namespace TileDB.CSharp.Examples;

[System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S6562:Always set the \"DateTimeKind\" when creating new \"DateTime\" instances", Justification = "Excessive for this example; the dates' kind will not be converted")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Minor Code Smell", "S6588:Use the \"UnixEpoch\" field instead of creating \"DateTime\" instances that point to the beginning of the Unix epoch", Justification = "DateTime.UnixEpoch is unavailable in .NET 5")]
internal static class ExampleDataframe
{
internal static class ExampleDataframe
public static void Run()
{
public static void Run()
using var ctx = new Context();
const string arrayUri = "dataframe_array";
if (Directory.Exists(arrayUri))
{
using var ctx = new Context();
const string arrayUri = "dataframe_array";
if (Directory.Exists(arrayUri))
{
Directory.Delete(arrayUri, true);
}
CreateArray(ctx, arrayUri);

string[] names = { "Adam", "Bree", "Charles", "Dianna", "Evan", "Fiona", "Gabe", "Hannah", "Isidore", "Julia" };
DateTime[] dobs = { new DateTime(1990, 1, 1), new DateTime(1991, 2, 2), new DateTime(1992, 3, 3), new DateTime(1993, 4, 4), new DateTime(1994, 5, 5),
new DateTime(1995, 6, 6), new DateTime(1996, 7, 7), new DateTime(1997, 8, 8), new DateTime(1998, 9, 9), new DateTime(1999, 10, 10) };
Write(ctx, arrayUri, 0, names, dobs);

foreach (var x in Read(ctx, arrayUri, 0, 9))
{
Console.WriteLine($"ID: {x.Id}, Name: {x.Name}, Date of birth: {x.DateOfBirth:d}");
}
Directory.Delete(arrayUri, true);
}
CreateArray(ctx, arrayUri);

string[] names = ["Adam", "Bree", "Charles", "Dianna", "Evan", "Fiona", "Gabe", "Hannah", "Isidore", "Julia"];
DateTime[] dobs = [new DateTime(1990, 1, 1),
new DateTime(1991, 2, 2),
new DateTime(1992, 3, 3),
new DateTime(1993, 4, 4),
new DateTime(1994, 5, 5),
new DateTime(1995, 6, 6),
new DateTime(1996, 7, 7),
new DateTime(1997, 8, 8),
new DateTime(1998, 9, 9),
new DateTime(1999, 10, 10)];
Write(ctx, arrayUri, 0, names, dobs);

static void CreateArray(Context ctx, string uri)
foreach (var x in Read(ctx, arrayUri, 0, 9))
{
using var schema = new ArraySchema(ctx, ArrayType.Dense);
using var domain = new Domain(ctx);
using var dimension = Dimension.Create<ulong>(ctx, "id", 0, ulong.MaxValue - 1, 1);
domain.AddDimension(dimension);
schema.SetDomain(domain);
using var attrName = new Attribute(ctx, "name", DataType.StringUtf8);
attrName.SetCellValNum(Attribute.VariableSized);
using var attrDob = new Attribute(ctx, "dob", DataType.DateTimeDay);
schema.AddAttributes(attrName);
schema.AddAttributes(attrDob);
Array.Create(ctx, uri, schema);
Console.WriteLine($"ID: {x.Id}, Name: {x.Name}, Date of birth: {x.DateOfBirth:d}");
}
}

static void Write(Context ctx, string uri, ulong idStart, string[] names, DateTime[] dobs)
static void CreateArray(Context ctx, string uri)
{
using var schema = new ArraySchema(ctx, ArrayType.Dense);
using var domain = new Domain(ctx);
using var dimension = Dimension.Create<ulong>(ctx, "id", 0, ulong.MaxValue - 1, 1);
domain.AddDimension(dimension);
schema.SetDomain(domain);
using var attrName = new Attribute(ctx, "name", DataType.StringUtf8);
attrName.SetCellValNum(Attribute.VariableSized);
using var attrDob = new Attribute(ctx, "dob", DataType.DateTimeDay);
schema.AddAttributes(attrName);
schema.AddAttributes(attrDob);
Array.Create(ctx, uri, schema);
}

static void Write(Context ctx, string uri, ulong idStart, string[] names, DateTime[] dobs)
{
using var array = new Array(ctx, uri);
array.Open(QueryType.Write);
using var query = new Query(array);
query.SetLayout(LayoutType.RowMajor);
using var subarray = new Subarray(array);
subarray.AddRange(0, idStart, idStart + (ulong)names.Length - 1);
query.SetSubarray(subarray);
var (nameData, nameOffsets) = CoreUtil.PackStringArray(names);
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs.Select(x => (long)(x - new DateTime(1970, 1, 1)).Days).ToArray());
query.Submit();
}

static IEnumerable<(ulong Id, string Name, DateTime DateOfBirth)> Read(Context ctx, string uri, ulong idStart, ulong count)
{
using var array = new Array(ctx, uri);
array.Open(QueryType.Read);
(ulong minElement, ulong maxElement, bool isEmpty) = array.NonEmptyDomain<ulong>("id");
if (isEmpty)
{
using var array = new Array(ctx, uri);
array.Open(QueryType.Write);
using var query = new Query(array);
query.SetLayout(LayoutType.RowMajor);
using var subarray = new Subarray(array);
subarray.AddRange(0, idStart, idStart + (ulong)names.Length - 1);
query.SetSubarray(subarray);
var (nameData, nameOffsets) = CoreUtil.PackStringArray(names);
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs.Select(x => (long)(x - new DateTime(1970, 1, 1)).Days).ToArray());
query.Submit();
yield break;
}
idStart = Math.Max(idStart, minElement);
ulong idEnd = Math.Min(idStart + count, maxElement);
using var query = new Query(array);
query.SetLayout(LayoutType.RowMajor);
using var subarray = new Subarray(array);
subarray.AddRange(0, idStart, idEnd);
query.SetSubarray(subarray);

static IEnumerable<(ulong Id, string Name, DateTime DateOfBirth)> Read(Context ctx, string uri, ulong idStart, ulong count)
byte[] nameData = new byte[512];
ulong[] nameOffsets = new ulong[16];
long[] dobs = new long[16];
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs);
ulong currentId = idStart;
// Loop until the query completes or fails.
while (query.Status() is not (QueryStatus.Failed or QueryStatus.Completed))
{
using var array = new Array(ctx, uri);
array.Open(QueryType.Read);
(ulong minElement, ulong maxElement, bool isEmpty) = array.NonEmptyDomain<ulong>("id");
if (isEmpty)
query.Submit();
var dataCount = (int)query.GetResultDataBytes("name");
// The count of offsets for the variable-length attribute "name"
// essentially tells us how many cells were returned.
var offsetCount = (int)query.GetResultOffsets("name");
// If zero cells were returned, check if the reason was that the
// buffers were too small, resize them, and try again.
if (offsetCount == 0 && query.GetStatusDetails().Reason == QueryStatusDetailsReason.UserBufferSize)
{
yield break;
System.Array.Resize(ref nameData, nameData.Length * 2);
System.Array.Resize(ref nameOffsets, nameOffsets.Length * 2);
System.Array.Resize(ref dobs, dobs.Length * 2);
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs);
continue;
}
idStart = Math.Max(idStart, minElement);
ulong idEnd = Math.Min(idStart + count, maxElement);
using var query = new Query(array);
query.SetLayout(LayoutType.RowMajor);
using var subarray = new Subarray(array);
subarray.AddRange(0, idStart, idEnd);
query.SetSubarray(subarray);

byte[] nameData = new byte[512];
ulong[] nameOffsets = new ulong[16];
long[] dobs = new long[16];
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs);
ulong currentId = idStart;
// Loop until the query completes or fails.
while (query.Status() is not (QueryStatus.Failed or QueryStatus.Completed))
for (int i = 0; i < offsetCount; i++)
{
query.Submit();
var dataCount = (int)query.GetResultDataBytes("name");
// The count of offsets for the variable-length attribute "name"
// essentially tells us how many cells were returned.
var offsetCount = (int)query.GetResultOffsets("name");
// If zero cells were returned, check if the reason was that the
// buffers were too small, resize them, and try again.
if (offsetCount == 0 && query.GetStatusDetails().Reason == QueryStatusDetailsReason.UserBufferSize)
{
System.Array.Resize(ref nameData, nameData.Length * 2);
System.Array.Resize(ref nameOffsets, nameOffsets.Length * 2);
System.Array.Resize(ref dobs, dobs.Length * 2);
query.SetDataBuffer("name", nameData);
query.SetOffsetsBuffer("name", nameOffsets);
query.SetDataBuffer("dob", dobs);
continue;
}
for (int i = 0; i < offsetCount; i++)
{
var offset = (int)nameOffsets[i];
var offsetOfNext = i < offsetCount - 1 ? (int)nameOffsets[i + 1] : dataCount;
var name = Encoding.ASCII.GetString(nameData.AsSpan(offset, offsetOfNext - offset));
var dob = new DateTime(1970, 1, 1).AddDays(dobs[i]);
yield return (currentId++, name, dob);
}
var offset = (int)nameOffsets[i];
var offsetOfNext = i < offsetCount - 1 ? (int)nameOffsets[i + 1] : dataCount;
var name = Encoding.ASCII.GetString(nameData.AsSpan(offset, offsetOfNext - offset));
var dob = new DateTime(1970, 1, 1).AddDays(dobs[i]);
yield return (currentId++, name, dob);
}
}
}
Expand Down
Loading

0 comments on commit 8526f4a

Please sign in to comment.