21
21
import org .apache .spark .unsafe .Platform ;
22
22
import org .apache .spark .unsafe .array .ByteArrayMethods ;
23
23
import org .apache .spark .unsafe .bitset .BitSetMethods ;
24
- import org .apache .spark .unsafe .types .CalendarInterval ;
25
- import org .apache .spark .unsafe .types .UTF8String ;
26
24
27
25
import static org .apache .spark .sql .catalyst .expressions .UnsafeArrayData .calculateHeaderPortionInBytes ;
28
26
32
30
*/
33
31
public final class UnsafeArrayWriter extends UnsafeWriter {
34
32
35
- private BufferHolder holder ;
36
-
37
- // The offset of the global buffer where we start to write this array.
38
- private int startingOffset ;
39
-
40
33
// The number of elements in this array
41
34
private int numElements ;
42
35
36
+ // The element size in this array
37
+ private int elementSize ;
38
+
43
39
private int headerInBytes ;
44
40
45
41
private void assertIndexIsValid (int index ) {
46
42
assert index >= 0 : "index (" + index + ") should >= 0" ;
47
43
assert index < numElements : "index (" + index + ") should < " + numElements ;
48
44
}
49
45
50
- public void initialize (BufferHolder holder , int numElements , int elementSize ) {
46
+ public UnsafeArrayWriter (UnsafeWriter writer , int elementSize ) {
47
+ super (writer .getBufferHolder ());
48
+ this .elementSize = elementSize ;
49
+ }
50
+
51
+ public void initialize (int numElements ) {
51
52
// We need 8 bytes to store numElements in header
52
53
this .numElements = numElements ;
53
54
this .headerInBytes = calculateHeaderPortionInBytes (numElements );
54
55
55
- this .holder = holder ;
56
- this .startingOffset = holder .cursor ;
56
+ this .startingOffset = cursor ();
57
57
58
58
// Grows the global buffer ahead for header and fixed size data.
59
59
int fixedPartInBytes =
60
60
ByteArrayMethods .roundNumberOfBytesToNearestWord (elementSize * numElements );
61
61
holder .grow (headerInBytes + fixedPartInBytes );
62
62
63
63
// Write numElements and clear out null bits to header
64
- Platform .putLong (holder . buffer , startingOffset , numElements );
64
+ Platform .putLong (getBuffer () , startingOffset , numElements );
65
65
for (int i = 8 ; i < headerInBytes ; i += 8 ) {
66
- Platform .putLong (holder . buffer , startingOffset + i , 0L );
66
+ Platform .putLong (getBuffer () , startingOffset + i , 0L );
67
67
}
68
68
69
69
// fill 0 into reminder part of 8-bytes alignment in unsafe array
70
70
for (int i = elementSize * numElements ; i < fixedPartInBytes ; i ++) {
71
- Platform .putByte (holder . buffer , startingOffset + headerInBytes + i , (byte ) 0 );
71
+ Platform .putByte (getBuffer () , startingOffset + headerInBytes + i , (byte ) 0 );
72
72
}
73
- holder . cursor += (headerInBytes + fixedPartInBytes );
73
+ increaseCursor (headerInBytes + fixedPartInBytes );
74
74
}
75
75
76
- private void zeroOutPaddingBytes (int numBytes ) {
77
- if ((numBytes & 0x07 ) > 0 ) {
78
- Platform .putLong (holder .buffer , holder .cursor + ((numBytes >> 3 ) << 3 ), 0L );
79
- }
80
- }
81
-
82
- private long getElementOffset (int ordinal , int elementSize ) {
76
+ private long getElementOffset (int ordinal ) {
83
77
return startingOffset + headerInBytes + ordinal * elementSize ;
84
78
}
85
79
86
- public void setOffsetAndSize (int ordinal , int currentCursor , int size ) {
87
- assertIndexIsValid (ordinal );
88
- final long relativeOffset = currentCursor - startingOffset ;
89
- final long offsetAndSize = (relativeOffset << 32 ) | (long )size ;
90
-
91
- write (ordinal , offsetAndSize );
92
- }
93
-
94
80
private void setNullBit (int ordinal ) {
95
81
assertIndexIsValid (ordinal );
96
- BitSetMethods .set (holder . buffer , startingOffset + 8 , ordinal );
82
+ BitSetMethods .set (getBuffer () , startingOffset + 8 , ordinal );
97
83
}
98
84
99
85
public void setNull1Bytes (int ordinal ) {
100
86
setNullBit (ordinal );
101
87
// put zero into the corresponding field when set null
102
- Platform . putByte ( holder . buffer , getElementOffset (ordinal , 1 ), (byte )0 );
88
+ writeByte ( getElementOffset (ordinal ), (byte )0 );
103
89
}
104
90
105
91
public void setNull2Bytes (int ordinal ) {
106
92
setNullBit (ordinal );
107
93
// put zero into the corresponding field when set null
108
- Platform . putShort ( holder . buffer , getElementOffset (ordinal , 2 ), (short )0 );
94
+ writeShort ( getElementOffset (ordinal ), (short )0 );
109
95
}
110
96
111
97
public void setNull4Bytes (int ordinal ) {
112
98
setNullBit (ordinal );
113
99
// put zero into the corresponding field when set null
114
- Platform . putInt ( holder . buffer , getElementOffset (ordinal , 4 ), 0 );
100
+ writeInt ( getElementOffset (ordinal ), 0 );
115
101
}
116
102
117
103
public void setNull8Bytes (int ordinal ) {
118
104
setNullBit (ordinal );
119
105
// put zero into the corresponding field when set null
120
- Platform . putLong ( holder . buffer , getElementOffset (ordinal , 8 ), ( long ) 0 );
106
+ writeLong ( getElementOffset (ordinal ), 0 );
121
107
}
122
108
123
109
public void setNull (int ordinal ) { setNull8Bytes (ordinal ); }
124
110
125
111
public void write (int ordinal , boolean value ) {
126
112
assertIndexIsValid (ordinal );
127
- Platform . putBoolean ( holder . buffer , getElementOffset (ordinal , 1 ), value );
113
+ writeBoolean ( getElementOffset (ordinal ), value );
128
114
}
129
115
130
116
public void write (int ordinal , byte value ) {
131
117
assertIndexIsValid (ordinal );
132
- Platform . putByte ( holder . buffer , getElementOffset (ordinal , 1 ), value );
118
+ writeByte ( getElementOffset (ordinal ), value );
133
119
}
134
120
135
121
public void write (int ordinal , short value ) {
136
122
assertIndexIsValid (ordinal );
137
- Platform . putShort ( holder . buffer , getElementOffset (ordinal , 2 ), value );
123
+ writeShort ( getElementOffset (ordinal ), value );
138
124
}
139
125
140
126
public void write (int ordinal , int value ) {
141
127
assertIndexIsValid (ordinal );
142
- Platform . putInt ( holder . buffer , getElementOffset (ordinal , 4 ), value );
128
+ writeInt ( getElementOffset (ordinal ), value );
143
129
}
144
130
145
131
public void write (int ordinal , long value ) {
146
132
assertIndexIsValid (ordinal );
147
- Platform . putLong ( holder . buffer , getElementOffset (ordinal , 8 ), value );
133
+ writeLong ( getElementOffset (ordinal ), value );
148
134
}
149
135
150
136
public void write (int ordinal , float value ) {
151
- if (Float .isNaN (value )) {
152
- value = Float .NaN ;
153
- }
154
137
assertIndexIsValid (ordinal );
155
- Platform . putFloat ( holder . buffer , getElementOffset (ordinal , 4 ), value );
138
+ writeFloat ( getElementOffset (ordinal ), value );
156
139
}
157
140
158
141
public void write (int ordinal , double value ) {
159
- if (Double .isNaN (value )) {
160
- value = Double .NaN ;
161
- }
162
142
assertIndexIsValid (ordinal );
163
- Platform . putDouble ( holder . buffer , getElementOffset (ordinal , 8 ), value );
143
+ writeDouble ( getElementOffset (ordinal ), value );
164
144
}
165
145
166
146
public void write (int ordinal , Decimal input , int precision , int scale ) {
167
147
// make sure Decimal object has the same scale as DecimalType
168
148
assertIndexIsValid (ordinal );
169
- if (input .changePrecision (precision , scale )) {
149
+ if (input != null && input .changePrecision (precision , scale )) {
170
150
if (precision <= Decimal .MAX_LONG_DIGITS ()) {
171
151
write (ordinal , input .toUnscaledLong ());
172
152
} else {
@@ -180,65 +160,14 @@ public void write(int ordinal, Decimal input, int precision, int scale) {
180
160
181
161
// Write the bytes to the variable length portion.
182
162
Platform .copyMemory (
183
- bytes , Platform .BYTE_ARRAY_OFFSET , holder . buffer , holder . cursor , numBytes );
184
- setOffsetAndSize (ordinal , holder . cursor , numBytes );
163
+ bytes , Platform .BYTE_ARRAY_OFFSET , getBuffer (), cursor () , numBytes );
164
+ setOffsetAndSize (ordinal , numBytes );
185
165
186
166
// move the cursor forward with 8-bytes boundary
187
- holder . cursor += roundedSize ;
167
+ increaseCursor ( roundedSize ) ;
188
168
}
189
169
} else {
190
170
setNull (ordinal );
191
171
}
192
172
}
193
-
194
- public void write (int ordinal , UTF8String input ) {
195
- final int numBytes = input .numBytes ();
196
- final int roundedSize = ByteArrayMethods .roundNumberOfBytesToNearestWord (numBytes );
197
-
198
- // grow the global buffer before writing data.
199
- holder .grow (roundedSize );
200
-
201
- zeroOutPaddingBytes (numBytes );
202
-
203
- // Write the bytes to the variable length portion.
204
- input .writeToMemory (holder .buffer , holder .cursor );
205
-
206
- setOffsetAndSize (ordinal , holder .cursor , numBytes );
207
-
208
- // move the cursor forward.
209
- holder .cursor += roundedSize ;
210
- }
211
-
212
- public void write (int ordinal , byte [] input ) {
213
- final int numBytes = input .length ;
214
- final int roundedSize = ByteArrayMethods .roundNumberOfBytesToNearestWord (input .length );
215
-
216
- // grow the global buffer before writing data.
217
- holder .grow (roundedSize );
218
-
219
- zeroOutPaddingBytes (numBytes );
220
-
221
- // Write the bytes to the variable length portion.
222
- Platform .copyMemory (
223
- input , Platform .BYTE_ARRAY_OFFSET , holder .buffer , holder .cursor , numBytes );
224
-
225
- setOffsetAndSize (ordinal , holder .cursor , numBytes );
226
-
227
- // move the cursor forward.
228
- holder .cursor += roundedSize ;
229
- }
230
-
231
- public void write (int ordinal , CalendarInterval input ) {
232
- // grow the global buffer before writing data.
233
- holder .grow (16 );
234
-
235
- // Write the months and microseconds fields of Interval to the variable length portion.
236
- Platform .putLong (holder .buffer , holder .cursor , input .months );
237
- Platform .putLong (holder .buffer , holder .cursor + 8 , input .microseconds );
238
-
239
- setOffsetAndSize (ordinal , holder .cursor , 16 );
240
-
241
- // move the cursor forward.
242
- holder .cursor += 16 ;
243
- }
244
173
}
0 commit comments