|
4 | 4 | using System.Linq;
|
5 | 5 | using System.Text;
|
6 | 6 |
|
7 |
| -namespace TileDB.CSharp.Examples |
| 7 | +namespace TileDB.CSharp.Examples; |
| 8 | + |
| 9 | +[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")] |
| 10 | +[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")] |
| 11 | +internal static class ExampleDataframe |
8 | 12 | {
|
9 |
| - internal static class ExampleDataframe |
| 13 | + public static void Run() |
10 | 14 | {
|
11 |
| - public static void Run() |
| 15 | + using var ctx = new Context(); |
| 16 | + const string arrayUri = "dataframe_array"; |
| 17 | + if (Directory.Exists(arrayUri)) |
12 | 18 | {
|
13 |
| - using var ctx = new Context(); |
14 |
| - const string arrayUri = "dataframe_array"; |
15 |
| - if (Directory.Exists(arrayUri)) |
16 |
| - { |
17 |
| - Directory.Delete(arrayUri, true); |
18 |
| - } |
19 |
| - CreateArray(ctx, arrayUri); |
20 |
| - |
21 |
| - string[] names = { "Adam", "Bree", "Charles", "Dianna", "Evan", "Fiona", "Gabe", "Hannah", "Isidore", "Julia" }; |
22 |
| - 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), |
23 |
| - 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) }; |
24 |
| - Write(ctx, arrayUri, 0, names, dobs); |
25 |
| - |
26 |
| - foreach (var x in Read(ctx, arrayUri, 0, 9)) |
27 |
| - { |
28 |
| - Console.WriteLine($"ID: {x.Id}, Name: {x.Name}, Date of birth: {x.DateOfBirth:d}"); |
29 |
| - } |
| 19 | + Directory.Delete(arrayUri, true); |
30 | 20 | }
|
| 21 | + CreateArray(ctx, arrayUri); |
| 22 | + |
| 23 | + string[] names = ["Adam", "Bree", "Charles", "Dianna", "Evan", "Fiona", "Gabe", "Hannah", "Isidore", "Julia"]; |
| 24 | + DateTime[] dobs = [new DateTime(1990, 1, 1), |
| 25 | + new DateTime(1991, 2, 2), |
| 26 | + new DateTime(1992, 3, 3), |
| 27 | + new DateTime(1993, 4, 4), |
| 28 | + new DateTime(1994, 5, 5), |
| 29 | + new DateTime(1995, 6, 6), |
| 30 | + new DateTime(1996, 7, 7), |
| 31 | + new DateTime(1997, 8, 8), |
| 32 | + new DateTime(1998, 9, 9), |
| 33 | + new DateTime(1999, 10, 10)]; |
| 34 | + Write(ctx, arrayUri, 0, names, dobs); |
31 | 35 |
|
32 |
| - static void CreateArray(Context ctx, string uri) |
| 36 | + foreach (var x in Read(ctx, arrayUri, 0, 9)) |
33 | 37 | {
|
34 |
| - using var schema = new ArraySchema(ctx, ArrayType.Dense); |
35 |
| - using var domain = new Domain(ctx); |
36 |
| - using var dimension = Dimension.Create<ulong>(ctx, "id", 0, ulong.MaxValue - 1, 1); |
37 |
| - domain.AddDimension(dimension); |
38 |
| - schema.SetDomain(domain); |
39 |
| - using var attrName = new Attribute(ctx, "name", DataType.StringUtf8); |
40 |
| - attrName.SetCellValNum(Attribute.VariableSized); |
41 |
| - using var attrDob = new Attribute(ctx, "dob", DataType.DateTimeDay); |
42 |
| - schema.AddAttributes(attrName); |
43 |
| - schema.AddAttributes(attrDob); |
44 |
| - Array.Create(ctx, uri, schema); |
| 38 | + Console.WriteLine($"ID: {x.Id}, Name: {x.Name}, Date of birth: {x.DateOfBirth:d}"); |
45 | 39 | }
|
| 40 | + } |
46 | 41 |
|
47 |
| - static void Write(Context ctx, string uri, ulong idStart, string[] names, DateTime[] dobs) |
| 42 | + static void CreateArray(Context ctx, string uri) |
| 43 | + { |
| 44 | + using var schema = new ArraySchema(ctx, ArrayType.Dense); |
| 45 | + using var domain = new Domain(ctx); |
| 46 | + using var dimension = Dimension.Create<ulong>(ctx, "id", 0, ulong.MaxValue - 1, 1); |
| 47 | + domain.AddDimension(dimension); |
| 48 | + schema.SetDomain(domain); |
| 49 | + using var attrName = new Attribute(ctx, "name", DataType.StringUtf8); |
| 50 | + attrName.SetCellValNum(Attribute.VariableSized); |
| 51 | + using var attrDob = new Attribute(ctx, "dob", DataType.DateTimeDay); |
| 52 | + schema.AddAttributes(attrName); |
| 53 | + schema.AddAttributes(attrDob); |
| 54 | + Array.Create(ctx, uri, schema); |
| 55 | + } |
| 56 | + |
| 57 | + static void Write(Context ctx, string uri, ulong idStart, string[] names, DateTime[] dobs) |
| 58 | + { |
| 59 | + using var array = new Array(ctx, uri); |
| 60 | + array.Open(QueryType.Write); |
| 61 | + using var query = new Query(array); |
| 62 | + query.SetLayout(LayoutType.RowMajor); |
| 63 | + using var subarray = new Subarray(array); |
| 64 | + subarray.AddRange(0, idStart, idStart + (ulong)names.Length - 1); |
| 65 | + query.SetSubarray(subarray); |
| 66 | + var (nameData, nameOffsets) = CoreUtil.PackStringArray(names); |
| 67 | + query.SetDataBuffer("name", nameData); |
| 68 | + query.SetOffsetsBuffer("name", nameOffsets); |
| 69 | + query.SetDataBuffer("dob", dobs.Select(x => (long)(x - new DateTime(1970, 1, 1)).Days).ToArray()); |
| 70 | + query.Submit(); |
| 71 | + } |
| 72 | + |
| 73 | + static IEnumerable<(ulong Id, string Name, DateTime DateOfBirth)> Read(Context ctx, string uri, ulong idStart, ulong count) |
| 74 | + { |
| 75 | + using var array = new Array(ctx, uri); |
| 76 | + array.Open(QueryType.Read); |
| 77 | + (ulong minElement, ulong maxElement, bool isEmpty) = array.NonEmptyDomain<ulong>("id"); |
| 78 | + if (isEmpty) |
48 | 79 | {
|
49 |
| - using var array = new Array(ctx, uri); |
50 |
| - array.Open(QueryType.Write); |
51 |
| - using var query = new Query(array); |
52 |
| - query.SetLayout(LayoutType.RowMajor); |
53 |
| - using var subarray = new Subarray(array); |
54 |
| - subarray.AddRange(0, idStart, idStart + (ulong)names.Length - 1); |
55 |
| - query.SetSubarray(subarray); |
56 |
| - var (nameData, nameOffsets) = CoreUtil.PackStringArray(names); |
57 |
| - query.SetDataBuffer("name", nameData); |
58 |
| - query.SetOffsetsBuffer("name", nameOffsets); |
59 |
| - query.SetDataBuffer("dob", dobs.Select(x => (long)(x - new DateTime(1970, 1, 1)).Days).ToArray()); |
60 |
| - query.Submit(); |
| 80 | + yield break; |
61 | 81 | }
|
| 82 | + idStart = Math.Max(idStart, minElement); |
| 83 | + ulong idEnd = Math.Min(idStart + count, maxElement); |
| 84 | + using var query = new Query(array); |
| 85 | + query.SetLayout(LayoutType.RowMajor); |
| 86 | + using var subarray = new Subarray(array); |
| 87 | + subarray.AddRange(0, idStart, idEnd); |
| 88 | + query.SetSubarray(subarray); |
62 | 89 |
|
63 |
| - static IEnumerable<(ulong Id, string Name, DateTime DateOfBirth)> Read(Context ctx, string uri, ulong idStart, ulong count) |
| 90 | + byte[] nameData = new byte[512]; |
| 91 | + ulong[] nameOffsets = new ulong[16]; |
| 92 | + long[] dobs = new long[16]; |
| 93 | + query.SetDataBuffer("name", nameData); |
| 94 | + query.SetOffsetsBuffer("name", nameOffsets); |
| 95 | + query.SetDataBuffer("dob", dobs); |
| 96 | + ulong currentId = idStart; |
| 97 | + // Loop until the query completes or fails. |
| 98 | + while (query.Status() is not (QueryStatus.Failed or QueryStatus.Completed)) |
64 | 99 | {
|
65 |
| - using var array = new Array(ctx, uri); |
66 |
| - array.Open(QueryType.Read); |
67 |
| - (ulong minElement, ulong maxElement, bool isEmpty) = array.NonEmptyDomain<ulong>("id"); |
68 |
| - if (isEmpty) |
| 100 | + query.Submit(); |
| 101 | + var dataCount = (int)query.GetResultDataBytes("name"); |
| 102 | + // The count of offsets for the variable-length attribute "name" |
| 103 | + // essentially tells us how many cells were returned. |
| 104 | + var offsetCount = (int)query.GetResultOffsets("name"); |
| 105 | + // If zero cells were returned, check if the reason was that the |
| 106 | + // buffers were too small, resize them, and try again. |
| 107 | + if (offsetCount == 0 && query.GetStatusDetails().Reason == QueryStatusDetailsReason.UserBufferSize) |
69 | 108 | {
|
70 |
| - yield break; |
| 109 | + System.Array.Resize(ref nameData, nameData.Length * 2); |
| 110 | + System.Array.Resize(ref nameOffsets, nameOffsets.Length * 2); |
| 111 | + System.Array.Resize(ref dobs, dobs.Length * 2); |
| 112 | + query.SetDataBuffer("name", nameData); |
| 113 | + query.SetOffsetsBuffer("name", nameOffsets); |
| 114 | + query.SetDataBuffer("dob", dobs); |
| 115 | + continue; |
71 | 116 | }
|
72 |
| - idStart = Math.Max(idStart, minElement); |
73 |
| - ulong idEnd = Math.Min(idStart + count, maxElement); |
74 |
| - using var query = new Query(array); |
75 |
| - query.SetLayout(LayoutType.RowMajor); |
76 |
| - using var subarray = new Subarray(array); |
77 |
| - subarray.AddRange(0, idStart, idEnd); |
78 |
| - query.SetSubarray(subarray); |
79 |
| - |
80 |
| - byte[] nameData = new byte[512]; |
81 |
| - ulong[] nameOffsets = new ulong[16]; |
82 |
| - long[] dobs = new long[16]; |
83 |
| - query.SetDataBuffer("name", nameData); |
84 |
| - query.SetOffsetsBuffer("name", nameOffsets); |
85 |
| - query.SetDataBuffer("dob", dobs); |
86 |
| - ulong currentId = idStart; |
87 |
| - // Loop until the query completes or fails. |
88 |
| - while (query.Status() is not (QueryStatus.Failed or QueryStatus.Completed)) |
| 117 | + for (int i = 0; i < offsetCount; i++) |
89 | 118 | {
|
90 |
| - query.Submit(); |
91 |
| - var dataCount = (int)query.GetResultDataBytes("name"); |
92 |
| - // The count of offsets for the variable-length attribute "name" |
93 |
| - // essentially tells us how many cells were returned. |
94 |
| - var offsetCount = (int)query.GetResultOffsets("name"); |
95 |
| - // If zero cells were returned, check if the reason was that the |
96 |
| - // buffers were too small, resize them, and try again. |
97 |
| - if (offsetCount == 0 && query.GetStatusDetails().Reason == QueryStatusDetailsReason.UserBufferSize) |
98 |
| - { |
99 |
| - System.Array.Resize(ref nameData, nameData.Length * 2); |
100 |
| - System.Array.Resize(ref nameOffsets, nameOffsets.Length * 2); |
101 |
| - System.Array.Resize(ref dobs, dobs.Length * 2); |
102 |
| - query.SetDataBuffer("name", nameData); |
103 |
| - query.SetOffsetsBuffer("name", nameOffsets); |
104 |
| - query.SetDataBuffer("dob", dobs); |
105 |
| - continue; |
106 |
| - } |
107 |
| - for (int i = 0; i < offsetCount; i++) |
108 |
| - { |
109 |
| - var offset = (int)nameOffsets[i]; |
110 |
| - var offsetOfNext = i < offsetCount - 1 ? (int)nameOffsets[i + 1] : dataCount; |
111 |
| - var name = Encoding.ASCII.GetString(nameData.AsSpan(offset, offsetOfNext - offset)); |
112 |
| - var dob = new DateTime(1970, 1, 1).AddDays(dobs[i]); |
113 |
| - yield return (currentId++, name, dob); |
114 |
| - } |
| 119 | + var offset = (int)nameOffsets[i]; |
| 120 | + var offsetOfNext = i < offsetCount - 1 ? (int)nameOffsets[i + 1] : dataCount; |
| 121 | + var name = Encoding.ASCII.GetString(nameData.AsSpan(offset, offsetOfNext - offset)); |
| 122 | + var dob = new DateTime(1970, 1, 1).AddDays(dobs[i]); |
| 123 | + yield return (currentId++, name, dob); |
115 | 124 | }
|
116 | 125 | }
|
117 | 126 | }
|
|
0 commit comments