]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/csharp/src/Apache.Arrow/Arrays/FixedSizeBinaryArray.cs
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / csharp / src / Apache.Arrow / Arrays / FixedSizeBinaryArray.cs
CommitLineData
1d09f67e
TL
1// Licensed to the Apache Software Foundation (ASF) under one or more
2// contributor license agreements. See the NOTICE file distributed with
3// this work for additional information regarding copyright ownership.
4// The ASF licenses this file to You under the Apache License, Version 2.0
5// (the "License"); you may not use this file except in compliance with
6// the License. You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16using System;
17using System.Collections.Generic;
18using Apache.Arrow.Memory;
19using Apache.Arrow.Types;
20
21namespace Apache.Arrow.Arrays
22{
23 public class FixedSizeBinaryArray : Array
24 {
25 public FixedSizeBinaryArray(ArrayData data)
26 : base(data)
27 {
28 data.EnsureDataType(ArrowTypeId.FixedSizedBinary);
29 data.EnsureBufferCount(2);
30 }
31
32 public FixedSizeBinaryArray(ArrowTypeId typeId, ArrayData data)
33 : base(data)
34 {
35 data.EnsureDataType(typeId);
36 data.EnsureBufferCount(2);
37 }
38
39 public override void Accept(IArrowArrayVisitor visitor) => Accept(this, visitor);
40
41 public ArrowBuffer ValueBuffer => Data.Buffers[1];
42
43 /// <summary>
44 /// Get the collection of bytes, as a read-only span, at a given index in the array.
45 /// </summary>
46 /// <remarks>
47 /// Note that this method cannot reliably identify null values, which are indistinguishable from empty byte
48 /// collection values when seen in the context of this method's return type of <see cref="ReadOnlySpan{Byte}"/>.
49 /// Use the <see cref="Array.IsNull"/> method instead to reliably determine null values.
50 /// </remarks>
51 /// <param name="index">Index at which to get bytes.</param>
52 /// <returns>Returns a <see cref="ReadOnlySpan{Byte}"/> object.</returns>
53 /// <exception cref="ArgumentOutOfRangeException">If the index is negative or beyond the length of the array.
54 /// </exception>
55 public ReadOnlySpan<byte> GetBytes(int index)
56 {
57 if (index < 0 || index >= Length)
58 {
59 throw new ArgumentOutOfRangeException(nameof(index));
60 }
61
62 if (IsNull(index))
63 {
64 // Note that `return null;` is valid syntax, but would be misleading as `null` in the context of a span
65 // is actually returned as an empty span.
66 return ReadOnlySpan<byte>.Empty;
67 }
68
69 int size = ((FixedSizeBinaryType)Data.DataType).ByteWidth;
70 return ValueBuffer.Span.Slice(index * size, size);
71 }
72
73 public abstract class BuilderBase<TArray, TBuilder> : IArrowArrayBuilder<byte[], TArray, TBuilder>
74 where TArray : IArrowArray
75 where TBuilder : class, IArrowArrayBuilder<byte[], TArray, TBuilder>
76 {
77 protected IArrowType DataType { get; }
78 protected TBuilder Instance => this as TBuilder;
79 protected int ByteWidth { get; }
80 protected ArrowBuffer.Builder<byte> ValueBuffer { get; }
81 protected ArrowBuffer.BitmapBuilder ValidityBuffer { get; }
82 public int Length => ValueBuffer.Length / ByteWidth;
83 protected int NullCount => this.ValidityBuffer.UnsetBitCount;
84 protected abstract TArray Build(ArrayData data);
85
86 protected BuilderBase(IArrowType dataType, int byteWidth)
87 {
88 DataType = dataType;
89 ByteWidth = byteWidth;
90 ValueBuffer = new ArrowBuffer.Builder<byte>();
91 ValidityBuffer = new ArrowBuffer.BitmapBuilder();
92 }
93
94 public TArray Build(MemoryAllocator allocator = default)
95 {
96 var bufs = new[]
97 {
98 NullCount > 0 ? ValidityBuffer.Build(allocator) : ArrowBuffer.Empty,
99 ValueBuffer.Build(ByteWidth, allocator),
100 };
101 var data = new ArrayData(
102 DataType,
103 Length,
104 NullCount,
105 0,
106 bufs);
107
108 return Build(data);
109 }
110
111 public TBuilder Reserve(int capacity)
112 {
113 ValueBuffer.Reserve(capacity * ByteWidth);
114 ValidityBuffer.Reserve(capacity + 1);
115 return Instance;
116 }
117
118 public TBuilder Resize(int length)
119 {
120 ValueBuffer.Resize(length * ByteWidth);
121 ValidityBuffer.Resize(length + 1);
122 return Instance;
123 }
124
125 public TBuilder Clear() {
126
127 ValueBuffer.Clear();
128 ValidityBuffer.Clear();
129
130 return Instance;
131 }
132
133 public TBuilder Append(byte[] value)
134 {
135 if(value.Length % ByteWidth != 0)
136 throw new ArgumentOutOfRangeException("Bytes of length: " + value.Length + " do not conform to the fixed size: " + ByteWidth);
137 return Append(value.AsSpan());
138 }
139 public TBuilder Append(ReadOnlySpan<byte[]> span)
140 {
141 foreach (var b in span)
142 {
143 Append(b);
144 }
145
146 return Instance;
147 }
148
149 public TBuilder AppendRange(IEnumerable<byte[]> values)
150 {
151 if (values == null)
152 {
153 throw new ArgumentNullException(nameof(values));
154 }
155
156 foreach (byte[] b in values)
157 {
158 Append(b);
159 }
160
161 return Instance;
162 }
163
164 public TBuilder Append(ReadOnlySpan<byte> span)
165 {
166 ValueBuffer.Append(span);
167 ValidityBuffer.Append(true);
168 return Instance;
169 }
170
171 public TBuilder AppendNull()
172 {
173 ValueBuffer.Append(new byte[ByteWidth]);
174 ValidityBuffer.Append(false);
175 return Instance;
176 }
177
178 public TBuilder Swap(int i, int j)
179 {
180 int iStart = i * ByteWidth;
181 int jStart = j * ByteWidth;
182 byte[] iBytes = ValueBuffer.Span.Slice(iStart, ByteWidth).ToArray();
183 Span<byte> jBytes = ValueBuffer.Span.Slice(jStart, ByteWidth);
184
185 for (int m = 0; m < ByteWidth; m++)
186 {
187 ValueBuffer.Span[iStart + m] = jBytes[m];
188 ValueBuffer.Span[jStart + m] = iBytes[m];
189 }
190
191 ValidityBuffer.Swap(i, j);
192 return Instance;
193 }
194
195 public TBuilder Set(int index, byte[] value)
196 {
197 return Set(index, value.AsSpan());
198 }
199
200 public TBuilder Set(int index, ReadOnlySpan<byte> value)
201 {
202 int startIndex = index * ByteWidth;
203 for (int i = 0; i < ByteWidth; i++)
204 {
205 ValueBuffer.Span[startIndex + i] = value[i];
206 }
207
208 ValidityBuffer.Set(index, true);
209 return Instance;
210 }
211
212 public TBuilder SetNull(int index)
213 {
214 int startIndex = index * ByteWidth;
215 for (int i = 0; i < ByteWidth; i++)
216 {
217 ValueBuffer.Span[startIndex + i] = 0;
218 }
219
220 ValidityBuffer.Set(index, false);
221 return Instance;
222 }
223
224 }
225 }
226}