@@ -29,21 +29,22 @@ static class JsonNode {
29
29
private final String [] emptyResult ;
30
30
private JsonNode ptr ;
31
31
private byte [] buffer ;
32
- private final int targetParseNum ;
32
+ private final int expectParseCols ;
33
+ // every time json string is processed, currentVersion will be incremented by 1
33
34
private long currentVersion = 0 ;
34
35
// pruning, when alreadyProcessedCols == NUM
35
- private long alreadyProcessedCols = 0 ;
36
+ private long parseCols = 0 ;
36
37
37
38
public SimdJsonParser2 (String ... args ) {
38
39
parser = new SimdJsonParser ();
39
- targetParseNum = args .length ;
40
- row = new JsonNode [targetParseNum ];
41
- result = new String [targetParseNum ];
42
- emptyResult = new String [targetParseNum ];
40
+ expectParseCols = args .length ;
41
+ row = new JsonNode [expectParseCols ];
42
+ result = new String [expectParseCols ];
43
+ emptyResult = new String [expectParseCols ];
43
44
for (int i = 0 ; i < args .length ; i ++) {
44
45
emptyResult [i ] = null ;
45
46
}
46
- for (int i = 0 ; i < targetParseNum ; i ++) {
47
+ for (int i = 0 ; i < expectParseCols ; i ++) {
47
48
JsonNode cur = root ;
48
49
String [] paths = args [i ].split ("\\ ." );
49
50
for (int j = 0 ; j < paths .length ; j ++) {
@@ -65,7 +66,7 @@ public String[] parse(byte[] buffer, int len) {
65
66
if (buffer == null || buffer .length == 0 ) {
66
67
return emptyResult ;
67
68
}
68
- this .alreadyProcessedCols = 0 ;
69
+ this .parseCols = 0 ;
69
70
this .currentVersion ++;
70
71
this .ptr = root ;
71
72
this .buffer = buffer ;
@@ -84,22 +85,34 @@ public String[] parse(byte[] buffer, int len) {
84
85
return getResult ();
85
86
}
86
87
87
- private void parseElement (String fieldName ) {
88
- if (fieldName == null ) {
89
- int start = bitIndexes .advance ();
90
- int realEnd = bitIndexes .advance ();
91
- while (realEnd > start ) {
92
- if (buffer [--realEnd ] == '"' ) {
93
- break ;
94
- }
95
- }
96
- fieldName = new String (buffer , start + 1 , realEnd - start - 1 );
88
+ private String parseField () {
89
+ int start = bitIndexes .advance ();
90
+ int next = bitIndexes .peek ();
91
+ String field = new String (buffer , start , next - start ).trim ();
92
+ if ("null" .equalsIgnoreCase (field )) {
93
+ return null ;
94
+ }
95
+ // field type is string or type is decimal
96
+ if (field .startsWith ("\" " )) {
97
+ field = field .substring (1 , field .length () - 1 );
98
+ }
99
+ return field ;
100
+ }
101
+
102
+ private void parseElement (String expectFieldName ) {
103
+ if (parseCols >= expectParseCols ) {
104
+ return ;
105
+ }
106
+ // if expectFieldName is null, parent is map, else is list
107
+ if (expectFieldName == null ) {
108
+ expectFieldName = parseField ();
109
+ bitIndexes .advance (); // skip :
97
110
}
98
- if (!ptr .getChildren ().containsKey (fieldName )) {
111
+ if (!ptr .getChildren ().containsKey (expectFieldName )) {
99
112
skip (false );
100
113
return ;
101
114
}
102
- ptr = ptr .getChildren ().get (fieldName );
115
+ ptr = ptr .getChildren ().get (expectFieldName );
103
116
switch (buffer [bitIndexes .peek ()]) {
104
117
case '{' -> {
105
118
parseMap ();
@@ -110,7 +123,7 @@ private void parseElement(String fieldName) {
110
123
default -> {
111
124
ptr .setValue (skip (true ));
112
125
ptr .setVersion (currentVersion );
113
- ++alreadyProcessedCols ;
126
+ ++parseCols ;
114
127
}
115
128
}
116
129
ptr = ptr .getParent ();
@@ -120,12 +133,12 @@ private void parseMap() {
120
133
if (ptr .getChildren () == null ) {
121
134
ptr .setValue (skip (true ));
122
135
ptr .setVersion (currentVersion );
123
- ++alreadyProcessedCols ;
136
+ ++parseCols ;
124
137
return ;
125
138
}
126
139
ptr .setStart (bitIndexes .peek ());
127
140
bitIndexes .advance ();
128
- while (bitIndexes .hasNext () && buffer [bitIndexes .peek ()] != '}' && alreadyProcessedCols < targetParseNum ) {
141
+ while (bitIndexes .hasNext () && buffer [bitIndexes .peek ()] != '}' && parseCols <= expectParseCols ) {
129
142
parseElement (null );
130
143
if (buffer [bitIndexes .peek ()] == ',' ) {
131
144
bitIndexes .advance ();
@@ -135,7 +148,7 @@ private void parseMap() {
135
148
if (ptr .isLeaf ()) {
136
149
ptr .setValue (new String (buffer , ptr .getStart (), ptr .getEnd () - ptr .getStart () + 1 ));
137
150
ptr .setVersion (currentVersion );
138
- ++alreadyProcessedCols ;
151
+ ++parseCols ;
139
152
}
140
153
bitIndexes .advance ();
141
154
}
@@ -144,13 +157,13 @@ private void parseList() {
144
157
if (ptr .getChildren () == null ) {
145
158
ptr .setValue (skip (true ));
146
159
ptr .setVersion (currentVersion );
147
- ++alreadyProcessedCols ;
160
+ ++parseCols ;
148
161
return ;
149
162
}
150
163
ptr .setStart (bitIndexes .peek ());
151
164
bitIndexes .advance ();
152
165
int i = 0 ;
153
- while (bitIndexes .hasNext () && buffer [bitIndexes .peek ()] != ']' && alreadyProcessedCols < targetParseNum ) {
166
+ while (bitIndexes .hasNext () && buffer [bitIndexes .peek ()] != ']' && parseCols <= expectParseCols ) {
154
167
parseElement ("" + i );
155
168
if (buffer [bitIndexes .peek ()] == ',' ) {
156
169
bitIndexes .advance ();
@@ -161,7 +174,7 @@ private void parseList() {
161
174
if (ptr .isLeaf ()) {
162
175
ptr .setValue (new String (buffer , ptr .getStart (), ptr .getEnd () - ptr .getStart () + 1 ));
163
176
ptr .setVersion (currentVersion );
164
- ++alreadyProcessedCols ;
177
+ ++parseCols ;
165
178
}
166
179
bitIndexes .advance ();
167
180
}
@@ -198,32 +211,14 @@ private String skip(boolean retainValue) {
198
211
bitIndexes .advance ();
199
212
return retainValue ? new String (buffer , start , end - start + 1 ) : null ;
200
213
}
201
- case '"' -> {
202
- bitIndexes .advance ();
203
- int realEnd = bitIndexes .peek ();
204
- while (realEnd > start ) {
205
- if (buffer [--realEnd ] == '"' ) {
206
- break ;
207
- }
208
- }
209
- return retainValue ? new String (buffer , start + 1 , realEnd - start - 1 ) : null ;
210
- }
211
214
default -> {
212
- bitIndexes .advance ();
213
- int realEnd = bitIndexes .peek ();
214
- while (realEnd >= start ) {
215
- --realEnd ;
216
- if (buffer [realEnd ] >= '0' && buffer [realEnd ] <= '9' ) {
217
- break ;
218
- }
219
- }
220
- return retainValue ? new String (buffer , start , realEnd - start + 1 ) : null ;
215
+ return parseField ();
221
216
}
222
217
}
223
218
}
224
219
225
220
private String [] getResult () {
226
- for (int i = 0 ; i < targetParseNum ; i ++) {
221
+ for (int i = 0 ; i < expectParseCols ; i ++) {
227
222
if (row [i ].getVersion () < currentVersion ) {
228
223
result [i ] = null ;
229
224
continue ;
0 commit comments