@@ -75,6 +75,81 @@ fn test_basic_small() {
75
75
assert_eq ! ( map. remove( & 1 ) , None ) ;
76
76
}
77
77
78
+ #[ test]
79
+ fn test_query ( ) {
80
+ // NOTE: shouldn't need to test mutable variants because they're
81
+ // generated from the same template and deviate only in mutability
82
+ // annotations. However incorrect implementations *may* result from Node's
83
+ // mut and non-mut impls drifting.
84
+
85
+ let size = 10000 ;
86
+ let gap = 4 ;
87
+ let min = gap;
88
+ let max = ( size - 1 ) * gap;
89
+
90
+ let mut map = BTreeMap :: new ( ) ;
91
+
92
+ assert_eq ! ( map. min( ) , None ) ;
93
+ assert_eq ! ( map. max( ) , None ) ;
94
+ assert_eq ! ( map. get_lt( & 0 ) , None ) ;
95
+ assert_eq ! ( map. get_gt( & 0 ) , None ) ;
96
+ assert_eq ! ( map. get_le( & 0 ) , None ) ;
97
+ assert_eq ! ( map. get_ge( & 0 ) , None ) ;
98
+
99
+ // linear insertions make degenerate trees, but we shouldn't care since all
100
+ // large trees are structurally similar for these tests.
101
+ for i in 1 .. size {
102
+ // times 10 to make gaps
103
+ map. insert ( i * gap, i * gap) ;
104
+ }
105
+
106
+ assert_eq ! ( map. min( ) , Some ( ( & min, & min) ) ) ;
107
+ assert_eq ! ( map. max( ) , Some ( ( & max, & max) ) ) ;
108
+
109
+
110
+ // less exists checks
111
+ for i in min + 1 .. max + gap {
112
+ // gap = 4
113
+ // input: 5 6 7 8 9 10 11 12
114
+ // <= 4 4 4 8 8 8 8 12
115
+ // < 4 4 4 4 8 8 8 8
116
+ let le = i / gap * gap;
117
+ let lt = ( i - 1 ) / gap * gap;
118
+ assert_eq ! ( map. get_lt( & i) , Some ( ( & lt, & lt) ) ) ;
119
+ assert_eq ! ( map. get_le( & i) , Some ( ( & le, & le) ) ) ;
120
+ }
121
+
122
+ // greater exists checks
123
+ for i in min - gap .. max - 1 {
124
+ // gap = 4
125
+ // input: 4 5 6 7 8 9 10 11
126
+ // >= 4 8 8 8 8 12 12 12 (same as < but +4)
127
+ // > 8 8 8 8 12 12 12 12 (same as <= but +4)
128
+ let ge = ( i - 1 ) / gap * gap + gap;
129
+ let gt = i / gap * gap + gap;
130
+ assert_eq ! ( map. get_gt( & i) , Some ( ( & gt, & gt) ) ) ;
131
+ assert_eq ! ( map. get_ge( & i) , Some ( ( & ge, & ge) ) ) ;
132
+ }
133
+
134
+ // less doesn't exist checks
135
+ for i in 0 .. min {
136
+ assert_eq ! ( map. get_lt( & i) , None ) ;
137
+ assert_eq ! ( map. get_le( & i) , None ) ;
138
+ }
139
+
140
+ // greater doesn't exist checks
141
+ for i in max + 1 .. max + gap {
142
+ assert_eq ! ( map. get_gt( & i) , None ) ;
143
+ assert_eq ! ( map. get_ge( & i) , None ) ;
144
+ }
145
+
146
+ // special cases:
147
+ assert_eq ! ( map. get_lt( & min) , None ) ;
148
+ assert_eq ! ( map. get_le( & min) , Some ( ( & min, & min) ) ) ;
149
+ assert_eq ! ( map. get_gt( & max) , None ) ;
150
+ assert_eq ! ( map. get_ge( & max) , Some ( ( & max, & max) ) ) ;
151
+ }
152
+
78
153
#[ test]
79
154
fn test_iter ( ) {
80
155
let size = 10000 ;
@@ -297,20 +372,121 @@ fn test_extend_ref() {
297
372
mod bench {
298
373
use std:: collections:: BTreeMap ;
299
374
use std:: __rand:: { Rng , thread_rng} ;
375
+ use std:: collections:: Bound :: { Included , Excluded , Unbounded } ;
300
376
301
377
use test:: { Bencher , black_box} ;
302
378
379
+ fn get < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < & ' a V > {
380
+ map. get ( key)
381
+ }
382
+
383
+ fn get_lt < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
384
+ map. get_lt ( key)
385
+ }
386
+ fn get_le < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
387
+ map. get_le ( key)
388
+ }
389
+ fn get_gt < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
390
+ map. get_gt ( key)
391
+ }
392
+ fn get_ge < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
393
+ map. get_ge ( key)
394
+ }
395
+
396
+ fn get_lt_range < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
397
+ map. range ( Unbounded , Excluded ( key) ) . next_back ( )
398
+ }
399
+ fn get_le_range < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
400
+ map. range ( Unbounded , Included ( key) ) . next_back ( )
401
+ }
402
+ fn get_gt_range < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
403
+ map. range ( Excluded ( key) , Unbounded ) . next ( )
404
+ }
405
+ fn get_ge_range < ' a , K : Ord , V > ( map : & ' a BTreeMap < K , V > , key : & K ) -> Option < ( & ' a K , & ' a V ) > {
406
+ map. range ( Included ( key) , Unbounded ) . next ( )
407
+ }
408
+
409
+
303
410
map_insert_rand_bench ! { insert_rand_100, 100 , BTreeMap }
304
- map_insert_rand_bench ! { insert_rand_10_000 , 10_000 , BTreeMap }
411
+ map_insert_rand_bench ! { insert_rand_10000 , 10_000 , BTreeMap }
305
412
306
413
map_insert_seq_bench ! { insert_seq_100, 100 , BTreeMap }
307
- map_insert_seq_bench ! { insert_seq_10_000, 10_000 , BTreeMap }
414
+ map_insert_seq_bench ! { insert_seq_10000, 10_000 , BTreeMap }
415
+
416
+
417
+
418
+ map_find_rand_bench ! { get_rand_100_eq, 100 , BTreeMap , get}
419
+ map_find_rand_bench ! { get_rand_10000_eq, 10_000 , BTreeMap , get}
420
+
421
+ map_find_seq_bench ! { get_seq_100_eq, 100 , BTreeMap , get}
422
+ map_find_seq_bench ! { get_seq_10000_eq, 10_000 , BTreeMap , get}
423
+
424
+
425
+
426
+
427
+ map_find_rand_bench ! { get_rand_100_lt, 100 , BTreeMap , get_lt}
428
+ map_find_rand_bench ! { get_rand_10000_lt, 10_000 , BTreeMap , get_lt}
429
+
430
+ map_find_seq_bench ! { get_seq_100_lt, 100 , BTreeMap , get_lt}
431
+ map_find_seq_bench ! { get_seq_10000_lt, 10_000 , BTreeMap , get_lt}
432
+
433
+
434
+
435
+ map_find_rand_bench ! { get_rand_100_le, 100 , BTreeMap , get_le}
436
+ map_find_rand_bench ! { get_rand_10000_le, 10_000 , BTreeMap , get_le}
437
+
438
+ map_find_seq_bench ! { get_seq_100_le, 100 , BTreeMap , get_le}
439
+ map_find_seq_bench ! { get_seq_10000_le, 10_000 , BTreeMap , get_le}
440
+
441
+
442
+
443
+ map_find_rand_bench ! { get_rand_100_gt, 100 , BTreeMap , get_gt}
444
+ map_find_rand_bench ! { get_rand_10000_gt, 10_000 , BTreeMap , get_gt}
445
+
446
+ map_find_seq_bench ! { get_seq_100_gt, 100 , BTreeMap , get_gt}
447
+ map_find_seq_bench ! { get_seq_10000_gt, 10_000 , BTreeMap , get_gt}
448
+
449
+
450
+
451
+ map_find_rand_bench ! { get_rand_100_ge, 100 , BTreeMap , get_ge}
452
+ map_find_rand_bench ! { get_rand_10000_ge, 10_000 , BTreeMap , get_ge}
453
+
454
+ map_find_seq_bench ! { get_seq_100_ge, 100 , BTreeMap , get_ge}
455
+ map_find_seq_bench ! { get_seq_10000_ge, 10_000 , BTreeMap , get_ge}
456
+
457
+
458
+
308
459
309
- map_find_rand_bench ! { find_rand_100, 100 , BTreeMap }
310
- map_find_rand_bench ! { find_rand_10_000, 10_000 , BTreeMap }
460
+ map_find_rand_bench ! { get_rand_100_lt_range, 100 , BTreeMap , get_lt_range}
461
+ map_find_rand_bench ! { get_rand_10000_lt_range, 10_000 , BTreeMap , get_lt_range}
462
+
463
+ map_find_seq_bench ! { get_seq_100_lt_range, 100 , BTreeMap , get_lt_range}
464
+ map_find_seq_bench ! { get_seq_10000_lt_range, 10_000 , BTreeMap , get_lt_range}
465
+
466
+
467
+
468
+ map_find_rand_bench ! { get_rand_100_le_range, 100 , BTreeMap , get_le_range}
469
+ map_find_rand_bench ! { get_rand_10000_le_range, 10_000 , BTreeMap , get_le_range}
470
+
471
+ map_find_seq_bench ! { get_seq_100_le_range, 100 , BTreeMap , get_le_range}
472
+ map_find_seq_bench ! { get_seq_10000_le_range, 10_000 , BTreeMap , get_le_range}
473
+
474
+
475
+
476
+ map_find_rand_bench ! { get_rand_100_gt_range, 100 , BTreeMap , get_gt_range}
477
+ map_find_rand_bench ! { get_rand_10000_gt_range, 10_000 , BTreeMap , get_gt_range}
478
+
479
+ map_find_seq_bench ! { get_seq_100_gt_range, 100 , BTreeMap , get_gt_range}
480
+ map_find_seq_bench ! { get_seq_10000_gt_range, 10_000 , BTreeMap , get_gt_range}
481
+
482
+
483
+
484
+ map_find_rand_bench ! { get_rand_100_ge_range, 100 , BTreeMap , get_ge_range}
485
+ map_find_rand_bench ! { get_rand_10000_ge_range, 10_000 , BTreeMap , get_ge_range}
486
+
487
+ map_find_seq_bench ! { get_seq_100_ge_range, 100 , BTreeMap , get_ge_range}
488
+ map_find_seq_bench ! { get_seq_10000_ge_range, 10_000 , BTreeMap , get_ge_range}
311
489
312
- map_find_seq_bench ! { find_seq_100, 100 , BTreeMap }
313
- map_find_seq_bench ! { find_seq_10_000, 10_000 , BTreeMap }
314
490
315
491
fn bench_iter ( b : & mut Bencher , size : i32 ) {
316
492
let mut map = BTreeMap :: < i32 , i32 > :: new ( ) ;
@@ -327,18 +503,86 @@ mod bench {
327
503
} ) ;
328
504
}
329
505
506
+ fn bench_iter_with_queries_forward ( b : & mut Bencher , size : i32 ) {
507
+ let mut map = BTreeMap :: < i32 , i32 > :: new ( ) ;
508
+ let mut rng = thread_rng ( ) ;
509
+
510
+ for _ in 0 ..size {
511
+ map. insert ( rng. gen ( ) , rng. gen ( ) ) ;
512
+ }
513
+
514
+ b. iter ( || {
515
+ let entry = map. min ( ) . unwrap ( ) ;
516
+ black_box ( entry) ;
517
+ let mut min = entry. 0 ;
518
+ while let Some ( entry) = map. get_gt ( min) {
519
+ black_box ( entry) ;
520
+ min = entry. 0 ;
521
+ }
522
+ } ) ;
523
+ }
524
+
525
+ fn bench_iter_with_queries_backward ( b : & mut Bencher , size : i32 ) {
526
+ let mut map = BTreeMap :: < i32 , i32 > :: new ( ) ;
527
+ let mut rng = thread_rng ( ) ;
528
+
529
+ for _ in 0 ..size {
530
+ map. insert ( rng. gen ( ) , rng. gen ( ) ) ;
531
+ }
532
+
533
+ b. iter ( || {
534
+ let entry = map. max ( ) . unwrap ( ) ;
535
+ black_box ( entry) ;
536
+ let mut max = entry. 0 ;
537
+ while let Some ( entry) = map. get_lt ( max) {
538
+ black_box ( entry) ;
539
+ max = entry. 0 ;
540
+ }
541
+ } ) ;
542
+ }
543
+
330
544
#[ bench]
331
- pub fn iter_20 ( b : & mut Bencher ) {
545
+ pub fn iter_20_plain ( b : & mut Bencher ) {
332
546
bench_iter ( b, 20 ) ;
333
547
}
334
548
335
549
#[ bench]
336
- pub fn iter_1000 ( b : & mut Bencher ) {
550
+ pub fn iter_1000_plain ( b : & mut Bencher ) {
337
551
bench_iter ( b, 1000 ) ;
338
552
}
339
553
340
554
#[ bench]
341
- pub fn iter_100000 ( b : & mut Bencher ) {
555
+ pub fn iter_100000_plain ( b : & mut Bencher ) {
342
556
bench_iter ( b, 100000 ) ;
343
557
}
558
+
559
+ #[ bench]
560
+ pub fn iter_20_with_queries_forward ( b : & mut Bencher ) {
561
+ bench_iter_with_queries_forward ( b, 20 ) ;
562
+ }
563
+
564
+ #[ bench]
565
+ pub fn iter_1000_with_queries_forward ( b : & mut Bencher ) {
566
+ bench_iter_with_queries_forward ( b, 1000 ) ;
567
+ }
568
+
569
+ #[ bench]
570
+ pub fn iter_100000_with_queries_forward ( b : & mut Bencher ) {
571
+ bench_iter_with_queries_forward ( b, 100000 ) ;
572
+ }
573
+
574
+ #[ bench]
575
+ pub fn iter_20_with_queries_backward ( b : & mut Bencher ) {
576
+ bench_iter_with_queries_backward ( b, 20 ) ;
577
+ }
578
+
579
+ #[ bench]
580
+ pub fn iter_1000_with_queries_backward ( b : & mut Bencher ) {
581
+ bench_iter_with_queries_backward ( b, 1000 ) ;
582
+ }
583
+
584
+ #[ bench]
585
+ pub fn iter_100000_with_queries_backward ( b : & mut Bencher ) {
586
+ bench_iter_with_queries_backward ( b, 100000 ) ;
587
+ }
344
588
}
0 commit comments