github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/step/step_test.go (about) 1 // Copyright ©2012 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package step 6 7 import ( 8 "bytes" 9 "fmt" 10 "math" 11 "math/rand" 12 "reflect" 13 "testing" 14 15 "gopkg.in/check.v1" 16 ) 17 18 // Tests 19 func Test(t *testing.T) { check.TestingT(t) } 20 21 type S struct{} 22 23 var _ = check.Suite(&S{}) 24 25 type nilable int 26 27 func (n *nilable) Equal(e Equaler) bool { 28 return n == e.(*nilable) 29 } 30 31 func (s *S) TestCreate(c *check.C) { 32 _, err := New(0, 0, nil) 33 c.Check(err, check.ErrorMatches, ErrZeroLength.Error()) 34 for _, vec := range []struct { 35 start, end int 36 zero Equaler 37 }{ 38 {1, 10, (*nilable)(nil)}, 39 {0, 10, (*nilable)(nil)}, 40 {-1, 100, (*nilable)(nil)}, 41 {-100, -10, (*nilable)(nil)}, 42 {1, 10, Int(0)}, 43 {0, 10, Int(0)}, 44 {-1, 100, Int(0)}, 45 {-100, -10, Int(0)}, 46 } { 47 sv, err := New(vec.start, vec.end, vec.zero) 48 c.Assert(err, check.Equals, nil) 49 c.Check(sv.Start(), check.Equals, vec.start) 50 c.Check(sv.End(), check.Equals, vec.end) 51 c.Check(sv.Len(), check.Equals, vec.end-vec.start) 52 c.Check(sv.Zero, check.DeepEquals, vec.zero) 53 var at Equaler 54 for i := vec.start; i < vec.end; i++ { 55 at, err = sv.At(i) 56 c.Check(at, check.DeepEquals, vec.zero) 57 c.Check(err, check.Equals, nil) 58 } 59 _, err = sv.At(vec.start - 1) 60 c.Check(err, check.ErrorMatches, ErrOutOfRange.Error()) 61 _, err = sv.At(vec.start - 1) 62 c.Check(err, check.ErrorMatches, ErrOutOfRange.Error()) 63 } 64 } 65 66 func (s *S) TestSet_1(c *check.C) { 67 for i, t := range []struct { 68 start, end int 69 zero Equaler 70 sets []position 71 expect string 72 }{ 73 {1, 10, Int(0), 74 []position{ 75 {1, Int(2)}, 76 {2, Int(3)}, 77 {3, Int(3)}, 78 {4, Int(3)}, 79 {5, Int(2)}, 80 }, 81 "[1:2 2:3 5:2 6:0 10:<nil>]", 82 }, 83 {1, 10, Int(0), 84 []position{ 85 {3, Int(3)}, 86 {4, Int(3)}, 87 {1, Int(2)}, 88 {2, Int(3)}, 89 {5, Int(2)}, 90 }, 91 "[1:2 2:3 5:2 6:0 10:<nil>]", 92 }, 93 {1, 10, Int(0), 94 []position{ 95 {3, Int(3)}, 96 {4, Int(3)}, 97 {5, Int(2)}, 98 {1, Int(2)}, 99 {2, Int(3)}, 100 {9, Int(2)}, 101 }, 102 "[1:2 2:3 5:2 6:0 9:2 10:<nil>]", 103 }, 104 {1, 10, Float(0), 105 []position{ 106 {3, Float(math.NaN())}, 107 {4, Float(math.NaN())}, 108 {5, Float(2)}, 109 {1, Float(2)}, 110 {2, Float(math.NaN())}, 111 {9, Float(2)}, 112 }, 113 "[1:2 2:NaN 5:2 6:0 9:2 10:<nil>]", 114 }, 115 {1, 10, Float(math.NaN()), 116 []position{ 117 {3, Float(3)}, 118 {4, Float(3)}, 119 {5, Float(2)}, 120 {1, Float(2)}, 121 {2, Float(3)}, 122 {9, Float(2)}, 123 }, 124 "[1:2 2:3 5:2 6:NaN 9:2 10:<nil>]", 125 }, 126 } { 127 sv, err := New(t.start, t.end, t.zero) 128 c.Assert(err, check.Equals, nil) 129 c.Check(func() { sv.Set(t.start-1, nil) }, check.Panics, ErrOutOfRange) 130 c.Check(func() { sv.Set(t.end, nil) }, check.Panics, ErrOutOfRange) 131 for _, v := range t.sets { 132 sv.Set(v.pos, v.val) 133 c.Check(sv.min.pos, check.Equals, t.start) 134 c.Check(sv.max.pos, check.Equals, t.end) 135 c.Check(sv.Len(), check.Equals, t.end-t.start) 136 } 137 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 138 sv.Relaxed = true 139 sv.Set(t.start-1, sv.Zero) 140 sv.Set(t.end, sv.Zero) 141 c.Check(sv.Len(), check.Equals, t.end-t.start+2) 142 for _, v := range t.sets { 143 sv.Set(v.pos, t.zero) 144 } 145 sv.Set(t.start-1, t.zero) 146 sv.Set(t.end, t.zero) 147 c.Check(sv.t.Len(), check.Equals, 2) 148 c.Check(sv.String(), check.Equals, fmt.Sprintf("[%d:%v %d:%v]", t.start-1, t.zero, t.end+1, nil)) 149 } 150 } 151 152 func (s *S) TestSet_2(c *check.C) { 153 for i, t := range []struct { 154 start, end int 155 zero Int 156 sets []position 157 expect string 158 count int 159 }{ 160 {1, 2, 0, 161 []position{ 162 {1, Int(2)}, 163 {2, Int(3)}, 164 {3, Int(3)}, 165 {4, Int(3)}, 166 {5, Int(2)}, 167 {-1, Int(5)}, 168 {10, Int(23)}, 169 }, 170 "[-1:5 0:0 1:2 2:3 5:2 6:0 10:23 11:<nil>]", 171 7, 172 }, 173 {1, 10, 0, 174 []position{ 175 {0, Int(0)}, 176 }, 177 "[0:0 10:<nil>]", 178 1, 179 }, 180 {1, 10, 0, 181 []position{ 182 {-1, Int(0)}, 183 }, 184 "[-1:0 10:<nil>]", 185 1, 186 }, 187 {1, 10, 0, 188 []position{ 189 {11, Int(0)}, 190 }, 191 "[1:0 12:<nil>]", 192 1, 193 }, 194 {1, 10, 0, 195 []position{ 196 {2, Int(1)}, 197 {3, Int(1)}, 198 {4, Int(1)}, 199 {5, Int(1)}, 200 {6, Int(1)}, 201 {7, Int(1)}, 202 {8, Int(1)}, 203 {5, Int(1)}, 204 }, 205 "[1:0 2:1 9:0 10:<nil>]", 206 3, 207 }, 208 {1, 10, 0, 209 []position{ 210 {3, Int(1)}, 211 {2, Int(1)}, 212 }, 213 "[1:0 2:1 4:0 10:<nil>]", 214 3, 215 }, 216 } { 217 sv, err := New(t.start, t.end, t.zero) 218 c.Assert(err, check.Equals, nil) 219 sv.Relaxed = true 220 for _, v := range t.sets { 221 sv.Set(v.pos, v.val) 222 } 223 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 224 c.Check(sv.Count(), check.Equals, t.count) 225 } 226 } 227 228 func (s *S) TestSetRange_0(c *check.C) { 229 type posRange struct { 230 start, end int 231 val Int 232 } 233 for i, t := range []struct { 234 start, end int 235 zero Int 236 sets []posRange 237 expect string 238 count int 239 }{ 240 // Left overhang 241 {1, 10, 0, 242 []posRange{ 243 {-2, 0, 1}, 244 }, 245 "[-2:1 0:0 10:<nil>]", 246 2, 247 }, 248 {1, 10, 0, 249 []posRange{ 250 {-2, 0, 0}, 251 }, 252 "[-2:0 10:<nil>]", 253 1, 254 }, 255 {1, 10, 0, 256 []posRange{ 257 {-1, 1, 1}, 258 }, 259 "[-1:1 1:0 10:<nil>]", 260 2, 261 }, 262 {1, 10, 0, 263 []posRange{ 264 {-1, 1, 0}, 265 }, 266 "[-1:0 10:<nil>]", 267 1, 268 }, 269 {1, 10, 0, 270 []posRange{ 271 {-1, 2, 1}, 272 }, 273 "[-1:1 2:0 10:<nil>]", 274 2, 275 }, 276 {1, 10, 0, 277 []posRange{ 278 {-1, 2, 0}, 279 }, 280 "[-1:0 10:<nil>]", 281 1, 282 }, 283 284 // Right overhang 285 {1, 10, 0, 286 []posRange{ 287 {11, 12, 1}, 288 }, 289 "[1:0 11:1 12:<nil>]", 290 2, 291 }, 292 {1, 10, 0, 293 []posRange{ 294 {11, 12, 0}, 295 }, 296 "[1:0 12:<nil>]", 297 1, 298 }, 299 {1, 10, 0, 300 []posRange{ 301 {11, 13, 1}, 302 }, 303 "[1:0 11:1 13:<nil>]", 304 2, 305 }, 306 {1, 10, 0, 307 []posRange{ 308 {11, 13, 0}, 309 }, 310 "[1:0 13:<nil>]", 311 1, 312 }, 313 {1, 10, 0, 314 []posRange{ 315 {1, 10, 1}, 316 {11, 13, 1}, 317 }, 318 "[1:1 10:0 11:1 13:<nil>]", 319 3, 320 }, 321 {1, 10, 0, 322 []posRange{ 323 {1, 10, 1}, 324 {11, 13, 0}, 325 }, 326 "[1:1 10:0 13:<nil>]", 327 2, 328 }, 329 {1, 10, 0, 330 []posRange{ 331 {10, 11, 1}, 332 }, 333 "[1:0 10:1 11:<nil>]", 334 2, 335 }, 336 {1, 10, 0, 337 []posRange{ 338 {10, 11, 0}, 339 }, 340 "[1:0 11:<nil>]", 341 1, 342 }, 343 {1, 10, 0, 344 []posRange{ 345 {9, 11, 1}, 346 }, 347 "[1:0 9:1 11:<nil>]", 348 2, 349 }, 350 {1, 10, 0, 351 []posRange{ 352 {9, 11, 0}, 353 }, 354 "[1:0 11:<nil>]", 355 1, 356 }, 357 } { 358 sv, err := New(t.start, t.end, t.zero) 359 c.Assert(err, check.Equals, nil) 360 sv.Relaxed = true 361 c.Logf("subtest %d process", i) 362 for _, v := range t.sets { 363 in := fmt.Sprint(sv) 364 sv.SetRange(v.start, v.end, v.val) 365 c.Logf(" %s --%+v-> %s min:%+v max:%+v", in, v, sv, *sv.min, *sv.max) 366 } 367 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 368 c.Check(sv.Count(), check.Equals, t.count) 369 } 370 } 371 372 func (s *S) TestSetRange_1(c *check.C) { 373 type posRange struct { 374 start, end int 375 val Int 376 } 377 for i, t := range []struct { 378 start, end int 379 zero Int 380 sets []posRange 381 expect string 382 count int 383 }{ 384 {1, 10, 0, 385 []posRange{ 386 {1, 2, 2}, 387 {2, 3, 3}, 388 {3, 4, 3}, 389 {4, 5, 3}, 390 {5, 6, 2}, 391 }, 392 "[1:2 2:3 5:2 6:0 10:<nil>]", 393 4, 394 }, 395 {1, 10, 0, 396 []posRange{ 397 {3, 4, 3}, 398 {4, 5, 3}, 399 {1, 2, 2}, 400 {2, 3, 3}, 401 {5, 6, 2}, 402 }, 403 "[1:2 2:3 5:2 6:0 10:<nil>]", 404 4, 405 }, 406 {1, 10, 0, 407 []posRange{ 408 {3, 4, 3}, 409 {4, 5, 3}, 410 {5, 6, 2}, 411 {1, 2, 2}, 412 {2, 3, 3}, 413 {9, 10, 2}, 414 }, 415 "[1:2 2:3 5:2 6:0 9:2 10:<nil>]", 416 5, 417 }, 418 {1, 10, 0, 419 []posRange{ 420 {3, 6, 3}, 421 {4, 5, 1}, 422 {5, 7, 2}, 423 {1, 3, 2}, 424 {9, 10, 2}, 425 }, 426 "[1:2 3:3 4:1 5:2 7:0 9:2 10:<nil>]", 427 6, 428 }, 429 {1, 10, 0, 430 []posRange{ 431 {1, 3, 3}, 432 {4, 5, 1}, 433 {7, 8, 2}, 434 {9, 10, 4}, 435 }, 436 "[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]", 437 7, 438 }, 439 } { 440 sv, err := New(t.start, t.end, t.zero) 441 c.Assert(err, check.Equals, nil) 442 c.Check(func() { sv.SetRange(t.start-2, t.start, nil) }, check.Panics, ErrOutOfRange) 443 c.Check(func() { sv.SetRange(t.end, t.end+2, nil) }, check.Panics, ErrOutOfRange) 444 for _, v := range t.sets { 445 sv.SetRange(v.start, v.end, v.val) 446 c.Check(sv.min.pos, check.Equals, t.start) 447 c.Check(sv.max.pos, check.Equals, t.end) 448 c.Check(sv.Len(), check.Equals, t.end-t.start) 449 } 450 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 451 c.Check(sv.Count(), check.Equals, t.count) 452 sv.Relaxed = true 453 sv.SetRange(t.start-1, t.start, sv.Zero) 454 sv.SetRange(t.end, t.end+1, sv.Zero) 455 c.Check(sv.Len(), check.Equals, t.end-t.start+2) 456 sv.SetRange(t.start-1, t.end+1, t.zero) 457 c.Check(sv.t.Len(), check.Equals, 2) 458 c.Check(sv.String(), check.Equals, fmt.Sprintf("[%d:%v %d:%v]", t.start-1, t.zero, t.end+1, nil)) 459 } 460 } 461 462 func (s *S) TestSetRange_2(c *check.C) { 463 sv, _ := New(0, 1, nil) 464 c.Check(func() { sv.SetRange(1, 0, nil) }, check.Panics, ErrInvertedRange) 465 type posRange struct { 466 start, end int 467 val Int 468 } 469 for i, t := range []struct { 470 start, end int 471 zero Int 472 sets []posRange 473 expect string 474 }{ 475 {1, 10, 0, 476 []posRange{ 477 {1, 2, 2}, 478 {2, 3, 3}, 479 {3, 4, 3}, 480 {4, 5, 3}, 481 {5, 6, 2}, 482 {-10, -1, 4}, 483 {23, 35, 10}, 484 }, 485 "[-10:4 -1:0 1:2 2:3 5:2 6:0 23:10 35:<nil>]", 486 }, 487 {1, 2, 0, 488 []posRange{ 489 {1, 1, 2}, 490 }, 491 "[1:0 2:<nil>]", 492 }, 493 {1, 10, 0, 494 []posRange{ 495 {-10, 1, 0}, 496 }, 497 "[-10:0 10:<nil>]", 498 }, 499 {1, 10, 0, 500 []posRange{ 501 {-10, 1, 1}, 502 }, 503 "[-10:1 1:0 10:<nil>]", 504 }, 505 {1, 10, 0, 506 []posRange{ 507 {-10, 0, 1}, 508 }, 509 "[-10:1 0:0 10:<nil>]", 510 }, 511 {1, 10, 0, 512 []posRange{ 513 {-10, 0, 0}, 514 }, 515 "[-10:0 10:<nil>]", 516 }, 517 {1, 10, 0, 518 []posRange{ 519 {10, 20, 0}, 520 }, 521 "[1:0 20:<nil>]", 522 }, 523 {1, 10, 0, 524 []posRange{ 525 {10, 20, 1}, 526 }, 527 "[1:0 10:1 20:<nil>]", 528 }, 529 {1, 10, 0, 530 []posRange{ 531 {11, 20, 0}, 532 }, 533 "[1:0 20:<nil>]", 534 }, 535 {1, 10, 0, 536 []posRange{ 537 {11, 20, 1}, 538 }, 539 "[1:0 11:1 20:<nil>]", 540 }, 541 {1, 10, 0, 542 []posRange{ 543 {1, 10, 1}, 544 {11, 20, 1}, 545 }, 546 "[1:1 10:0 11:1 20:<nil>]", 547 }, 548 {1, 10, 0, 549 []posRange{ 550 {2, 5, 1}, 551 {2, 5, 0}, 552 }, 553 "[1:0 10:<nil>]", 554 }, 555 {1, 10, 0, 556 []posRange{ 557 {2, 6, 1}, 558 {2, 5, 0}, 559 }, 560 "[1:0 5:1 6:0 10:<nil>]", 561 }, 562 {1, 10, 0, 563 []posRange{ 564 {1, 3, 1}, 565 {5, 7, 2}, 566 {3, 5, 1}, 567 }, 568 "[1:1 5:2 7:0 10:<nil>]", 569 }, 570 {1, 10, 0, 571 []posRange{ 572 {1, 3, 1}, 573 {5, 7, 2}, 574 {3, 5, 2}, 575 }, 576 "[1:1 3:2 7:0 10:<nil>]", 577 }, 578 {1, 10, 0, 579 []posRange{ 580 {2, 5, 1}, 581 {2, 6, 0}, 582 }, 583 "[1:0 10:<nil>]", 584 }, 585 {1, 10, 0, 586 []posRange{ 587 {2, 6, 1}, 588 {2, 5, 0}, 589 }, 590 "[1:0 5:1 6:0 10:<nil>]", 591 }, 592 {1, 10, 0, 593 []posRange{ 594 {2, 5, 1}, 595 {2, 5, 2}, 596 }, 597 "[1:0 2:2 5:0 10:<nil>]", 598 }, 599 {1, 10, 0, 600 []posRange{ 601 {2, 5, 1}, 602 {3, 5, 2}, 603 }, 604 "[1:0 2:1 3:2 5:0 10:<nil>]", 605 }, 606 {1, 10, 0, 607 []posRange{ 608 {2, 5, 1}, 609 {3, 5, 0}, 610 }, 611 "[1:0 2:1 3:0 10:<nil>]", 612 }, 613 {1, 10, 0, 614 []posRange{ 615 {5, 20, 1}, 616 }, 617 "[1:0 5:1 20:<nil>]", 618 }, 619 {1, 10, 0, 620 []posRange{ 621 {5, 10, 1}, 622 }, 623 "[1:0 5:1 10:<nil>]", 624 }, 625 {5, 10, 0, 626 []posRange{ 627 {5, 10, 1}, 628 {1, 4, 1}, 629 }, 630 "[1:1 4:0 5:1 10:<nil>]", 631 }, 632 {1, 4, 0, 633 []posRange{ 634 {1, 4, 1}, 635 {5, 10, 1}, 636 }, 637 "[1:1 4:0 5:1 10:<nil>]", 638 }, 639 } { 640 sv, err := New(t.start, t.end, t.zero) 641 c.Assert(err, check.Equals, nil) 642 sv.Relaxed = true 643 for _, v := range t.sets { 644 sv.SetRange(v.start, v.end, v.val) 645 } 646 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 647 } 648 } 649 650 func (s *S) TestStepAt(c *check.C) { 651 type posRange struct { 652 start, end int 653 val Int 654 } 655 t := struct { 656 start, end int 657 zero Int 658 sets []posRange 659 expect string 660 }{1, 10, 0, 661 []posRange{ 662 {1, 3, 3}, 663 {4, 5, 1}, 664 {7, 8, 2}, 665 {9, 10, 4}, 666 }, 667 "[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]", 668 } 669 670 sv, err := New(t.start, t.end, t.zero) 671 c.Assert(err, check.Equals, nil) 672 for _, v := range t.sets { 673 sv.SetRange(v.start, v.end, v.val) 674 } 675 c.Check(sv.String(), check.Equals, t.expect) 676 for i, v := range t.sets { 677 for j := v.start; j < v.end; j++ { 678 st, en, at, err := sv.StepAt(v.start) 679 c.Check(err, check.Equals, nil) 680 c.Check(at, check.DeepEquals, v.val) 681 c.Check(st, check.Equals, v.start) 682 c.Check(en, check.Equals, v.end) 683 } 684 st, en, at, err := sv.StepAt(v.end) 685 if v.end < sv.End() { 686 c.Check(err, check.Equals, nil) 687 c.Check(at, check.DeepEquals, sv.Zero) 688 c.Check(st, check.Equals, v.end) 689 c.Check(en, check.Equals, t.sets[i+1].start) 690 } else { 691 c.Check(err, check.ErrorMatches, ErrOutOfRange.Error()) 692 } 693 } 694 _, _, _, err = sv.StepAt(t.start - 1) 695 c.Check(err, check.ErrorMatches, ErrOutOfRange.Error()) 696 } 697 698 func (s *S) TestDo(c *check.C) { 699 var data interface{} 700 type posRange struct { 701 start, end int 702 val Int 703 } 704 for i, t := range []struct { 705 start, end int 706 zero Int 707 relaxed bool 708 sets []posRange 709 setup func() 710 fn Operation 711 expect interface{} 712 }{ 713 {1, 10, 0, false, 714 []posRange{ 715 {1, 3, 3}, 716 {4, 5, 1}, 717 {7, 8, 2}, 718 {9, 10, 4}, 719 }, 720 func() { data = []Int(nil) }, 721 func(start, end int, vi Equaler) { 722 sl := data.([]Int) 723 v := vi.(Int) 724 for i := start; i < end; i++ { 725 sl = append(sl, v) 726 } 727 data = sl 728 }, 729 []Int{3, 3, 0, 1, 0, 0, 2, 0, 4}, 730 }, 731 {5, 10, 0, true, 732 []posRange{ 733 {5, 10, 1}, 734 {1, 7, 1}, 735 }, 736 func() { data = []Int(nil) }, 737 func(start, end int, vi Equaler) { 738 sl := data.([]Int) 739 v := vi.(Int) 740 for i := start; i < end; i++ { 741 sl = append(sl, v) 742 } 743 data = sl 744 }, 745 []Int{1, 1, 1, 1, 1, 1, 1, 1, 1}, 746 }, 747 {5, 10, 0, true, 748 []posRange{ 749 {5, 10, 1}, 750 {3, 7, 1}, 751 {1, 3, 1}, 752 }, 753 func() { data = []Int(nil) }, 754 func(start, end int, vi Equaler) { 755 sl := data.([]Int) 756 v := vi.(Int) 757 for i := start; i < end; i++ { 758 sl = append(sl, v) 759 } 760 data = sl 761 }, 762 []Int{1, 1, 1, 1, 1, 1, 1, 1, 1}, 763 }, 764 } { 765 t.setup() 766 sv, err := New(t.start, t.end, t.zero) 767 sv.Relaxed = t.relaxed 768 c.Assert(err, check.Equals, nil) 769 for _, v := range t.sets { 770 sv.SetRange(v.start, v.end, v.val) 771 } 772 sv.Do(t.fn) 773 c.Check(data, check.DeepEquals, t.expect, check.Commentf("subtest %d", i)) 774 c.Check(reflect.ValueOf(data).Len(), check.Equals, sv.Len()) 775 } 776 } 777 778 func (s *S) TestDoRange(c *check.C) { 779 var data interface{} 780 type posRange struct { 781 start, end int 782 val Int 783 } 784 for i, t := range []struct { 785 start, end int 786 zero Int 787 sets []posRange 788 setup func() 789 fn Operation 790 from, to int 791 expect interface{} 792 err error 793 }{ 794 {1, 10, 0, 795 []posRange{ 796 {1, 3, 3}, 797 {4, 5, 1}, 798 {7, 8, 2}, 799 {9, 10, 4}, 800 }, 801 func() { data = []Int(nil) }, 802 func(start, end int, vi Equaler) { 803 sl := data.([]Int) 804 v := vi.(Int) 805 for i := start; i < end; i++ { 806 sl = append(sl, v) 807 } 808 data = sl 809 }, 810 2, 8, 811 []Int{3, 0, 1, 0, 0, 2}, 812 nil, 813 }, 814 {1, 10, 0, 815 []posRange{ 816 {1, 3, 3}, 817 {4, 5, 1}, 818 {7, 8, 2}, 819 {9, 10, 4}, 820 }, 821 func() { data = []Int(nil) }, 822 func(_, _ int, _ Equaler) {}, 823 -2, -1, 824 []Int(nil), 825 ErrOutOfRange, 826 }, 827 {1, 10, 0, 828 []posRange{ 829 {1, 3, 3}, 830 {4, 5, 1}, 831 {7, 8, 2}, 832 {9, 10, 4}, 833 }, 834 func() { data = []Int(nil) }, 835 func(_, _ int, _ Equaler) {}, 836 10, 1, 837 []Int(nil), 838 ErrInvertedRange, 839 }, 840 } { 841 t.setup() 842 sv, err := New(t.start, t.end, t.zero) 843 c.Assert(err, check.Equals, nil) 844 for _, v := range t.sets { 845 sv.SetRange(v.start, v.end, v.val) 846 } 847 c.Check(sv.DoRange(t.from, t.to, t.fn), check.DeepEquals, t.err) 848 c.Check(data, check.DeepEquals, t.expect, check.Commentf("subtest %d", i)) 849 if t.from <= t.to && t.from < sv.End() && t.to > sv.Start() { 850 c.Check(reflect.ValueOf(data).Len(), check.Equals, t.to-t.from) 851 } 852 } 853 } 854 855 func (s *S) TestApply(c *check.C) { 856 type posRange struct { 857 start, end int 858 val Equaler 859 } 860 for i, t := range []struct { 861 start, end int 862 zero Equaler 863 sets []posRange 864 mutate Mutator 865 expect string 866 }{ 867 {1, 10, Int(0), 868 []posRange{ 869 {1, 3, Int(3)}, 870 {4, 5, Int(1)}, 871 {7, 8, Int(2)}, 872 {9, 10, Int(4)}, 873 }, 874 IncInt, 875 "[1:4 3:1 4:2 5:1 7:3 8:1 9:5 10:<nil>]", 876 }, 877 {1, 10, Int(0), 878 []posRange{ 879 {1, 3, Int(3)}, 880 {4, 5, Int(1)}, 881 {7, 8, Int(2)}, 882 {9, 10, Int(4)}, 883 }, 884 DecInt, 885 "[1:2 3:-1 4:0 5:-1 7:1 8:-1 9:3 10:<nil>]", 886 }, 887 {1, 10, Float(0), 888 []posRange{ 889 {1, 3, Float(3)}, 890 {4, 5, Float(1)}, 891 {7, 8, Float(2)}, 892 {9, 10, Float(4)}, 893 }, 894 IncFloat, 895 "[1:4 3:1 4:2 5:1 7:3 8:1 9:5 10:<nil>]", 896 }, 897 {1, 10, Float(0), 898 []posRange{ 899 {1, 3, Float(3)}, 900 {4, 5, Float(1)}, 901 {7, 8, Float(2)}, 902 {9, 10, Float(4)}, 903 }, 904 DecFloat, 905 "[1:2 3:-1 4:0 5:-1 7:1 8:-1 9:3 10:<nil>]", 906 }, 907 {1, 10, Int(0), 908 []posRange{ 909 {1, 3, Int(3)}, 910 {4, 5, Int(1)}, 911 {7, 8, Int(2)}, 912 {9, 10, Int(4)}, 913 }, 914 func(_ Equaler) Equaler { return Int(0) }, 915 "[1:0 10:<nil>]", 916 }, 917 } { 918 sv, err := New(t.start, t.end, t.zero) 919 c.Assert(err, check.Equals, nil) 920 for _, v := range t.sets { 921 sv.SetRange(v.start, v.end, v.val) 922 } 923 sv.Apply(t.mutate) 924 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 925 } 926 } 927 928 func (s *S) TestMutateRange(c *check.C) { 929 type posRange struct { 930 start, end int 931 val Int 932 } 933 for i, t := range []struct { 934 start, end int 935 zero Int 936 sets []posRange 937 mutate Mutator 938 from, to int 939 expect string 940 err error 941 }{ 942 {1, 10, 0, 943 []posRange{ 944 {1, 3, 3}, 945 {4, 5, 1}, 946 {7, 8, 2}, 947 {9, 10, 4}, 948 }, 949 IncInt, 950 2, 8, 951 "[1:3 2:4 3:1 4:2 5:1 7:3 8:0 9:4 10:<nil>]", 952 nil, 953 }, 954 {1, 10, 0, 955 []posRange{ 956 {1, 3, 3}, 957 {7, 8, 2}, 958 {9, 10, 4}, 959 }, 960 IncInt, 961 4, 6, 962 "[1:3 3:0 4:1 6:0 7:2 8:0 9:4 10:<nil>]", 963 nil, 964 }, 965 {1, 10, 0, 966 []posRange{ 967 {1, 3, 3}, 968 {7, 8, 1}, 969 {9, 10, 4}, 970 }, 971 IncInt, 972 4, 7, 973 "[1:3 3:0 4:1 8:0 9:4 10:<nil>]", 974 nil, 975 }, 976 {1, 10, 0, 977 []posRange{ 978 {1, 3, 3}, 979 {4, 5, 1}, 980 {7, 8, 2}, 981 {9, 10, 4}, 982 }, 983 func(_ Equaler) Equaler { return Int(0) }, 984 2, 8, 985 "[1:3 2:0 9:4 10:<nil>]", 986 nil, 987 }, 988 {1, 10, 0, 989 []posRange{ 990 {1, 3, 3}, 991 {4, 5, 1}, 992 {7, 9, 2}, 993 {9, 10, 4}, 994 }, 995 func(_ Equaler) Equaler { return Int(0) }, 996 2, 8, 997 "[1:3 2:0 8:2 9:4 10:<nil>]", 998 nil, 999 }, 1000 {1, 10, 0, 1001 []posRange{ 1002 {1, 3, 3}, 1003 {7, 8, 1}, 1004 {9, 10, 4}, 1005 }, 1006 IncInt, 1007 4, 8, 1008 "[1:3 3:0 4:1 7:2 8:0 9:4 10:<nil>]", 1009 nil, 1010 }, 1011 {1, 20, 0, 1012 []posRange{ 1013 {5, 10, 1}, 1014 {10, 15, 2}, 1015 {15, 20, 3}, 1016 }, 1017 func(v Equaler) Equaler { 1018 if v.Equal(Int(3)) { 1019 return Int(1) 1020 } 1021 return v 1022 }, 1023 8, 18, 1024 "[1:0 5:1 10:2 15:1 18:3 20:<nil>]", 1025 nil, 1026 }, 1027 {1, 20, 0, 1028 []posRange{ 1029 {1, 6, 1}, 1030 {6, 15, 2}, 1031 {15, 20, 1}, 1032 }, 1033 func(v Equaler) Equaler { 1034 return Int(2) 1035 }, 1036 4, 12, 1037 "[1:1 4:2 15:1 20:<nil>]", 1038 nil, 1039 }, 1040 {1, 10, 0, 1041 []posRange{ 1042 {1, 3, 3}, 1043 {4, 5, 1}, 1044 {7, 8, 2}, 1045 {9, 10, 4}, 1046 }, 1047 IncInt, 1048 -1, 0, 1049 "[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]", 1050 ErrOutOfRange, 1051 }, 1052 {1, 10, 0, 1053 []posRange{ 1054 {1, 3, 3}, 1055 {4, 5, 1}, 1056 {7, 8, 2}, 1057 {9, 10, 4}, 1058 }, 1059 IncInt, 1060 10, 1, 1061 "[1:3 3:0 4:1 5:0 7:2 8:0 9:4 10:<nil>]", 1062 ErrInvertedRange, 1063 }, 1064 } { 1065 sv, err := New(t.start, t.end, t.zero) 1066 c.Assert(err, check.Equals, nil) 1067 for _, v := range t.sets { 1068 sv.SetRange(v.start, v.end, v.val) 1069 } 1070 c.Check(sv.ApplyRange(t.from, t.to, t.mutate), check.DeepEquals, t.err) 1071 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 1072 } 1073 } 1074 1075 // pair is a [2]bool type satisfying the step.Equaler interface. 1076 type pair [2]bool 1077 1078 // Equal returns whether p equals e. Equal assumes the underlying type of e is pair. 1079 func (p pair) Equal(e Equaler) bool { 1080 return p == e.(pair) 1081 } 1082 1083 func (s *S) TestMutateRangePartial(c *check.C) { 1084 type posRange struct { 1085 start, end int 1086 val pair 1087 } 1088 for i, t := range []struct { 1089 start, end int 1090 zero pair 1091 sets []posRange 1092 mutate Mutator 1093 from, to int 1094 expect string 1095 err error 1096 }{ 1097 {94, 301, pair{}, 1098 []posRange{ 1099 {94, 120, pair{false, false}}, 1100 {120, 134, pair{false, true}}, 1101 {134, 301, pair{false, false}}, 1102 }, 1103 func(e Equaler) Equaler { 1104 p := e.(pair) 1105 p[1] = true 1106 return p 1107 }, 1108 113, 130, 1109 "[94:[false false] 113:[false true] 134:[false false] 301:<nil>]", 1110 nil, 1111 }, 1112 {253121, 253565, pair{}, 1113 []posRange{ 1114 {253121, 253565, pair{false, true}}, 1115 }, 1116 func(e Equaler) Equaler { 1117 p := e.(pair) 1118 p[1] = true 1119 return p 1120 }, 1121 253115, 253565, 1122 "[253115:[false true] 253565:<nil>]", 1123 nil, 1124 }, 1125 {253121, 253565, pair{}, 1126 []posRange{ 1127 {253121, 253565, pair{false, true}}, 1128 }, 1129 func(e Equaler) Equaler { 1130 p := e.(pair) 1131 p[1] = true 1132 return p 1133 }, 1134 253121, 253575, 1135 "[253121:[false true] 253575:<nil>]", 1136 nil, 1137 }, 1138 {253121, 253565, pair{}, 1139 []posRange{ 1140 {253121, 253565, pair{false, true}}, 1141 }, 1142 func(e Equaler) Equaler { 1143 p := e.(pair) 1144 p[1] = true 1145 return p 1146 }, 1147 253115, 253575, 1148 "[253115:[false true] 253575:<nil>]", 1149 nil, 1150 }, 1151 {0, 13, pair{}, 1152 []posRange{ 1153 {0, 1, pair{false, false}}, 1154 {1, 2, pair{false, true}}, 1155 {2, 4, pair{true, true}}, 1156 {4, 6, pair{true, false}}, 1157 {6, 7, pair{false, false}}, 1158 {7, 9, pair{false, true}}, 1159 {9, 13, pair{false, false}}, 1160 }, 1161 func(e Equaler) Equaler { 1162 p := e.(pair) 1163 p[1] = false 1164 return p 1165 }, 1166 8, 11, 1167 "[0:[false false] 1:[false true] 2:[true true] 4:[true false] 6:[false false] 7:[false true] 8:[false false] 13:<nil>]", 1168 nil, 1169 }, 1170 {0, 13, pair{}, 1171 []posRange{ 1172 {0, 1, pair{false, false}}, 1173 {1, 2, pair{false, true}}, 1174 {2, 3, pair{true, false}}, 1175 {3, 6, pair{true, false}}, 1176 {6, 7, pair{false, true}}, 1177 {7, 9, pair{true, true}}, 1178 {9, 10, pair{true, false}}, 1179 {10, 13, pair{false, false}}, 1180 }, 1181 func(e Equaler) Equaler { 1182 p := e.(pair) 1183 p[1] = false 1184 return p 1185 }, 1186 1, 5, 1187 "[0:[false false] 2:[true false] 6:[false true] 7:[true true] 9:[true false] 10:[false false] 13:<nil>]", 1188 nil, 1189 }, 1190 } { 1191 sv, err := New(t.start, t.end, pair{}) 1192 c.Assert(err, check.Equals, nil) 1193 sv.Relaxed = true 1194 for _, v := range t.sets { 1195 sv.SetRange(v.start, v.end, v.val) 1196 } 1197 1198 c.Check(sv.ApplyRange(t.from, t.to, t.mutate), check.DeepEquals, t.err) 1199 1200 var ( 1201 last Equaler 1202 failed = false 1203 failedEnd int 1204 ) 1205 sv.Do(func(start, end int, e Equaler) { 1206 if e == last { 1207 failed = true 1208 failedEnd = start 1209 } 1210 last = e 1211 }) 1212 if failed { 1213 c.Errorf("setting pair[1]=true over [%d,%d) gives invalid vector near %d:\n%s", 1214 t.start, t.end, failedEnd, sv.String()) 1215 } 1216 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 1217 } 1218 } 1219 1220 func (s *S) TestMutatorSetting(c *check.C) { 1221 type posRange struct { 1222 start, end int 1223 } 1224 for i, t := range []struct { 1225 sets []posRange 1226 max int 1227 expect string 1228 err error 1229 }{ 1230 { 1231 []posRange{ 1232 {30, 70}, 1233 {10, 50}, 1234 }, 1235 70, 1236 "[10:[false true] 70:<nil>]", 1237 nil, 1238 }, 1239 { 1240 []posRange{ 1241 {10, 50}, 1242 {30, 70}, 1243 }, 1244 70, 1245 "[10:[false true] 70:<nil>]", 1246 nil, 1247 }, 1248 { 1249 []posRange{ 1250 {30, 50}, 1251 {10, 70}, 1252 }, 1253 70, 1254 "[10:[false true] 70:<nil>]", 1255 nil, 1256 }, 1257 { 1258 []posRange{ 1259 {10, 70}, 1260 {30, 50}, 1261 }, 1262 70, 1263 "[10:[false true] 70:<nil>]", 1264 nil, 1265 }, 1266 } { 1267 sv, err := New(t.sets[0].start, t.sets[0].end, pair{}) 1268 c.Assert(err, check.Equals, nil) 1269 sv.Relaxed = true 1270 av := newVector(t.sets[0].start, t.sets[0].end, t.max, pair{}) 1271 for _, v := range t.sets { 1272 m := func(e Equaler) Equaler { 1273 p := e.(pair) 1274 p[1] = true 1275 return p 1276 } 1277 c.Check(sv.ApplyRange(v.start, v.end, m), check.DeepEquals, t.err) 1278 av.applyRange(v.start, v.end, m) 1279 } 1280 1281 c.Check(sv.String(), check.Equals, t.expect, check.Commentf("subtest %d", i)) 1282 c.Check(av.aggreesWith(sv), check.Equals, true) 1283 } 1284 } 1285 1286 type vector struct { 1287 min, max int 1288 data []Equaler 1289 } 1290 1291 func newVector(start, end, cap int, zero Equaler) *vector { 1292 data := make([]Equaler, cap) 1293 for i := range data { 1294 data[i] = zero 1295 } 1296 return &vector{ 1297 min: start, 1298 max: end, 1299 data: data, 1300 } 1301 } 1302 1303 func (v *vector) setRange(start, end int, e Equaler) { 1304 if start == end { 1305 return 1306 } 1307 if start < v.min { 1308 v.min = start 1309 } 1310 if end > v.max { 1311 v.max = end 1312 } 1313 for i := start; i < end; i++ { 1314 v.data[i] = e 1315 } 1316 } 1317 1318 func (v *vector) applyRange(start, end int, m Mutator) { 1319 if start == end { 1320 return 1321 } 1322 if start < v.min { 1323 v.min = start 1324 } 1325 if end > v.max { 1326 v.max = end 1327 } 1328 for i := start; i < end; i++ { 1329 v.data[i] = m(v.data[i]) 1330 } 1331 } 1332 1333 func (v *vector) aggreesWith(sv *Vector) bool { 1334 if v.min != sv.Start() || v.max != sv.End() { 1335 return false 1336 } 1337 ok := true 1338 sv.Do(func(start, end int, e Equaler) { 1339 for _, ve := range v.data[start:end] { 1340 if e != ve { 1341 ok = false 1342 } 1343 } 1344 }) 1345 return ok 1346 } 1347 1348 func (v *vector) String() string { 1349 var ( 1350 buf bytes.Buffer 1351 last Equaler 1352 ) 1353 fmt.Fprint(&buf, "[") 1354 for i := v.min; i < v.max; i++ { 1355 if v.data[i] != last { 1356 fmt.Fprintf(&buf, "%d:%v ", i, v.data[i]) 1357 } 1358 last = v.data[i] 1359 } 1360 fmt.Fprintf(&buf, "%d:<nil>]", v.max) 1361 return buf.String() 1362 } 1363 1364 func (s *S) TestMutateRangePartialFuzzing(c *check.C) { 1365 rand.Seed(1) 1366 sv, err := New(0, 1, pair{}) 1367 c.Assert(err, check.Equals, nil) 1368 sv.Relaxed = true 1369 v := newVector(0, 1, 15, pair{}) 1370 var prev, prevArray string 1371 for i := 0; i < 100000; i++ { 1372 s := rand.Intn(10) 1373 l := rand.Intn(5) 1374 j := rand.Intn(2) 1375 f := rand.Intn(2) < 1 1376 c.Check(sv.ApplyRange(s, s+l, func(e Equaler) Equaler { 1377 p := e.(pair) 1378 p[j] = f 1379 return p 1380 }), check.DeepEquals, nil) 1381 v.applyRange(s, s+l, func(e Equaler) Equaler { 1382 p := e.(pair) 1383 p[j] = f 1384 return p 1385 }) 1386 now := sv.String() 1387 array := v.String() 1388 c.Assert(sv.min, check.DeepEquals, sv.t.Min(), 1389 check.Commentf("invalid tree after iteration %d: set [%d,%d) pair[%d]=%t:\nwas: %v\nis: %s", i, s, s+l, j, f, prev, now), 1390 ) 1391 c.Assert(sv.max, check.DeepEquals, sv.t.Max(), 1392 check.Commentf("invalid tree after iteration %d: set [%d,%d) pair[%d]=%t:\nwas: %v\nis: %s", i, s, s+l, j, f, prev, now), 1393 ) 1394 c.Assert(v.aggreesWith(sv), check.Equals, true, 1395 check.Commentf("vector disagreement after iteration %d: set [%d,%d) pair[%d]=%t:\nwas: %s\narray: %v\nwas: %s\nstep: %s", 1396 i, s, s+l, j, f, prevArray, array, prev, now), 1397 ) 1398 var last Equaler 1399 sv.Do(func(start, end int, e Equaler) { 1400 if e == last { 1401 c.Fatalf("iteration %d: setting pair[%d]=%t over [%d,%d) gives invalid vector near %d:\nwas: %s\nis: %s\nwant:%s", 1402 i, j, f, s, s+l, start, prev, now, array) 1403 } 1404 last = e 1405 }) 1406 prev = now 1407 prevArray = array 1408 } 1409 } 1410 1411 func (s *S) TestSetRangeFuzzing(c *check.C) { 1412 rand.Seed(2) 1413 sv, err := New(0, 1, pair{}) 1414 c.Assert(err, check.Equals, nil) 1415 sv.Relaxed = true 1416 v := newVector(0, 1, 15, pair{}) 1417 var prev, prevArray string 1418 for i := 0; i < 100000; i++ { 1419 s := rand.Intn(10) 1420 l := rand.Intn(5) 1421 f := pair{rand.Intn(2) < 1, rand.Intn(2) < 1} 1422 sv.SetRange(s, s+l, f) 1423 v.setRange(s, s+l, f) 1424 now := sv.String() 1425 array := v.String() 1426 c.Assert(sv.min, check.DeepEquals, sv.t.Min(), 1427 check.Commentf("invalid tree after iteration %d: set [%d,%d) to %#v:\nwas: %v\nis: %s", i, s, s+l, f, prev, now), 1428 ) 1429 c.Assert(sv.max, check.DeepEquals, sv.t.Max(), 1430 check.Commentf("invalid tree after iteration %d: set [%d,%d) to %#v:\nwas: %v\nis: %s", i, s, s+l, f, prev, now), 1431 ) 1432 c.Assert(v.aggreesWith(sv), check.Equals, true, 1433 check.Commentf("vector disagreement after iteration %d: set [%d,%d) to %#v:\nwas: %s\narray: %v\nwas: %s\nstep: %s", 1434 i, s, s+l, f, prevArray, array, prev, now), 1435 ) 1436 var last Equaler 1437 sv.Do(func(start, end int, e Equaler) { 1438 if e == last { 1439 c.Fatalf("iteration %d: setting pair=%#v over [%d,%d) gives invalid vector near %d:\nwas: %s\nis: %s\nwant:%s", 1440 i, f, s, s+l, start, prev, now, array) 1441 } 1442 last = e 1443 }) 1444 prev = now 1445 prevArray = array 1446 } 1447 } 1448 1449 func (s *S) TestAgreementFuzzing(c *check.C) { 1450 rand.Seed(1) 1451 mutV, err := New(0, 1, pair{}) 1452 c.Assert(err, check.Equals, nil) 1453 mutV.Relaxed = true 1454 setV, err := New(0, 1, pair{}) 1455 c.Assert(err, check.Equals, nil) 1456 setV.Relaxed = true 1457 var ( 1458 prevSet, prevMut string 1459 setLen int 1460 ) 1461 // Set up agreeing representations of intervals. 1462 for i := 0; i < 100000; i++ { 1463 s := rand.Intn(1000) 1464 l := rand.Intn(50) 1465 setV.SetRange(s, s+l, pair{true, false}) 1466 c.Assert(mutV.ApplyRange(s, s+l, func(e Equaler) Equaler { 1467 p := e.(pair) 1468 p[0] = true 1469 return p 1470 }), check.Equals, nil) 1471 1472 setNow := setV.String() 1473 mutNow := mutV.String() 1474 var mutLen int 1475 setLen = 0 1476 setV.Do(func(start, end int, e Equaler) { 1477 p := e.(pair) 1478 if p[0] { 1479 setLen += end - start 1480 } 1481 }) 1482 mutV.Do(func(start, end int, e Equaler) { 1483 p := e.(pair) 1484 if p[0] { 1485 mutLen += end - start 1486 } 1487 }) 1488 if setLen != mutLen { 1489 c.Fatalf("length disagreement after iteration %d: %d != %d\nset was: %s\nmut was: %s\nset now: %s\nmut now: %s", 1490 i, setLen, mutLen, prevSet, prevMut, setNow, mutNow) 1491 } 1492 1493 prevSet = setNow 1494 prevMut = mutNow 1495 } 1496 1497 // Mutate the other element of steps in the mutating vector, checking for changes 1498 // in position 0 of the steps. 1499 for i := 0; i < 100000; i++ { 1500 s := rand.Intn(1000) 1501 l := rand.Intn(50) 1502 c.Assert(mutV.ApplyRange(s, s+l, func(e Equaler) Equaler { 1503 p := e.(pair) 1504 p[1] = rand.Intn(2) < 1 1505 return p 1506 }), check.Equals, nil) 1507 1508 mutNow := mutV.String() 1509 var mutLen int 1510 mutV.Do(func(start, end int, e Equaler) { 1511 p := e.(pair) 1512 if p[0] { 1513 mutLen += end - start 1514 } 1515 }) 1516 if setLen != mutLen { 1517 c.Fatalf("length disagreement after iteration %d: %d != %d\nmut was: %s\nmut now: %s", 1518 i, setLen, mutLen, prevMut, mutNow) 1519 } 1520 1521 prevMut = mutNow 1522 } 1523 } 1524 1525 // Benchmarks 1526 1527 func applyRange(b *testing.B, coverage float64) { 1528 b.StopTimer() 1529 var ( 1530 length = 100 1531 start = 0 1532 end = int(float64(b.N)/coverage) / length 1533 zero = Int(0) 1534 pool = make([]int, b.N) 1535 ) 1536 if end == 0 { 1537 return 1538 } 1539 sv, _ := New(start, end, zero) 1540 for i := 0; i < b.N; i++ { 1541 pool[i] = rand.Intn(end) 1542 } 1543 b.StartTimer() 1544 for _, r := range pool { 1545 sv.ApplyRange(r, r+length, IncInt) 1546 } 1547 } 1548 1549 func BenchmarkApplyRangeXDense(b *testing.B) { 1550 applyRange(b, 1000) 1551 } 1552 func BenchmarkApplyRangeVDense(b *testing.B) { 1553 applyRange(b, 100) 1554 } 1555 func BenchmarkApplyRangeDense(b *testing.B) { 1556 applyRange(b, 10) 1557 } 1558 func BenchmarkApplyRangeUnity(b *testing.B) { 1559 applyRange(b, 1) 1560 } 1561 func BenchmarkApplyRangeSparse(b *testing.B) { 1562 applyRange(b, 0.1) 1563 } 1564 func BenchmarkApplyRangeVSparse(b *testing.B) { 1565 applyRange(b, 0.01) 1566 } 1567 func BenchmarkApplyRangeXSparse(b *testing.B) { 1568 applyRange(b, 0.001) 1569 } 1570 1571 func atFunc(b *testing.B, coverage float64) { 1572 b.StopTimer() 1573 var ( 1574 length = 100 1575 start = 0 1576 end = int(float64(b.N)/coverage) / length 1577 zero = Int(0) 1578 ) 1579 if end == 0 { 1580 return 1581 } 1582 sv, _ := New(start, end, zero) 1583 for i := 0; i < b.N; i++ { 1584 r := rand.Intn(end) 1585 sv.ApplyRange(r, r+length, IncInt) 1586 } 1587 b.StartTimer() 1588 for i := 0; i < b.N; i++ { 1589 _, err := sv.At(rand.Intn(end)) 1590 if err != nil { 1591 panic("cannot reach") 1592 } 1593 } 1594 } 1595 1596 func BenchmarkAtXDense(b *testing.B) { 1597 atFunc(b, 1000) 1598 } 1599 func BenchmarkAtVDense(b *testing.B) { 1600 atFunc(b, 100) 1601 } 1602 func BenchmarkAtDense(b *testing.B) { 1603 atFunc(b, 10) 1604 } 1605 func BenchmarkAtUnity(b *testing.B) { 1606 atFunc(b, 1) 1607 } 1608 func BenchmarkAtSparse(b *testing.B) { 1609 atFunc(b, 0.1) 1610 } 1611 func BenchmarkAtVSparse(b *testing.B) { 1612 atFunc(b, 0.01) 1613 } 1614 func BenchmarkAtXSparse(b *testing.B) { 1615 atFunc(b, 0.001) 1616 }