21
21
using System . IO ;
22
22
using System . Threading ;
23
23
using System . Threading . Tasks ;
24
+ using Apache . Arrow . Types ;
24
25
25
26
namespace Apache . Arrow . Ipc
26
27
{
@@ -114,35 +115,42 @@ private List<IArrowArray> BuildArrays(
114
115
Flatbuf . RecordBatch recordBatchMessage )
115
116
{
116
117
var arrays = new List < IArrowArray > ( recordBatchMessage . NodesLength ) ;
117
- int bufferIndex = 0 ;
118
118
119
- for ( var n = 0 ; n < recordBatchMessage . NodesLength ; n ++ )
119
+ if ( recordBatchMessage . NodesLength == 0 )
120
120
{
121
- Field field = schema . GetFieldByIndex ( n ) ;
122
- Flatbuf . FieldNode fieldNode = recordBatchMessage . Nodes ( n ) . GetValueOrDefault ( ) ;
121
+ return arrays ;
122
+ }
123
+
124
+ var recordBatchEnumerator = new RecordBatchEnumerator ( in recordBatchMessage ) ;
125
+
126
+ do
127
+ {
128
+ var field = schema . GetFieldByIndex ( recordBatchEnumerator . CurrentNodeIndex ) ;
129
+ var fieldNode = recordBatchEnumerator . CurrentNode ;
123
130
124
- ArrayData arrayData = field . DataType . IsFixedPrimitive ( ) ?
125
- LoadPrimitiveField ( field , fieldNode , recordBatchMessage , messageBuffer , ref bufferIndex ) :
126
- LoadVariableField ( field , fieldNode , recordBatchMessage , messageBuffer , ref bufferIndex ) ;
131
+ var arrayData = field . DataType . IsFixedPrimitive ( )
132
+ ? LoadPrimitiveField ( ref recordBatchEnumerator , field , in fieldNode , messageBuffer )
133
+ : LoadVariableField ( ref recordBatchEnumerator , field , in fieldNode , messageBuffer ) ;
127
134
128
135
arrays . Add ( ArrowArrayFactory . BuildArray ( arrayData ) ) ;
129
- }
136
+ } while ( recordBatchEnumerator . MoveNextNode ( ) ) ;
130
137
131
138
return arrays ;
132
139
}
133
140
141
+
134
142
private ArrayData LoadPrimitiveField (
143
+ ref RecordBatchEnumerator recordBatchEnumerator ,
135
144
Field field ,
136
- Flatbuf . FieldNode fieldNode ,
137
- Flatbuf . RecordBatch recordBatch ,
138
- ByteBuffer bodyData ,
139
- ref int bufferIndex )
145
+ in Flatbuf . FieldNode fieldNode ,
146
+ ByteBuffer bodyData )
140
147
{
141
- var nullBitmapBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
142
- var valueBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
143
148
144
- ArrowBuffer nullArrowBuffer = BuildArrowBuffer ( bodyData , nullBitmapBuffer ) ;
145
- ArrowBuffer valueArrowBuffer = BuildArrowBuffer ( bodyData , valueBuffer ) ;
149
+ ArrowBuffer nullArrowBuffer = BuildArrowBuffer ( bodyData , recordBatchEnumerator . CurrentBuffer ) ;
150
+ recordBatchEnumerator . MoveNextBuffer ( ) ;
151
+ ArrowBuffer valueArrowBuffer = BuildArrowBuffer ( bodyData , recordBatchEnumerator . CurrentBuffer ) ;
152
+ recordBatchEnumerator . MoveNextBuffer ( ) ;
153
+
146
154
147
155
var fieldLength = ( int ) fieldNode . Length ;
148
156
var fieldNullCount = ( int ) fieldNode . NullCount ;
@@ -158,24 +166,25 @@ private ArrayData LoadPrimitiveField(
158
166
}
159
167
160
168
var arrowBuff = new [ ] { nullArrowBuffer , valueArrowBuffer } ;
169
+ var children = GetChildren ( ref recordBatchEnumerator , field , bodyData ) ;
161
170
162
- return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff ) ;
171
+ return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff , children ) ;
163
172
}
164
173
174
+
165
175
private ArrayData LoadVariableField (
176
+ ref RecordBatchEnumerator recordBatchEnumerator ,
166
177
Field field ,
167
- Flatbuf . FieldNode fieldNode ,
168
- Flatbuf . RecordBatch recordBatch ,
169
- ByteBuffer bodyData ,
170
- ref int bufferIndex )
178
+ in Flatbuf . FieldNode fieldNode ,
179
+ ByteBuffer bodyData )
171
180
{
172
- var nullBitmapBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
173
- var offsetBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
174
- var valueBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
175
181
176
- ArrowBuffer nullArrowBuffer = BuildArrowBuffer ( bodyData , nullBitmapBuffer ) ;
177
- ArrowBuffer offsetArrowBuffer = BuildArrowBuffer ( bodyData , offsetBuffer ) ;
178
- ArrowBuffer valueArrowBuffer = BuildArrowBuffer ( bodyData , valueBuffer ) ;
182
+ ArrowBuffer nullArrowBuffer = BuildArrowBuffer ( bodyData , recordBatchEnumerator . CurrentBuffer ) ;
183
+ recordBatchEnumerator . MoveNextBuffer ( ) ;
184
+ ArrowBuffer offsetArrowBuffer = BuildArrowBuffer ( bodyData , recordBatchEnumerator . CurrentBuffer ) ;
185
+ recordBatchEnumerator . MoveNextBuffer ( ) ;
186
+ ArrowBuffer valueArrowBuffer = BuildArrowBuffer ( bodyData , recordBatchEnumerator . CurrentBuffer ) ;
187
+ recordBatchEnumerator . MoveNextBuffer ( ) ;
179
188
180
189
var fieldLength = ( int ) fieldNode . Length ;
181
190
var fieldNullCount = ( int ) fieldNode . NullCount ;
@@ -191,8 +200,33 @@ private ArrayData LoadVariableField(
191
200
}
192
201
193
202
var arrowBuff = new [ ] { nullArrowBuffer , offsetArrowBuffer , valueArrowBuffer } ;
203
+ var children = GetChildren ( ref recordBatchEnumerator , field , bodyData ) ;
194
204
195
- return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff ) ;
205
+ return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff , children ) ;
206
+ }
207
+
208
+ private ArrayData [ ] GetChildren (
209
+ ref RecordBatchEnumerator recordBatchEnumerator ,
210
+ Field field ,
211
+ ByteBuffer bodyData )
212
+ {
213
+ if ( ! ( field . DataType is NestedType type ) ) return null ;
214
+
215
+ var childrenCount = type . Children . Count ;
216
+ var children = new ArrayData [ childrenCount ] ;
217
+ for ( var index = 0 ; index < childrenCount ; index ++ )
218
+ {
219
+ Flatbuf . FieldNode childFieldNode = recordBatchEnumerator . CurrentNode ;
220
+ recordBatchEnumerator . MoveNextNode ( ) ;
221
+
222
+ var childField = type . Children [ index ] ;
223
+ var child = childField . DataType . IsFixedPrimitive ( )
224
+ ? LoadPrimitiveField ( ref recordBatchEnumerator , childField , in childFieldNode , bodyData )
225
+ : LoadVariableField ( ref recordBatchEnumerator , childField , in childFieldNode , bodyData ) ;
226
+
227
+ children [ index ] = child ;
228
+ }
229
+ return children ;
196
230
}
197
231
198
232
private ArrowBuffer BuildArrowBuffer ( ByteBuffer bodyData , Flatbuf . Buffer buffer )
@@ -209,4 +243,32 @@ private ArrowBuffer BuildArrowBuffer(ByteBuffer bodyData, Flatbuf.Buffer buffer)
209
243
return new ArrowBuffer ( data ) ;
210
244
}
211
245
}
246
+
247
+ internal struct RecordBatchEnumerator
248
+ {
249
+ private Flatbuf . RecordBatch RecordBatch { get ; }
250
+ internal int CurrentBufferIndex { get ; private set ; }
251
+ internal int CurrentNodeIndex { get ; private set ; }
252
+
253
+ internal Flatbuf . Buffer CurrentBuffer => RecordBatch . Buffers ( CurrentBufferIndex ) . GetValueOrDefault ( ) ;
254
+
255
+ internal Flatbuf . FieldNode CurrentNode => RecordBatch . Nodes ( CurrentNodeIndex ) . GetValueOrDefault ( ) ;
256
+
257
+ internal bool MoveNextBuffer ( )
258
+ {
259
+ return ++ CurrentBufferIndex < RecordBatch . BuffersLength ;
260
+ }
261
+
262
+ internal bool MoveNextNode ( )
263
+ {
264
+ return ++ CurrentNodeIndex < RecordBatch . NodesLength ;
265
+ }
266
+
267
+ internal RecordBatchEnumerator ( in Flatbuf . RecordBatch recordBatch )
268
+ {
269
+ RecordBatch = recordBatch ;
270
+ CurrentBufferIndex = 0 ;
271
+ CurrentNodeIndex = 0 ;
272
+ }
273
+ }
212
274
}
0 commit comments