2121using System . IO ;
2222using System . Threading ;
2323using System . Threading . Tasks ;
24+ using Apache . Arrow . Types ;
2425
2526namespace Apache . Arrow . Ipc
2627{
@@ -114,35 +115,42 @@ private List<IArrowArray> BuildArrays(
114115 Flatbuf . RecordBatch recordBatchMessage )
115116 {
116117 var arrays = new List < IArrowArray > ( recordBatchMessage . NodesLength ) ;
117- int bufferIndex = 0 ;
118118
119- for ( var n = 0 ; n < recordBatchMessage . NodesLength ; n ++ )
119+ if ( recordBatchMessage . NodesLength == 0 )
120120 {
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 ;
123130
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 ) ;
127134
128135 arrays . Add ( ArrowArrayFactory . BuildArray ( arrayData ) ) ;
129- }
136+ } while ( recordBatchEnumerator . MoveNextNode ( ) ) ;
130137
131138 return arrays ;
132139 }
133140
141+
134142 private ArrayData LoadPrimitiveField (
143+ ref RecordBatchEnumerator recordBatchEnumerator ,
135144 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 )
140147 {
141- var nullBitmapBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
142- var valueBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
143148
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+
146154
147155 var fieldLength = ( int ) fieldNode . Length ;
148156 var fieldNullCount = ( int ) fieldNode . NullCount ;
@@ -158,24 +166,25 @@ private ArrayData LoadPrimitiveField(
158166 }
159167
160168 var arrowBuff = new [ ] { nullArrowBuffer , valueArrowBuffer } ;
169+ var children = GetChildren ( ref recordBatchEnumerator , field , bodyData ) ;
161170
162- return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff ) ;
171+ return new ArrayData ( field . DataType , fieldLength , fieldNullCount , 0 , arrowBuff , children ) ;
163172 }
164173
174+
165175 private ArrayData LoadVariableField (
176+ ref RecordBatchEnumerator recordBatchEnumerator ,
166177 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 )
171180 {
172- var nullBitmapBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
173- var offsetBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
174- var valueBuffer = recordBatch . Buffers ( bufferIndex ++ ) . GetValueOrDefault ( ) ;
175181
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 ( ) ;
179188
180189 var fieldLength = ( int ) fieldNode . Length ;
181190 var fieldNullCount = ( int ) fieldNode . NullCount ;
@@ -191,8 +200,33 @@ private ArrayData LoadVariableField(
191200 }
192201
193202 var arrowBuff = new [ ] { nullArrowBuffer , offsetArrowBuffer , valueArrowBuffer } ;
203+ var children = GetChildren ( ref recordBatchEnumerator , field , bodyData ) ;
194204
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 ;
196230 }
197231
198232 private ArrowBuffer BuildArrowBuffer ( ByteBuffer bodyData , Flatbuf . Buffer buffer )
@@ -209,4 +243,32 @@ private ArrowBuffer BuildArrowBuffer(ByteBuffer bodyData, Flatbuf.Buffer buffer)
209243 return new ArrowBuffer ( data ) ;
210244 }
211245 }
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+ }
212274}
0 commit comments