github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pot/pot.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:48</date> 10 //</624342676908544000> 11 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 // 25 // 26 // 27 28 // 29 package pot 30 31 import ( 32 "fmt" 33 "sync" 34 ) 35 36 const ( 37 maxkeylen = 256 38 ) 39 40 // 41 type Pot struct { 42 pin Val 43 bins []*Pot 44 size int 45 po int 46 } 47 48 // 49 type Val interface{} 50 51 // 52 type Pof func(Val, Val, int) (int, bool) 53 54 // 55 // 56 // 57 func NewPot(v Val, po int) *Pot { 58 var size int 59 if v != nil { 60 size++ 61 } 62 return &Pot{ 63 pin: v, 64 po: po, 65 size: size, 66 } 67 } 68 69 // 70 func (t *Pot) Pin() Val { 71 return t.pin 72 } 73 74 // 75 func (t *Pot) Size() int { 76 if t == nil { 77 return 0 78 } 79 return t.size 80 } 81 82 // 83 // 84 // 85 // 86 // 87 // 88 // 89 func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 90 return add(t, val, pof) 91 } 92 93 func (t *Pot) clone() *Pot { 94 return &Pot{ 95 pin: t.pin, 96 size: t.size, 97 po: t.po, 98 bins: t.bins, 99 } 100 } 101 102 func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 103 var r *Pot 104 if t == nil || t.pin == nil { 105 r = t.clone() 106 r.pin = val 107 r.size++ 108 return r, 0, false 109 } 110 po, found := pof(t.pin, val, t.po) 111 if found { 112 r = t.clone() 113 r.pin = val 114 return r, po, true 115 } 116 117 var p *Pot 118 var i, j int 119 size := t.size 120 for i < len(t.bins) { 121 n := t.bins[i] 122 if n.po == po { 123 p, _, found = add(n, val, pof) 124 if !found { 125 size++ 126 } 127 j++ 128 break 129 } 130 if n.po > po { 131 break 132 } 133 i++ 134 j++ 135 } 136 if p == nil { 137 size++ 138 p = &Pot{ 139 pin: val, 140 size: 1, 141 po: po, 142 } 143 } 144 145 bins := append([]*Pot{}, t.bins[:i]...) 146 bins = append(bins, p) 147 bins = append(bins, t.bins[j:]...) 148 r = &Pot{ 149 pin: t.pin, 150 size: size, 151 po: t.po, 152 bins: bins, 153 } 154 155 return r, po, found 156 } 157 158 // 159 // 160 // 161 // 162 // 163 // 164 // 165 func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { 166 return remove(t, v, pof) 167 } 168 169 func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { 170 size := t.size 171 po, found = pof(t.pin, val, t.po) 172 if found { 173 size-- 174 if size == 0 { 175 r = &Pot{ 176 po: t.po, 177 } 178 return r, po, true 179 } 180 i := len(t.bins) - 1 181 last := t.bins[i] 182 r = &Pot{ 183 pin: last.pin, 184 bins: append(t.bins[:i], last.bins...), 185 size: size, 186 po: t.po, 187 } 188 return r, t.po, true 189 } 190 191 var p *Pot 192 var i, j int 193 for i < len(t.bins) { 194 n := t.bins[i] 195 if n.po == po { 196 p, po, found = remove(n, val, pof) 197 if found { 198 size-- 199 } 200 j++ 201 break 202 } 203 if n.po > po { 204 return t, po, false 205 } 206 i++ 207 j++ 208 } 209 bins := t.bins[:i] 210 if p != nil && p.pin != nil { 211 bins = append(bins, p) 212 } 213 bins = append(bins, t.bins[j:]...) 214 r = &Pot{ 215 pin: val, 216 size: size, 217 po: t.po, 218 bins: bins, 219 } 220 return r, po, found 221 } 222 223 // 224 // 225 // 226 // 227 // 228 // 229 func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { 230 var val Val 231 if t.pin == nil { 232 val = f(nil) 233 if val == nil { 234 return nil, 0, false, false 235 } 236 return NewPot(val, t.po), 0, false, true 237 } 238 size := t.size 239 po, found = pof(k, t.pin, t.po) 240 if found { 241 val = f(t.pin) 242 // 243 if val == nil { 244 size-- 245 if size == 0 { 246 r = &Pot{ 247 po: t.po, 248 } 249 // 250 return r, po, true, true 251 } 252 // 253 i := len(t.bins) - 1 254 last := t.bins[i] 255 r = &Pot{ 256 pin: last.pin, 257 bins: append(t.bins[:i], last.bins...), 258 size: size, 259 po: t.po, 260 } 261 return r, po, true, true 262 } 263 // 264 if val == t.pin { 265 return t, po, true, false 266 } 267 // 268 r = t.clone() 269 r.pin = val 270 return r, po, true, true 271 } 272 273 // 274 var p *Pot 275 n, i := t.getPos(po) 276 if n != nil { 277 p, po, found, change = Swap(n, k, pof, f) 278 // 279 if !change { 280 return t, po, found, false 281 } 282 // 283 bins := append([]*Pot{}, t.bins[:i]...) 284 if p.size == 0 { 285 size-- 286 } else { 287 size += p.size - n.size 288 bins = append(bins, p) 289 } 290 i++ 291 if i < len(t.bins) { 292 bins = append(bins, t.bins[i:]...) 293 } 294 r = t.clone() 295 r.bins = bins 296 r.size = size 297 return r, po, found, true 298 } 299 // 300 val = f(nil) 301 if val == nil { 302 // 303 return t, po, false, false 304 } 305 // 306 if _, eq := pof(val, k, po); !eq { 307 panic("invalid value") 308 } 309 // 310 size++ 311 p = &Pot{ 312 pin: val, 313 size: 1, 314 po: po, 315 } 316 317 bins := append([]*Pot{}, t.bins[:i]...) 318 bins = append(bins, p) 319 if i < len(t.bins) { 320 bins = append(bins, t.bins[i:]...) 321 } 322 r = t.clone() 323 r.bins = bins 324 r.size = size 325 return r, po, found, true 326 } 327 328 // 329 // 330 // 331 func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { 332 return union(t0, t1, pof) 333 } 334 335 func union(t0, t1 *Pot, pof Pof) (*Pot, int) { 336 if t0 == nil || t0.size == 0 { 337 return t1, 0 338 } 339 if t1 == nil || t1.size == 0 { 340 return t0, 0 341 } 342 var pin Val 343 var bins []*Pot 344 var mis []int 345 wg := &sync.WaitGroup{} 346 wg.Add(1) 347 pin0 := t0.pin 348 pin1 := t1.pin 349 bins0 := t0.bins 350 bins1 := t1.bins 351 var i0, i1 int 352 var common int 353 354 po, eq := pof(pin0, pin1, 0) 355 356 for { 357 l0 := len(bins0) 358 l1 := len(bins1) 359 var n0, n1 *Pot 360 var p0, p1 int 361 var a0, a1 bool 362 363 for { 364 365 if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { 366 n0 = bins0[i0] 367 p0 = n0.po 368 a0 = p0 == po 369 } else { 370 a0 = true 371 } 372 373 if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { 374 n1 = bins1[i1] 375 p1 = n1.po 376 a1 = p1 == po 377 } else { 378 a1 = true 379 } 380 if a0 && a1 { 381 break 382 } 383 384 switch { 385 case (p0 < p1 || a1) && !a0: 386 bins = append(bins, n0) 387 i0++ 388 n0 = nil 389 case (p1 < p0 || a0) && !a1: 390 bins = append(bins, n1) 391 i1++ 392 n1 = nil 393 case p1 < po: 394 bl := len(bins) 395 bins = append(bins, nil) 396 ml := len(mis) 397 mis = append(mis, 0) 398 // 399 // 400 // 401 // 402 // 403 bins[bl], mis[ml] = union(n0, n1, pof) 404 i0++ 405 i1++ 406 n0 = nil 407 n1 = nil 408 } 409 } 410 411 if eq { 412 common++ 413 pin = pin1 414 break 415 } 416 417 i := i0 418 if len(bins0) > i && bins0[i].po == po { 419 i++ 420 } 421 var size0 int 422 for _, n := range bins0[i:] { 423 size0 += n.size 424 } 425 np := &Pot{ 426 pin: pin0, 427 bins: bins0[i:], 428 size: size0 + 1, 429 po: po, 430 } 431 432 bins2 := []*Pot{np} 433 if n0 == nil { 434 pin0 = pin1 435 po = maxkeylen + 1 436 eq = true 437 common-- 438 439 } else { 440 bins2 = append(bins2, n0.bins...) 441 pin0 = pin1 442 pin1 = n0.pin 443 po, eq = pof(pin0, pin1, n0.po) 444 445 } 446 bins0 = bins1 447 bins1 = bins2 448 i0 = i1 449 i1 = 0 450 451 } 452 453 wg.Done() 454 wg.Wait() 455 for _, c := range mis { 456 common += c 457 } 458 n := &Pot{ 459 pin: pin, 460 bins: bins, 461 size: t0.size + t1.size - common, 462 po: t0.po, 463 } 464 return n, common 465 } 466 467 // 468 // 469 // 470 func (t *Pot) Each(f func(Val, int) bool) bool { 471 return t.each(f) 472 } 473 474 func (t *Pot) each(f func(Val, int) bool) bool { 475 var next bool 476 for _, n := range t.bins { 477 if n == nil { 478 return true 479 } 480 next = n.each(f) 481 if !next { 482 return false 483 } 484 } 485 if t.size == 0 { 486 return false 487 } 488 return f(t.pin, t.po) 489 } 490 491 // 492 // 493 // 494 // 495 // 496 // 497 // 498 // 499 func (t *Pot) EachFrom(f func(Val, int) bool, po int) bool { 500 return t.eachFrom(f, po) 501 } 502 503 func (t *Pot) eachFrom(f func(Val, int) bool, po int) bool { 504 var next bool 505 _, lim := t.getPos(po) 506 for i := lim; i < len(t.bins); i++ { 507 n := t.bins[i] 508 next = n.each(f) 509 if !next { 510 return false 511 } 512 } 513 return f(t.pin, t.po) 514 } 515 516 // 517 // 518 // 519 // 520 func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { 521 t.eachBin(val, pof, po, f) 522 } 523 524 func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { 525 if t == nil || t.size == 0 { 526 return 527 } 528 spr, _ := pof(t.pin, val, t.po) 529 _, lim := t.getPos(spr) 530 var size int 531 var n *Pot 532 for i := 0; i < lim; i++ { 533 n = t.bins[i] 534 size += n.size 535 if n.po < po { 536 continue 537 } 538 if !f(n.po, n.size, n.each) { 539 return 540 } 541 } 542 if lim == len(t.bins) { 543 if spr >= po { 544 f(spr, 1, func(g func(Val, int) bool) bool { 545 return g(t.pin, spr) 546 }) 547 } 548 return 549 } 550 551 n = t.bins[lim] 552 553 spo := spr 554 if n.po == spr { 555 spo++ 556 size += n.size 557 } 558 if spr >= po { 559 if !f(spr, t.size-size, func(g func(Val, int) bool) bool { 560 return t.eachFrom(func(v Val, j int) bool { 561 return g(v, spr) 562 }, spo) 563 }) { 564 return 565 } 566 } 567 if n.po == spr { 568 n.eachBin(val, pof, po, f) 569 } 570 571 } 572 573 // 574 // 575 // 576 func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 577 return t.eachNeighbour(val, pof, f) 578 } 579 580 func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 581 if t == nil || t.size == 0 { 582 return false 583 } 584 var next bool 585 l := len(t.bins) 586 var n *Pot 587 ir := l 588 il := l 589 po, eq := pof(t.pin, val, t.po) 590 if !eq { 591 n, il = t.getPos(po) 592 if n != nil { 593 next = n.eachNeighbour(val, pof, f) 594 if !next { 595 return false 596 } 597 ir = il 598 } else { 599 ir = il - 1 600 } 601 } 602 603 next = f(t.pin, po) 604 if !next { 605 return false 606 } 607 608 for i := l - 1; i > ir; i-- { 609 next = t.bins[i].each(func(v Val, _ int) bool { 610 return f(v, po) 611 }) 612 if !next { 613 return false 614 } 615 } 616 617 for i := il - 1; i >= 0; i-- { 618 n := t.bins[i] 619 next = n.each(func(v Val, _ int) bool { 620 return f(v, n.po) 621 }) 622 if !next { 623 return false 624 } 625 } 626 return true 627 } 628 629 // 630 // 631 // 632 // 633 // 634 // 635 // 636 // 637 // 638 // 639 // 640 func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { 641 if max > t.size { 642 max = t.size 643 } 644 var wg *sync.WaitGroup 645 if wait { 646 wg = &sync.WaitGroup{} 647 } 648 t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) 649 if wait { 650 wg.Wait() 651 } 652 } 653 654 func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { 655 l := len(t.bins) 656 657 po, eq := pof(t.pin, val, t.po) 658 659 // 660 pom := po 661 if pom > maxPos { 662 pom = maxPos 663 } 664 n, il := t.getPos(pom) 665 ir := il 666 // 667 if pom == po { 668 if n != nil { 669 670 m := n.size 671 if max < m { 672 m = max 673 } 674 max -= m 675 676 extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) 677 678 } else { 679 if !eq { 680 ir-- 681 } 682 } 683 } else { 684 extra++ 685 max-- 686 if n != nil { 687 il++ 688 } 689 // 690 // 691 for i := l - 1; i >= il; i-- { 692 s := t.bins[i] 693 m := s.size 694 if max < m { 695 m = max 696 } 697 max -= m 698 extra += m 699 } 700 } 701 702 var m int 703 if pom == po { 704 705 m, max, extra = need(1, max, extra) 706 if m <= 0 { 707 return 708 } 709 710 if wg != nil { 711 wg.Add(1) 712 } 713 go func() { 714 if wg != nil { 715 defer wg.Done() 716 } 717 f(t.pin, po) 718 }() 719 720 // 721 for i := l - 1; i > ir; i-- { 722 n := t.bins[i] 723 724 m, max, extra = need(n.size, max, extra) 725 if m <= 0 { 726 return 727 } 728 729 if wg != nil { 730 wg.Add(m) 731 } 732 go func(pn *Pot, pm int) { 733 pn.each(func(v Val, _ int) bool { 734 if wg != nil { 735 defer wg.Done() 736 } 737 f(v, po) 738 pm-- 739 return pm > 0 740 }) 741 }(n, m) 742 743 } 744 } 745 746 // 747 for i := il - 1; i >= 0; i-- { 748 n := t.bins[i] 749 // 750 // 751 m, max, extra = need(n.size, max, extra) 752 if m <= 0 { 753 return 754 } 755 756 if wg != nil { 757 wg.Add(m) 758 } 759 go func(pn *Pot, pm int) { 760 pn.each(func(v Val, _ int) bool { 761 if wg != nil { 762 defer wg.Done() 763 } 764 f(v, pn.po) 765 pm-- 766 return pm > 0 767 }) 768 }(n, m) 769 770 } 771 return max + extra 772 } 773 774 // 775 // 776 // 777 func (t *Pot) getPos(po int) (n *Pot, i int) { 778 for i, n = range t.bins { 779 if po > n.po { 780 continue 781 } 782 if po < n.po { 783 return nil, i 784 } 785 return n, i 786 } 787 return nil, len(t.bins) 788 } 789 790 // 791 // 792 func need(m, max, extra int) (int, int, int) { 793 if m <= extra { 794 return m, max, extra - m 795 } 796 max += extra - m 797 if max <= 0 { 798 return m + max, 0, 0 799 } 800 return m, max, 0 801 } 802 803 func (t *Pot) String() string { 804 return t.sstring("") 805 } 806 807 func (t *Pot) sstring(indent string) string { 808 if t == nil { 809 return "<nil>" 810 } 811 var s string 812 indent += " " 813 s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) 814 for _, n := range t.bins { 815 s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) 816 } 817 return s 818 } 819