8
8
import java .util .SortedMap ;
9
9
import java .util .TreeMap ;
10
10
import java .util .concurrent .CompletableFuture ;
11
- import java .util .stream .Collectors ;
12
11
13
12
import tech .ydb .core .Issue ;
14
13
import tech .ydb .core .Result ;
25
24
*/
26
25
public class QueryReader implements Iterable <ResultSetReader > {
27
26
private final QueryInfo info ;
28
- private final List <Issue > isssues ;
29
- private final List <ResultSetParts > results ;
27
+ private final List <Issue > issues ;
28
+ private final List <ResultSetReader > results ;
30
29
31
- QueryReader (QueryInfo info , List <Issue > issues , List <ResultSetParts > results ) {
30
+ private QueryReader (QueryInfo info , List <Issue > issues , List <ResultSetReader > results ) {
32
31
this .info = info ;
33
- this .isssues = issues ;
32
+ this .issues = issues ;
34
33
this .results = results ;
35
34
}
36
35
@@ -43,11 +42,11 @@ public int getResultSetCount() {
43
42
}
44
43
45
44
public ResultSetReader getResultSet (int index ) {
46
- return new CompositeResultSet ( results .get (index ). getParts () );
45
+ return results .get (index );
47
46
}
48
47
49
48
public List <Issue > getIssueList () {
50
- return this .isssues ;
49
+ return this .issues ;
51
50
}
52
51
53
52
public static CompletableFuture <Result <QueryReader >> readFrom (QueryStream stream ) {
@@ -57,45 +56,32 @@ public static CompletableFuture<Result<QueryReader>> readFrom(QueryStream stream
57
56
58
57
@ Override
59
58
public Iterator <ResultSetReader > iterator () {
60
- return new IteratorImpl (results .iterator ());
61
- }
62
-
63
- private class IteratorImpl implements Iterator <ResultSetReader > {
64
- private final Iterator <ResultSetParts > iter ;
65
-
66
- IteratorImpl (Iterator <ResultSetParts > iter ) {
67
- this .iter = iter ;
68
- }
69
-
70
- @ Override
71
- public boolean hasNext () {
72
- return iter .hasNext ();
73
- }
74
-
75
- @ Override
76
- public ResultSetReader next () {
77
- return new CompositeResultSet (iter .next ().getParts ());
78
- }
59
+ return results .iterator ();
79
60
}
80
61
81
62
private static class PartsCollector implements QueryStream .PartsHandler {
82
63
private final List <Issue > issueList = new ArrayList <>();
83
- private final SortedMap <Long , ResultSetParts > results = new TreeMap <>();
64
+ private final SortedMap <Long , List < QueryResultPart > > results = new TreeMap <>();
84
65
85
66
QueryReader toReader (QueryInfo info ) {
86
- List <ResultSetParts > ordered = new ArrayList <>();
67
+ List <List < QueryResultPart > > ordered = new ArrayList <>();
87
68
long lastInserted = 0 ;
88
- for (Map .Entry <Long , ResultSetParts > entry : results .entrySet ()) {
69
+ for (Map .Entry <Long , List < QueryResultPart > > entry : results .entrySet ()) {
89
70
long key = entry .getKey ();
90
71
while (lastInserted + 1 < key ) {
91
- ordered .add (new ResultSetParts ( lastInserted ));
72
+ ordered .add (new ArrayList <>( )); // add empty result for skipped indexes
92
73
lastInserted ++;
93
74
}
94
75
ordered .add (entry .getValue ());
95
76
lastInserted = key ;
96
77
}
97
78
98
- return new QueryReader (info , issueList , ordered );
79
+ List <ResultSetReader > resultsList = new ArrayList <>(ordered .size ());
80
+ for (List <QueryResultPart > queryResult : ordered ) {
81
+ resultsList .add (new CompositeResultSet (queryResult ));
82
+ }
83
+
84
+ return new QueryReader (info , issueList , resultsList );
99
85
}
100
86
101
87
@ Override
@@ -107,42 +93,27 @@ public void onIssues(Issue[] issues) {
107
93
public void onNextPart (QueryResultPart part ) {
108
94
Long index = part .getResultSetIndex ();
109
95
if (!results .containsKey (index )) {
110
- results .put (index , new ResultSetParts ( index ));
96
+ results .put (index , new ArrayList <>( ));
111
97
}
112
- results .get (index ).addPart (part );
113
- }
114
- }
115
-
116
- static class ResultSetParts {
117
- private final long resultSetIndex ;
118
- private final List <QueryResultPart > parts = new ArrayList <>();
119
-
120
- ResultSetParts (long index ) {
121
- this .resultSetIndex = index ;
122
- }
123
-
124
- public void addPart (QueryResultPart part ) {
125
- parts .add (part );
126
- }
127
-
128
- public long getIndex () {
129
- return resultSetIndex ;
130
- }
131
-
132
- public List <QueryResultPart > getParts () {
133
- return parts ;
98
+ results .get (index ).add (part );
134
99
}
135
100
}
136
101
137
102
private static class CompositeResultSet implements ResultSetReader {
138
- private final List < ResultSetReader > parts ;
103
+ private final ResultSetReader [] parts ;
139
104
private final int rowsCount ;
140
105
private int partIndex = -1 ;
141
106
142
107
CompositeResultSet (List <QueryResultPart > list ) {
143
- this .parts = list .stream ().map (QueryResultPart ::getResultSetReader ).collect (Collectors .toList ());
144
- this .rowsCount = list .stream ().mapToInt (QueryResultPart ::getResultSetRowsCount ).sum ();
145
- this .partIndex = parts .isEmpty () ? -1 : 0 ;
108
+ this .parts = new ResultSetReader [list .size ()];
109
+ int count = 0 ;
110
+ int idx = 0 ;
111
+ for (QueryResultPart part : list ) {
112
+ this .parts [idx ++] = part .getResultSetReader ();
113
+ count += part .getResultSetRowsCount ();
114
+ }
115
+ this .rowsCount = count ;
116
+ this .partIndex = list .isEmpty () ? -1 : 0 ;
146
117
}
147
118
148
119
@ Override
@@ -155,47 +126,47 @@ public int getColumnCount() {
155
126
if (partIndex < 0 ) {
156
127
return 0 ;
157
128
}
158
- return parts . get ( partIndex ) .getColumnCount ();
129
+ return parts [ partIndex ] .getColumnCount ();
159
130
}
160
131
161
132
@ Override
162
133
public String getColumnName (int index ) {
163
134
if (partIndex < 0 ) {
164
135
return null ;
165
136
}
166
- return parts . get ( partIndex ) .getColumnName (index );
137
+ return parts [ partIndex ] .getColumnName (index );
167
138
}
168
139
169
140
@ Override
170
141
public int getColumnIndex (String name ) {
171
142
if (partIndex < 0 ) {
172
143
return -1 ;
173
144
}
174
- return parts . get ( partIndex ) .getColumnIndex (name );
145
+ return parts [ partIndex ] .getColumnIndex (name );
175
146
}
176
147
177
148
@ Override
178
149
public ValueReader getColumn (int index ) {
179
150
if (partIndex < 0 ) {
180
151
return null ;
181
152
}
182
- return parts . get ( partIndex ) .getColumn (index );
153
+ return parts [ partIndex ] .getColumn (index );
183
154
}
184
155
185
156
@ Override
186
157
public ValueReader getColumn (String name ) {
187
158
if (partIndex < 0 ) {
188
159
return null ;
189
160
}
190
- return parts . get ( partIndex ) .getColumn (name );
161
+ return parts [ partIndex ] .getColumn (name );
191
162
}
192
163
193
164
@ Override
194
165
public Type getColumnType (int index ) {
195
166
if (partIndex < 0 ) {
196
167
return null ;
197
168
}
198
- return parts . get ( partIndex ) .getColumnType (index );
169
+ return parts [ partIndex ] .getColumnType (index );
199
170
}
200
171
201
172
@ Override
@@ -205,20 +176,32 @@ public int getRowCount() {
205
176
206
177
@ Override
207
178
public void setRowIndex (int index ) {
179
+ // TODO: Enable after JDBC fixing
180
+ // if (index < 0 || index >= rowsCount) {
181
+ // throw new IndexOutOfBoundsException(String.format("Index %s out of bounds for length %s",
182
+ // index, rowsCount));
183
+ // }
184
+ // int currentIdx = index;
185
+ int currentIdx = Math .max (0 , index );
208
186
partIndex = 0 ;
209
- int currentIdx = index ;
210
- while (partIndex < parts .size ()) {
211
- int readerRows = parts .get (partIndex ).getRowCount ();
187
+ while (partIndex < parts .length ) {
188
+ int readerRows = parts [partIndex ].getRowCount ();
212
189
if (currentIdx < readerRows ) {
213
- parts . get ( partIndex ) .setRowIndex (currentIdx );
190
+ parts [ partIndex ] .setRowIndex (currentIdx );
214
191
break ;
215
192
}
216
- parts . get ( partIndex ) .setRowIndex (readerRows - 1 );
193
+ parts [ partIndex ] .setRowIndex (readerRows );
217
194
currentIdx -= readerRows ;
218
195
partIndex ++;
219
196
}
220
- for (int partStep = partIndex + 1 ; partStep < parts .size (); partStep ++) {
221
- parts .get (partStep ).setRowIndex (0 );
197
+
198
+ // TODO: remove after JDBC fixing
199
+ if (partIndex >= parts .length ) {
200
+ partIndex = parts .length - 1 ;
201
+ }
202
+
203
+ for (int partStep = partIndex + 1 ; partStep < parts .length ; partStep ++) {
204
+ parts [partStep ].setRowIndex (0 );
222
205
}
223
206
}
224
207
@@ -227,10 +210,10 @@ public boolean next() {
227
210
if (partIndex < 0 ) {
228
211
return false ;
229
212
}
230
- boolean res = parts . get ( partIndex ) .next ();
231
- while (!res && partIndex < parts .size () - 1 ) {
213
+ boolean res = parts [ partIndex ] .next ();
214
+ while (!res && partIndex < parts .length - 1 ) {
232
215
partIndex ++;
233
- res = parts . get ( partIndex ) .next ();
216
+ res = parts [ partIndex ] .next ();
234
217
}
235
218
return res ;
236
219
}
0 commit comments