Skip to content

Commit 19cd3b3

Browse files
Merge pull request #22 from willtemperley/main
Use concrete buffer types to build arrays. Contain generics in typealiases.
2 parents aab53ee + 000b4e7 commit 19cd3b3

File tree

6 files changed

+176
-61
lines changed

6 files changed

+176
-61
lines changed

Sources/Arrow/Array/Array.swift

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,18 @@ public struct ArrowArrayBoolean: ArrowArrayProtocol {
7070
}
7171

7272
/// An Arrow array of fixed-width types.
73-
struct ArrowArrayFixed<T>: ArrowArrayProtocol where T: Numeric {
74-
typealias ItemType = T
73+
struct ArrowArrayFixed<Element, ValueBuffer>: ArrowArrayProtocol
74+
where
75+
Element: Numeric,
76+
ValueBuffer: FixedWidthBufferProtocol<Element>
77+
{
78+
typealias ItemType = Element
7579
let offset: Int
7680
let length: Int
7781
let nullBuffer: NullBuffer
78-
let valueBuffer: FixedWidthBuffer<T>
82+
let valueBuffer: ValueBuffer
7983

80-
subscript(index: Int) -> T? {
84+
subscript(index: Int) -> Element? {
8185
precondition(index >= 0 && index < length, "Invalid index.")
8286
let offsetIndex = self.offset + index
8387
if !self.nullBuffer.isSet(offsetIndex) {
@@ -86,7 +90,7 @@ struct ArrowArrayFixed<T>: ArrowArrayProtocol where T: Numeric {
8690
return valueBuffer[offsetIndex]
8791
}
8892

89-
func slice(offset: Int, length: Int) -> ArrowArrayFixed<T> {
93+
func slice(offset: Int, length: Int) -> Self {
9094
.init(
9195
offset: offset,
9296
length: length,
@@ -97,22 +101,26 @@ struct ArrowArrayFixed<T>: ArrowArrayProtocol where T: Numeric {
97101
}
98102

99103
/// An Arrow array of variable-length types.
100-
public struct ArrowArrayVariable<T>: ArrowArrayProtocol
101-
where T: VariableLength {
102-
public typealias ItemType = T
104+
public struct ArrowArrayVariable<Element, OffsetsBuffer, ValueBuffer>:
105+
ArrowArrayProtocol
106+
where
107+
Element: VariableLength,
108+
OffsetsBuffer: FixedWidthBufferProtocol<Int32>,
109+
ValueBuffer: VariableLengthBufferProtocol<Element>
110+
{
111+
public typealias ItemType = Element
103112
public let offset: Int
104113
public let length: Int
105114
let nullBuffer: NullBuffer
106-
let offsetsBuffer: any FixedWidthBufferProtocol<Int32>
107-
let valueBuffer: any VariableLengthBufferProtocol<T>
115+
let offsetsBuffer: OffsetsBuffer
116+
let valueBuffer: ValueBuffer
108117

109118
public init(
110119
offset: Int,
111120
length: Int,
112121
nullBuffer: NullBuffer,
113-
offsetsBuffer:
114-
any FixedWidthBufferProtocol<Int32>,
115-
valueBuffer: any VariableLengthBufferProtocol<T>
122+
offsetsBuffer: OffsetsBuffer,
123+
valueBuffer: ValueBuffer
116124
) {
117125
self.offset = offset
118126
self.length = length
@@ -121,7 +129,7 @@ where T: VariableLength {
121129
self.valueBuffer = valueBuffer
122130
}
123131

124-
public subscript(index: Int) -> T? {
132+
public subscript(index: Int) -> Element? {
125133

126134
let offsetIndex = self.offset + index
127135

@@ -147,14 +155,14 @@ where T: VariableLength {
147155
}
148156
}
149157

150-
public typealias ArrowArrayUtf8 = ArrowArrayVariable<String>
151-
public typealias ArrowArrayBinary = ArrowArrayVariable<Data>
152-
153158
/// An Arrow array of `Date`s with a resolution of 1 day.
154-
struct ArrowArrayDate32: ArrowArrayProtocol {
159+
struct ArrowArrayDate32<ValueBuffer>: ArrowArrayProtocol
160+
where
161+
ValueBuffer: FixedWidthBufferProtocol<Int32>
162+
{
155163
typealias ItemType = Date
156164

157-
let array: ArrowArrayFixed<Date32>
165+
let array: ArrowArrayFixed<Date32, ValueBuffer>
158166

159167
var offset: Int {
160168
array.offset
@@ -182,10 +190,13 @@ struct ArrowArrayDate32: ArrowArrayProtocol {
182190
}
183191

184192
/// An Arrow array of `Date`s with a resolution of 1 second.
185-
struct ArrowArrayDate64: ArrowArrayProtocol {
193+
struct ArrowArrayDate64<ValueBuffer>: ArrowArrayProtocol
194+
where
195+
ValueBuffer: FixedWidthBufferProtocol<Int64>
196+
{
186197
typealias ItemType = Date
187198

188-
let array: ArrowArrayFixed<Date64>
199+
let array: ArrowArrayFixed<Date64, ValueBuffer>
189200

190201
var offset: Int {
191202
array.offset
@@ -212,17 +223,20 @@ struct ArrowArrayDate64: ArrowArrayProtocol {
212223
}
213224
}
214225

215-
struct ArrowListArray<T>: ArrowArrayProtocol where T: ArrowArrayProtocol {
216-
217-
typealias ItemType = T
226+
/// An Arrow list array which may be nested arbitrarily.
227+
struct ArrowListArray<Element>: ArrowArrayProtocol
228+
where
229+
Element: ArrowArrayProtocol
230+
{
231+
typealias ItemType = Element
218232

219233
let offset: Int
220234
let length: Int
221235
let nullBuffer: NullBuffer
222236
let offsetsBuffer: FixedWidthBuffer<Int32>
223-
let values: T
237+
let values: Element
224238

225-
subscript(index: Int) -> T? {
239+
subscript(index: Int) -> Element? {
226240
precondition(index >= 0 && index < length, "Invalid index.")
227241
let offsetIndex = self.offset + index
228242
if !self.nullBuffer.isSet(offsetIndex) {

Sources/Arrow/Array/Builder.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class ArrayBuilderBoolean: AnyArrayBuilder {
7676
/// A builder for Arrow arrays holding fixed-width types.
7777
class ArrayBuilderFixedWidth<T: Numeric>: AnyArrayBuilder {
7878

79-
typealias ArrayType = ArrowArrayFixed<T>
79+
typealias ArrayType = ArrowArrayFixed<T, FixedWidthBuffer<T>>
8080

8181
var length: Int
8282
let nullBuilder: NullBufferBuilder
@@ -114,23 +114,25 @@ class ArrayBuilderFixedWidth<T: Numeric>: AnyArrayBuilder {
114114
}
115115

116116
/// A builder for Arrow arrays holding variable length types.
117-
class ArrayBuilderVariable<T: VariableLength>: AnyArrayBuilder {
118-
typealias ArrayType = ArrowArrayVariable<T>
117+
class ArrayBuilderVariable<Element: VariableLength>: AnyArrayBuilder {
118+
typealias ArrayType = ArrowArrayVariable<
119+
Element, FixedWidthBuffer<Int32>, VariableLengthTypeBuffer<Element>
120+
>
119121

120122
var length: Int
121123
let nullBuilder: NullBufferBuilder
122124
let offsetsBuilder: FixedWidthBufferBuilder<Int32>
123-
let valueBuilder: VariableLengthTypeBufferBuilder<T>
125+
let valueBuilder: VariableLengthTypeBufferBuilder<Element>
124126

125127
init() {
126128
self.length = 0
127129
self.nullBuilder = NullBufferBuilder()
128130
self.offsetsBuilder = FixedWidthBufferBuilder<Int32>()
129-
self.valueBuilder = VariableLengthTypeBufferBuilder<T>()
131+
self.valueBuilder = VariableLengthTypeBufferBuilder<Element>()
130132
self.offsetsBuilder.append(Int32.zero)
131133
}
132134

133-
public func append(_ value: T) {
135+
public func append(_ value: Element) {
134136
length += 1
135137
nullBuilder.appendValid(true)
136138
let data = value.data
@@ -176,7 +178,7 @@ typealias ArrayBuilderBinary = ArrayBuilderVariable<Data>
176178

177179
/// A builder for Arrow arrays holding `Date`s with a resolution of one day.
178180
struct ArrayBuilderDate32: AnyArrayBuilder {
179-
typealias ArrayType = ArrowArrayDate32
181+
typealias ArrayType = ArrowArrayDate32<FixedWidthBuffer<Date32>>
180182

181183
let builder: ArrayBuilderFixedWidth<Date32> = .init()
182184

@@ -200,7 +202,7 @@ struct ArrayBuilderDate32: AnyArrayBuilder {
200202

201203
/// A builder for Arrow arrays holding `Date`s with a resolution of one day.
202204
struct ArrayBuilderDate64: AnyArrayBuilder {
203-
typealias ArrayType = ArrowArrayDate64
205+
typealias ArrayType = ArrowArrayDate64<FixedWidthBuffer<Date64>>
204206

205207
let builder: ArrayBuilderFixedWidth<Date64> = .init()
206208

Sources/Arrow/Buffer/NullBuffer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ public struct AllNullBuffer: NullBuffer {
4848

4949
/// A bit-packed buffer used to represent nulls and booleans in Arrow arrays.
5050
final class BitPackedNullBuffer: NullBuffer {
51-
var length: Int
52-
var capacity: Int
51+
let length: Int
52+
let capacity: Int
5353
let ownsMemory: Bool
54-
var buffer: UnsafePointer<UInt8>
54+
let buffer: UnsafePointer<UInt8>
5555

5656
init(
5757
length: Int,

Sources/ArrowIPC/Array+IPC.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright 2025 The Columnar Swift Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Arrow
16+
import Foundation
17+
18+
typealias ArrowArrayUtf8 = ArrowArrayVariable<
19+
String,
20+
FixedWidthBufferIPC<Int32>,
21+
VariableLengthBufferIPC<String>
22+
>
23+
24+
extension ArrowArrayUtf8 {
25+
26+
/// Build a `Data` backed Arrow utf8 array.
27+
/// - Parameters:
28+
/// - length: The array length.
29+
/// - nullBuffer: The null buffer.
30+
/// - offsetsBuffer: A view over file-backed data.
31+
/// - valueBuffer: A view over file-backed data.
32+
/// - Returns: A file-backed Arrow utf8 array.
33+
static func utf8(
34+
length: Int,
35+
nullBuffer: NullBuffer,
36+
offsetsBuffer: FileDataBuffer,
37+
valueBuffer: FileDataBuffer
38+
) -> Self {
39+
let offsetsBufferTyped = FixedWidthBufferIPC<Int32>(buffer: offsetsBuffer)
40+
let valueBufferTyped = VariableLengthBufferIPC<String>(buffer: valueBuffer)
41+
return Self(
42+
offset: 0,
43+
length: length,
44+
nullBuffer: nullBuffer,
45+
offsetsBuffer: offsetsBufferTyped,
46+
valueBuffer: valueBufferTyped
47+
)
48+
}
49+
}
50+
51+
typealias ArrowArrayBinary = ArrowArrayVariable<
52+
Data,
53+
FixedWidthBufferIPC<Int32>,
54+
VariableLengthBufferIPC<Data>
55+
>
56+
57+
extension ArrowArrayBinary {
58+
59+
/// Build a `Data` backed Arrow binary array.
60+
/// - Parameters:
61+
/// - length: The array length.
62+
/// - nullBuffer: The null buffer.
63+
/// - offsetsBuffer: A view over file-backed data.
64+
/// - valueBuffer: A view over file-backed data.
65+
/// - Returns: A file-backed Arrow utf8 array.
66+
static func binary(
67+
length: Int,
68+
nullBuffer: NullBuffer,
69+
offsetsBuffer: FileDataBuffer,
70+
valueBuffer: FileDataBuffer
71+
) -> Self {
72+
let offsetsBufferTyped = FixedWidthBufferIPC<Int32>(buffer: offsetsBuffer)
73+
let valueBufferTyped = VariableLengthBufferIPC<Data>(buffer: valueBuffer)
74+
return Self(
75+
offset: 0,
76+
length: length,
77+
nullBuffer: nullBuffer,
78+
offsetsBuffer: offsetsBufferTyped,
79+
valueBuffer: valueBufferTyped
80+
)
81+
}
82+
}

0 commit comments

Comments
 (0)