@@ -17,7 +17,7 @@ namespace Microsoft.Data.Analysis
17
17
/// </summary>
18
18
/// <typeparam name="T"></typeparam>
19
19
internal partial class PrimitiveColumnContainer < T > : IEnumerable < T ? >
20
- where T : struct
20
+ where T : unmanaged
21
21
{
22
22
public IList < ReadOnlyDataFrameBuffer < T > > Buffers = new List < ReadOnlyDataFrameBuffer < T > > ( ) ;
23
23
@@ -90,6 +90,7 @@ public PrimitiveColumnContainer(ReadOnlyMemory<byte> buffer, ReadOnlyMemory<byte
90
90
dataBuffer = new ReadOnlyDataFrameBuffer < T > ( buffer , length ) ;
91
91
}
92
92
Buffers . Add ( dataBuffer ) ;
93
+
93
94
int bitMapBufferLength = ( length + 7 ) / 8 ;
94
95
ReadOnlyDataFrameBuffer < byte > nullDataFrameBuffer ;
95
96
if ( nullBitMap . IsEmpty )
@@ -127,31 +128,7 @@ public PrimitiveColumnContainer(ReadOnlyMemory<byte> buffer, ReadOnlyMemory<byte
127
128
128
129
public PrimitiveColumnContainer ( long length = 0 )
129
130
{
130
- while ( length > 0 )
131
- {
132
- if ( Buffers . Count == 0 )
133
- {
134
- Buffers . Add ( new DataFrameBuffer < T > ( ) ) ;
135
- NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
136
- }
137
- DataFrameBuffer < T > lastBuffer = ( DataFrameBuffer < T > ) Buffers [ Buffers . Count - 1 ] ;
138
- if ( lastBuffer . Length == ReadOnlyDataFrameBuffer < T > . MaxCapacity )
139
- {
140
- lastBuffer = new DataFrameBuffer < T > ( ) ;
141
- Buffers . Add ( lastBuffer ) ;
142
- NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
143
- }
144
- int allocatable = ( int ) Math . Min ( length , ReadOnlyDataFrameBuffer < T > . MaxCapacity ) ;
145
- lastBuffer . EnsureCapacity ( allocatable ) ;
146
- DataFrameBuffer < byte > lastNullBitMapBuffer = ( DataFrameBuffer < byte > ) ( NullBitMapBuffers [ NullBitMapBuffers . Count - 1 ] ) ;
147
- int nullBufferAllocatable = ( allocatable + 7 ) / 8 ;
148
- lastNullBitMapBuffer . EnsureCapacity ( nullBufferAllocatable ) ;
149
- lastBuffer . Length = allocatable ;
150
- lastNullBitMapBuffer . Length = nullBufferAllocatable ;
151
- length -= allocatable ;
152
- Length += lastBuffer . Length ;
153
- NullCount += lastBuffer . Length ;
154
- }
131
+ AppendMany ( null , length ) ;
155
132
}
156
133
157
134
public void Resize ( long length )
@@ -168,16 +145,14 @@ public void Append(T? value)
168
145
Buffers . Add ( new DataFrameBuffer < T > ( ) ) ;
169
146
NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
170
147
}
171
- int bufferIndex = Buffers . Count - 1 ;
172
- ReadOnlyDataFrameBuffer < T > lastBuffer = Buffers [ bufferIndex ] ;
173
- if ( lastBuffer . Length == ReadOnlyDataFrameBuffer < T > . MaxCapacity )
148
+
149
+ if ( Buffers [ Buffers . Count - 1 ] . Length == ReadOnlyDataFrameBuffer < T > . MaxCapacity )
174
150
{
175
- lastBuffer = new DataFrameBuffer < T > ( ) ;
176
- Buffers . Add ( lastBuffer ) ;
151
+ Buffers . Add ( new DataFrameBuffer < T > ( ) ) ;
177
152
NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
178
153
}
179
- DataFrameBuffer < T > mutableLastBuffer = DataFrameBuffer < T > . GetMutableBuffer ( lastBuffer ) ;
180
- Buffers [ bufferIndex ] = mutableLastBuffer ;
154
+
155
+ DataFrameBuffer < T > mutableLastBuffer = Buffers . GetOrCreateMutable ( Buffers . Count - 1 ) ;
181
156
mutableLastBuffer . Append ( value ?? default ) ;
182
157
SetValidityBit ( Length , value . HasValue ) ;
183
158
Length ++ ;
@@ -190,90 +165,91 @@ public void AppendMany(T? value, long count)
190
165
NullCount += count ;
191
166
}
192
167
193
- while ( count > 0 )
168
+ var remaining = count ;
169
+ while ( remaining > 0 )
194
170
{
195
171
if ( Buffers . Count == 0 )
196
172
{
197
173
Buffers . Add ( new DataFrameBuffer < T > ( ) ) ;
198
174
NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
199
175
}
200
- int bufferIndex = Buffers . Count - 1 ;
201
- ReadOnlyDataFrameBuffer < T > lastBuffer = Buffers [ bufferIndex ] ;
202
- if ( lastBuffer . Length == ReadOnlyDataFrameBuffer < T > . MaxCapacity )
176
+
177
+ if ( Buffers [ Buffers . Count - 1 ] . Length == ReadOnlyDataFrameBuffer < T > . MaxCapacity )
203
178
{
204
- lastBuffer = new DataFrameBuffer < T > ( ) ;
205
- Buffers . Add ( lastBuffer ) ;
179
+ Buffers . Add ( new DataFrameBuffer < T > ( ) ) ;
206
180
NullBitMapBuffers . Add ( new DataFrameBuffer < byte > ( ) ) ;
207
181
}
208
- DataFrameBuffer < T > mutableLastBuffer = DataFrameBuffer < T > . GetMutableBuffer ( lastBuffer ) ;
209
- Buffers [ bufferIndex ] = mutableLastBuffer ;
210
- int allocatable = ( int ) Math . Min ( count , ReadOnlyDataFrameBuffer < T > . MaxCapacity ) ;
182
+
183
+ DataFrameBuffer < T > mutableLastBuffer = Buffers . GetOrCreateMutable ( Buffers . Count - 1 ) ;
184
+ int allocatable = ( int ) Math . Min ( remaining , ReadOnlyDataFrameBuffer < T > . MaxCapacity ) ;
211
185
mutableLastBuffer . EnsureCapacity ( allocatable ) ;
212
- mutableLastBuffer . RawSpan . Slice ( lastBuffer . Length , allocatable ) . Fill ( value ?? default ) ;
186
+
187
+ DataFrameBuffer < byte > lastNullBitMapBuffer = NullBitMapBuffers . GetOrCreateMutable ( NullBitMapBuffers . Count - 1 ) ;
188
+ int nullBufferAllocatable = ( allocatable + 7 ) / 8 ;
189
+ lastNullBitMapBuffer . EnsureCapacity ( nullBufferAllocatable ) ;
190
+
191
+
213
192
mutableLastBuffer . Length += allocatable ;
193
+ lastNullBitMapBuffer . Length += nullBufferAllocatable ;
214
194
Length += allocatable ;
215
195
216
- int nullBitMapBufferIndex = NullBitMapBuffers . Count - 1 ;
217
- ReadOnlyDataFrameBuffer < byte > lastNullBitMapBuffer = NullBitMapBuffers [ nullBitMapBufferIndex ] ;
218
- DataFrameBuffer < byte > mutableLastNullBitMapBuffer = DataFrameBuffer < byte > . GetMutableBuffer ( lastNullBitMapBuffer ) ;
219
- NullBitMapBuffers [ nullBitMapBufferIndex ] = mutableLastNullBitMapBuffer ;
220
- int nullBitMapAllocatable = ( int ) ( ( ( uint ) allocatable ) / 8 ) + 1 ;
221
- mutableLastNullBitMapBuffer . EnsureCapacity ( nullBitMapAllocatable ) ;
222
- _modifyNullCountWhileIndexing = false ;
223
- for ( long i = Length - count ; i < Length ; i ++ )
196
+ if ( value . HasValue )
224
197
{
225
- SetValidityBit ( i , value . HasValue ? true : false ) ;
198
+ mutableLastBuffer . RawSpan . Slice ( mutableLastBuffer . Length - allocatable , allocatable ) . Fill ( value ?? default ) ;
199
+
200
+ _modifyNullCountWhileIndexing = false ;
201
+ for ( long i = Length - allocatable ; i < Length ; i ++ )
202
+ {
203
+ SetValidityBit ( i , value . HasValue ) ;
204
+ }
205
+ _modifyNullCountWhileIndexing = true ;
226
206
}
227
- _modifyNullCountWhileIndexing = true ;
228
- count -= allocatable ;
207
+
208
+
209
+ remaining -= allocatable ;
229
210
}
230
211
}
231
212
232
213
public void ApplyElementwise ( Func < T ? , long , T ? > func )
233
214
{
215
+ var bufferMaxCapacity = ReadOnlyDataFrameBuffer < T > . MaxCapacity ;
234
216
for ( int b = 0 ; b < Buffers . Count ; b ++ )
235
217
{
236
- ReadOnlyDataFrameBuffer < T > buffer = Buffers [ b ] ;
237
- long prevLength = checked ( Buffers [ 0 ] . Length * b ) ;
238
- DataFrameBuffer < T > mutableBuffer = DataFrameBuffer < T > . GetMutableBuffer ( buffer ) ;
239
- Buffers [ b ] = mutableBuffer ;
240
- Span < T > span = mutableBuffer . Span ;
241
- DataFrameBuffer < byte > mutableNullBitMapBuffer = DataFrameBuffer < byte > . GetMutableBuffer ( NullBitMapBuffers [ b ] ) ;
242
- NullBitMapBuffers [ b ] = mutableNullBitMapBuffer ;
243
- Span < byte > nullBitMapSpan = mutableNullBitMapBuffer . Span ;
244
- for ( int i = 0 ; i < span . Length ; i ++ )
218
+ long prevLength = checked ( bufferMaxCapacity * b ) ;
219
+
220
+ Span < T > mutableBuffer = Buffers . GetOrCreateMutable ( b ) . Span ;
221
+ Span < byte > mutableNullBitMapBuffer = NullBitMapBuffers . GetOrCreateMutable ( b ) . Span ;
222
+
223
+ for ( int i = 0 ; i < mutableBuffer . Length ; i ++ )
245
224
{
246
225
long curIndex = i + prevLength ;
247
- bool isValid = IsValid ( nullBitMapSpan , i ) ;
248
- T ? value = func ( isValid ? span [ i ] : default ( T ? ) , curIndex ) ;
249
- span [ i ] = value . GetValueOrDefault ( ) ;
250
- SetValidityBit ( nullBitMapSpan , i , value != null ) ;
226
+ bool isValid = IsValid ( mutableNullBitMapBuffer , i ) ;
227
+ T ? value = func ( isValid ? mutableBuffer [ i ] : null , curIndex ) ;
228
+ mutableBuffer [ i ] = value . GetValueOrDefault ( ) ;
229
+ SetValidityBit ( mutableNullBitMapBuffer , i , value != null ) ;
251
230
}
252
231
}
253
232
}
254
233
255
234
public void Apply < TResult > ( Func < T ? , TResult ? > func , PrimitiveColumnContainer < TResult > resultContainer )
256
235
where TResult : unmanaged
257
236
{
237
+ var bufferMaxCapacity = ReadOnlyDataFrameBuffer < T > . MaxCapacity ;
258
238
for ( int b = 0 ; b < Buffers . Count ; b ++ )
259
239
{
260
- ReadOnlyDataFrameBuffer < T > sourceBuffer = Buffers [ b ] ;
261
- ReadOnlySpan < byte > sourceNullBitMap = NullBitMapBuffers [ b ] . ReadOnlySpan ;
240
+ long prevLength = checked ( bufferMaxCapacity * b ) ;
241
+ var sourceBuffer = Buffers [ b ] ;
242
+ var sourceNullBitMap = NullBitMapBuffers [ b ] . ReadOnlySpan ;
262
243
263
- ReadOnlyDataFrameBuffer < TResult > resultBuffer = resultContainer . Buffers [ b ] ;
264
- DataFrameBuffer < TResult > resultMutableBuffer = DataFrameBuffer < TResult > . GetMutableBuffer ( resultBuffer ) ;
265
- resultContainer . Buffers [ b ] = resultMutableBuffer ;
266
- Span < TResult > resultSpan = resultMutableBuffer . Span ;
267
- DataFrameBuffer < byte > resultMutableNullBitMapBuffer = DataFrameBuffer < byte > . GetMutableBuffer ( resultContainer . NullBitMapBuffers [ b ] ) ;
268
- resultContainer . NullBitMapBuffers [ b ] = resultMutableNullBitMapBuffer ;
269
- Span < byte > resultNullBitMapSpan = resultMutableNullBitMapBuffer . Span ;
244
+ Span < TResult > mutableResultBuffer = resultContainer . Buffers . GetOrCreateMutable ( b ) . Span ;
245
+ Span < byte > mutableResultNullBitMapBuffers = resultContainer . NullBitMapBuffers . GetOrCreateMutable ( b ) . Span ;
270
246
271
- for ( int i = 0 ; i < Buffers [ b ] . Length ; i ++ )
247
+ for ( int i = 0 ; i < sourceBuffer . Length ; i ++ )
272
248
{
273
249
bool isValid = IsValid ( sourceNullBitMap , i ) ;
274
- TResult ? value = func ( isValid ? sourceBuffer [ i ] : default ( T ? ) ) ;
275
- resultSpan [ i ] = value . GetValueOrDefault ( ) ;
276
- resultContainer . SetValidityBit ( resultNullBitMapSpan , i , value != null ) ;
250
+ TResult ? value = func ( isValid ? sourceBuffer [ i ] : null ) ;
251
+ mutableResultBuffer [ i ] = value . GetValueOrDefault ( ) ;
252
+ resultContainer . SetValidityBit ( mutableResultNullBitMapBuffers , i , value != null ) ;
277
253
}
278
254
}
279
255
}
@@ -440,11 +416,10 @@ public T? this[long rowIndex]
440
416
{
441
417
int arrayIndex = GetArrayContainingRowIndex ( rowIndex ) ;
442
418
rowIndex = rowIndex - arrayIndex * ReadOnlyDataFrameBuffer < T > . MaxCapacity ;
443
- ReadOnlyDataFrameBuffer < T > buffer = Buffers [ arrayIndex ] ;
444
- DataFrameBuffer < T > mutableBuffer = DataFrameBuffer < T > . GetMutableBuffer ( buffer ) ;
445
- Buffers [ arrayIndex ] = mutableBuffer ;
446
- DataFrameBuffer < byte > mutableNullBuffer = DataFrameBuffer < byte > . GetMutableBuffer ( NullBitMapBuffers [ arrayIndex ] ) ;
447
- NullBitMapBuffers [ arrayIndex ] = mutableNullBuffer ;
419
+
420
+ Buffers . GetOrCreateMutable ( arrayIndex ) ;
421
+ NullBitMapBuffers . GetOrCreateMutable ( arrayIndex ) ;
422
+
448
423
if ( value . HasValue )
449
424
{
450
425
Buffers [ arrayIndex ] [ ( int ) rowIndex ] = value . Value ;
0 commit comments