@@ -88,7 +88,7 @@ public void skipOnAborted() {
88
88
* This used to fail, but we've since compacted top n so it actually succeeds now.
89
89
*/
90
90
public void testSortByManyLongsSuccess () throws IOException {
91
- initManyLongs ();
91
+ initManyLongs (10 );
92
92
Map <String , Object > response = sortByManyLongs (500 );
93
93
ListMatcher columns = matchesList ().item (matchesMap ().entry ("name" , "a" ).entry ("type" , "long" ))
94
94
.item (matchesMap ().entry ("name" , "b" ).entry ("type" , "long" ));
@@ -105,7 +105,7 @@ public void testSortByManyLongsSuccess() throws IOException {
105
105
* This used to crash the node with an out of memory, but now it just trips a circuit breaker.
106
106
*/
107
107
public void testSortByManyLongsTooMuchMemory () throws IOException {
108
- initManyLongs ();
108
+ initManyLongs (10 );
109
109
// 5000 is plenty to break on most nodes
110
110
assertCircuitBreaks (attempt -> sortByManyLongs (attempt * 5000 ));
111
111
}
@@ -114,7 +114,7 @@ public void testSortByManyLongsTooMuchMemory() throws IOException {
114
114
* This should record an async response with a {@link CircuitBreakingException}.
115
115
*/
116
116
public void testSortByManyLongsTooMuchMemoryAsync () throws IOException {
117
- initManyLongs ();
117
+ initManyLongs (10 );
118
118
Request request = new Request ("POST" , "/_query/async" );
119
119
request .addParameter ("error_trace" , "" );
120
120
request .setJsonEntity (makeSortByManyLongs (5000 ).toString ().replace ("\n " , "\\ n" ));
@@ -191,6 +191,22 @@ public void testSortByManyLongsTooMuchMemoryAsync() throws IOException {
191
191
);
192
192
}
193
193
194
+ public void testSortByManyLongsGiantTopN () throws IOException {
195
+ initManyLongs (10 );
196
+ assertMap (
197
+ sortBySomeLongsLimit (100000 ),
198
+ matchesMap ().entry ("took" , greaterThan (0 ))
199
+ .entry ("is_partial" , false )
200
+ .entry ("columns" , List .of (Map .of ("name" , "MAX(a)" , "type" , "long" )))
201
+ .entry ("values" , List .of (List .of (9 )))
202
+ );
203
+ }
204
+
205
+ public void testStupidTopN () throws IOException {
206
+ initManyLongs (1 ); // Doesn't actually matter how much data there is.
207
+ assertCircuitBreaks (attempt -> sortBySomeLongsLimit (2147483630 ));
208
+ }
209
+
194
210
private static final int MAX_ATTEMPTS = 5 ;
195
211
196
212
interface TryCircuitBreaking {
@@ -249,11 +265,25 @@ private StringBuilder makeSortByManyLongs(int count) {
249
265
return query ;
250
266
}
251
267
268
+ private Map <String , Object > sortBySomeLongsLimit (int count ) throws IOException {
269
+ logger .info ("sorting by 5 longs, keeping {}" , count );
270
+ return responseAsMap (query (makeSortBySomeLongsLimit (count ), null ));
271
+ }
272
+
273
+ private String makeSortBySomeLongsLimit (int count ) {
274
+ StringBuilder query = new StringBuilder ("{\" query\" : \" FROM manylongs\n " );
275
+ query .append ("| SORT a, b, c, d, e\n " );
276
+ query .append ("| LIMIT " ).append (count ).append ("\n " );
277
+ query .append ("| STATS MAX(a)\n " );
278
+ query .append ("\" }" );
279
+ return query .toString ();
280
+ }
281
+
252
282
/**
253
283
* This groups on about 200 columns which is a lot but has never caused us trouble.
254
284
*/
255
285
public void testGroupOnSomeLongs () throws IOException {
256
- initManyLongs ();
286
+ initManyLongs (10 );
257
287
Response resp = groupOnManyLongs (200 );
258
288
Map <String , Object > map = responseAsMap (resp );
259
289
ListMatcher columns = matchesList ().item (matchesMap ().entry ("name" , "MAX(a)" ).entry ("type" , "long" ));
@@ -265,7 +295,7 @@ public void testGroupOnSomeLongs() throws IOException {
265
295
* This groups on 5000 columns which used to throw a {@link StackOverflowError}.
266
296
*/
267
297
public void testGroupOnManyLongs () throws IOException {
268
- initManyLongs ();
298
+ initManyLongs (10 );
269
299
Response resp = groupOnManyLongs (5000 );
270
300
Map <String , Object > map = responseAsMap (resp );
271
301
ListMatcher columns = matchesList ().item (matchesMap ().entry ("name" , "MAX(a)" ).entry ("type" , "long" ));
@@ -333,15 +363,15 @@ private Response concat(int evals) throws IOException {
333
363
*/
334
364
public void testManyConcat () throws IOException {
335
365
int strings = 300 ;
336
- initManyLongs ();
366
+ initManyLongs (10 );
337
367
assertManyStrings (manyConcat ("FROM manylongs" , strings ), strings );
338
368
}
339
369
340
370
/**
341
371
* Hits a circuit breaker by building many moderately long strings.
342
372
*/
343
373
public void testHugeManyConcat () throws IOException {
344
- initManyLongs ();
374
+ initManyLongs (10 );
345
375
// 2000 is plenty to break on most nodes
346
376
assertCircuitBreaks (attempt -> manyConcat ("FROM manylongs" , attempt * 2000 ));
347
377
}
@@ -412,15 +442,15 @@ private Map<String, Object> manyConcat(String init, int strings) throws IOExcept
412
442
*/
413
443
public void testManyRepeat () throws IOException {
414
444
int strings = 30 ;
415
- initManyLongs ();
445
+ initManyLongs (10 );
416
446
assertManyStrings (manyRepeat ("FROM manylongs" , strings ), 30 );
417
447
}
418
448
419
449
/**
420
450
* Hits a circuit breaker by building many moderately long strings.
421
451
*/
422
452
public void testHugeManyRepeat () throws IOException {
423
- initManyLongs ();
453
+ initManyLongs (10 );
424
454
// 75 is plenty to break on most nodes
425
455
assertCircuitBreaks (attempt -> manyRepeat ("FROM manylongs" , attempt * 75 ));
426
456
}
@@ -478,7 +508,7 @@ private void assertManyStrings(Map<String, Object> resp, int strings) throws IOE
478
508
}
479
509
480
510
public void testManyEval () throws IOException {
481
- initManyLongs ();
511
+ initManyLongs (10 );
482
512
Map <String , Object > response = manyEval (1 );
483
513
ListMatcher columns = matchesList ();
484
514
columns = columns .item (matchesMap ().entry ("name" , "a" ).entry ("type" , "long" ));
@@ -493,7 +523,7 @@ public void testManyEval() throws IOException {
493
523
}
494
524
495
525
public void testTooManyEval () throws IOException {
496
- initManyLongs ();
526
+ initManyLongs (10 );
497
527
// 490 is plenty to fail on most nodes
498
528
assertCircuitBreaks (attempt -> manyEval (attempt * 490 ));
499
529
}
@@ -756,24 +786,34 @@ private Map<String, Object> enrichExplosion(int sensorDataCount, int lookupEntri
756
786
}
757
787
}
758
788
759
- private void initManyLongs () throws IOException {
789
+ private void initManyLongs (int countPerLong ) throws IOException {
760
790
logger .info ("loading many documents with longs" );
761
791
StringBuilder bulk = new StringBuilder ();
762
- for (int a = 0 ; a < 10 ; a ++) {
763
- for (int b = 0 ; b < 10 ; b ++) {
764
- for (int c = 0 ; c < 10 ; c ++) {
765
- for (int d = 0 ; d < 10 ; d ++) {
766
- for (int e = 0 ; e < 10 ; e ++) {
792
+ int flush = 0 ;
793
+ for (int a = 0 ; a < countPerLong ; a ++) {
794
+ for (int b = 0 ; b < countPerLong ; b ++) {
795
+ for (int c = 0 ; c < countPerLong ; c ++) {
796
+ for (int d = 0 ; d < countPerLong ; d ++) {
797
+ for (int e = 0 ; e < countPerLong ; e ++) {
767
798
bulk .append (String .format (Locale .ROOT , """
768
799
{"create":{}}
769
800
{"a":%d,"b":%d,"c":%d,"d":%d,"e":%d}
770
801
""" , a , b , c , d , e ));
802
+ flush ++;
803
+ if (flush % 10_000 == 0 ) {
804
+ bulk ("manylongs" , bulk .toString ());
805
+ bulk .setLength (0 );
806
+ logger .info (
807
+ "flushing {}/{} to manylongs" ,
808
+ flush ,
809
+ countPerLong * countPerLong * countPerLong * countPerLong * countPerLong
810
+ );
811
+
812
+ }
771
813
}
772
814
}
773
815
}
774
816
}
775
- bulk ("manylongs" , bulk .toString ());
776
- bulk .setLength (0 );
777
817
}
778
818
initIndex ("manylongs" , bulk .toString ());
779
819
}
0 commit comments