github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:44</date> 10 //</624450116220096512> 11 12 13 //包装罐见Go医生 14 package pot 15 16 import ( 17 "fmt" 18 "sync" 19 ) 20 21 const ( 22 maxkeylen = 256 23 ) 24 25 //pot是节点类型(根、分支节点和叶相同) 26 type Pot struct { 27 pin Val 28 bins []*Pot 29 size int 30 po int 31 } 32 33 //VAL是锅的元件类型 34 type Val interface{} 35 36 //pof是邻近订单比较运算符函数 37 type Pof func(Val, Val, int) (int, bool) 38 39 //Newpot构造函数。需要VAL类型的值才能固定 40 //和po指向val键中的跨度 41 //钉住的项目按大小计算 42 func NewPot(v Val, po int) *Pot { 43 var size int 44 if v != nil { 45 size++ 46 } 47 return &Pot{ 48 pin: v, 49 po: po, 50 size: size, 51 } 52 } 53 54 //pin返回pot的pinned元素(键) 55 func (t *Pot) Pin() Val { 56 return t.pin 57 } 58 59 //SIZE返回pot中的值数 60 func (t *Pot) Size() int { 61 if t == nil { 62 return 0 63 } 64 return t.size 65 } 66 67 //添加将新值插入到容器中,然后 68 //返回v和布尔值的接近顺序 69 //指示是否找到该项 70 //add called on(t,v)返回包含t的所有元素的新pot 71 //加上V值,使用应用加法 72 //第二个返回值是插入元素的接近顺序。 73 //第三个是布尔值,指示是否找到该项 74 func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 75 return add(t, val, pof) 76 } 77 78 func (t *Pot) clone() *Pot { 79 return &Pot{ 80 pin: t.pin, 81 size: t.size, 82 po: t.po, 83 bins: t.bins, 84 } 85 } 86 87 func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 88 var r *Pot 89 if t == nil || t.pin == nil { 90 r = t.clone() 91 r.pin = val 92 r.size++ 93 return r, 0, false 94 } 95 po, found := pof(t.pin, val, t.po) 96 if found { 97 r = t.clone() 98 r.pin = val 99 return r, po, true 100 } 101 102 var p *Pot 103 var i, j int 104 size := t.size 105 for i < len(t.bins) { 106 n := t.bins[i] 107 if n.po == po { 108 p, _, found = add(n, val, pof) 109 if !found { 110 size++ 111 } 112 j++ 113 break 114 } 115 if n.po > po { 116 break 117 } 118 i++ 119 j++ 120 } 121 if p == nil { 122 size++ 123 p = &Pot{ 124 pin: val, 125 size: 1, 126 po: po, 127 } 128 } 129 130 bins := append([]*Pot{}, t.bins[:i]...) 131 bins = append(bins, p) 132 bins = append(bins, t.bins[j:]...) 133 r = &Pot{ 134 pin: t.pin, 135 size: size, 136 po: t.po, 137 bins: bins, 138 } 139 140 return r, po, found 141 } 142 143 //remove从pot t t中删除元素v并返回三个参数: 144 //1。新锅,包含所有元素t减去元素v; 145 //2。拆除元件V的接近顺序; 146 //三。指示是否找到该项的布尔值。 147 func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { 148 return remove(t, v, pof) 149 } 150 151 func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { 152 size := t.size 153 po, found = pof(t.pin, val, t.po) 154 if found { 155 size-- 156 if size == 0 { 157 return &Pot{}, po, true 158 } 159 i := len(t.bins) - 1 160 last := t.bins[i] 161 r = &Pot{ 162 pin: last.pin, 163 bins: append(t.bins[:i], last.bins...), 164 size: size, 165 po: t.po, 166 } 167 return r, t.po, true 168 } 169 170 var p *Pot 171 var i, j int 172 for i < len(t.bins) { 173 n := t.bins[i] 174 if n.po == po { 175 p, po, found = remove(n, val, pof) 176 if found { 177 size-- 178 } 179 j++ 180 break 181 } 182 if n.po > po { 183 return t, po, false 184 } 185 i++ 186 j++ 187 } 188 bins := t.bins[:i] 189 if p != nil && p.pin != nil { 190 bins = append(bins, p) 191 } 192 bins = append(bins, t.bins[j:]...) 193 r = &Pot{ 194 pin: t.pin, 195 size: size, 196 po: t.po, 197 bins: bins, 198 } 199 return r, po, found 200 } 201 202 //调用的swap(k,f)在k处查找项 203 // 204 //如果f(v)返回nil,则删除元素 205 //如果f(v)返回v'<>v,则v'插入锅中。 206 //如果(v)==v,则罐不更换。 207 //如果pof(f(v),k)显示v'和v不是键相等,则会恐慌。 208 func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { 209 var val Val 210 if t.pin == nil { 211 val = f(nil) 212 if val == nil { 213 return nil, 0, false, false 214 } 215 return NewPot(val, t.po), 0, false, true 216 } 217 size := t.size 218 po, found = pof(k, t.pin, t.po) 219 if found { 220 val = f(t.pin) 221 //移除元素 222 if val == nil { 223 size-- 224 if size == 0 { 225 r = &Pot{ 226 po: t.po, 227 } 228 //返回空罐 229 return r, po, true, true 230 } 231 //实际上,通过合并最后一个bin来删除pin 232 i := len(t.bins) - 1 233 last := t.bins[i] 234 r = &Pot{ 235 pin: last.pin, 236 bins: append(t.bins[:i], last.bins...), 237 size: size, 238 po: t.po, 239 } 240 return r, po, true, true 241 } 242 //找到元素,但没有更改 243 if val == t.pin { 244 return t, po, true, false 245 } 246 //实际修改固定元素,但结构没有更改 247 r = t.clone() 248 r.pin = val 249 return r, po, true, true 250 } 251 252 //递归阶段 253 var p *Pot 254 n, i := t.getPos(po) 255 if n != nil { 256 p, po, found, change = Swap(n, k, pof, f) 257 //递归无更改 258 if !change { 259 return t, po, found, false 260 } 261 //递归更改 262 bins := append([]*Pot{}, t.bins[:i]...) 263 if p.size == 0 { 264 size-- 265 } else { 266 size += p.size - n.size 267 bins = append(bins, p) 268 } 269 i++ 270 if i < len(t.bins) { 271 bins = append(bins, t.bins[i:]...) 272 } 273 r = t.clone() 274 r.bins = bins 275 r.size = size 276 return r, po, found, true 277 } 278 //密钥不存在 279 val = f(nil) 280 if val == nil { 281 //它不应该被创建 282 return t, po, false, false 283 } 284 //否则,如果等于k,则检查val 285 if _, eq := pof(val, k, po); !eq { 286 panic("invalid value") 287 } 288 /// 289 size++ 290 p = &Pot{ 291 pin: val, 292 size: 1, 293 po: po, 294 } 295 296 bins := append([]*Pot{}, t.bins[:i]...) 297 bins = append(bins, p) 298 if i < len(t.bins) { 299 bins = append(bins, t.bins[i:]...) 300 } 301 r = t.clone() 302 r.bins = bins 303 r.size = size 304 return r, po, found, true 305 } 306 307 //在(t0,t1,pof)上调用的union返回t0和t1的union 308 //使用应用联合计算联合 309 //第二个返回值是公共元素的数目 310 func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { 311 return union(t0, t1, pof) 312 } 313 314 func union(t0, t1 *Pot, pof Pof) (*Pot, int) { 315 if t0 == nil || t0.size == 0 { 316 return t1, 0 317 } 318 if t1 == nil || t1.size == 0 { 319 return t0, 0 320 } 321 var pin Val 322 var bins []*Pot 323 var mis []int 324 wg := &sync.WaitGroup{} 325 wg.Add(1) 326 pin0 := t0.pin 327 pin1 := t1.pin 328 bins0 := t0.bins 329 bins1 := t1.bins 330 var i0, i1 int 331 var common int 332 333 po, eq := pof(pin0, pin1, 0) 334 335 for { 336 l0 := len(bins0) 337 l1 := len(bins1) 338 var n0, n1 *Pot 339 var p0, p1 int 340 var a0, a1 bool 341 342 for { 343 344 if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { 345 n0 = bins0[i0] 346 p0 = n0.po 347 a0 = p0 == po 348 } else { 349 a0 = true 350 } 351 352 if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { 353 n1 = bins1[i1] 354 p1 = n1.po 355 a1 = p1 == po 356 } else { 357 a1 = true 358 } 359 if a0 && a1 { 360 break 361 } 362 363 switch { 364 case (p0 < p1 || a1) && !a0: 365 bins = append(bins, n0) 366 i0++ 367 n0 = nil 368 case (p1 < p0 || a0) && !a1: 369 bins = append(bins, n1) 370 i1++ 371 n1 = nil 372 case p1 < po: 373 bl := len(bins) 374 bins = append(bins, nil) 375 ml := len(mis) 376 mis = append(mis, 0) 377 //添加(1) 378 //go func(b,m int,m0,m1*pot) 379 //推迟WG.DONE() 380 //箱[B],MIS[M]=联管节(M0、M1、POF) 381 //(bl,ml,n0,n1) 382 bins[bl], mis[ml] = union(n0, n1, pof) 383 i0++ 384 i1++ 385 n0 = nil 386 n1 = nil 387 } 388 } 389 390 if eq { 391 common++ 392 pin = pin1 393 break 394 } 395 396 i := i0 397 if len(bins0) > i && bins0[i].po == po { 398 i++ 399 } 400 var size0 int 401 for _, n := range bins0[i:] { 402 size0 += n.size 403 } 404 np := &Pot{ 405 pin: pin0, 406 bins: bins0[i:], 407 size: size0 + 1, 408 po: po, 409 } 410 411 bins2 := []*Pot{np} 412 if n0 == nil { 413 pin0 = pin1 414 po = maxkeylen + 1 415 eq = true 416 common-- 417 418 } else { 419 bins2 = append(bins2, n0.bins...) 420 pin0 = pin1 421 pin1 = n0.pin 422 po, eq = pof(pin0, pin1, n0.po) 423 424 } 425 bins0 = bins1 426 bins1 = bins2 427 i0 = i1 428 i1 = 0 429 430 } 431 432 wg.Done() 433 wg.Wait() 434 for _, c := range mis { 435 common += c 436 } 437 n := &Pot{ 438 pin: pin, 439 bins: bins, 440 size: t0.size + t1.size - common, 441 po: t0.po, 442 } 443 return n, common 444 } 445 446 //每个函数都是pot元素上的同步迭代器,函数为f。 447 func (t *Pot) Each(f func(Val) bool) bool { 448 return t.each(f) 449 } 450 451 //每个函数都是pot元素上的同步迭代器,函数为f。 452 //如果函数返回false或没有其他元素,则迭代将结束。 453 func (t *Pot) each(f func(Val) bool) bool { 454 if t == nil || t.size == 0 { 455 return false 456 } 457 for _, n := range t.bins { 458 if !n.each(f) { 459 return false 460 } 461 } 462 return f(t.pin) 463 } 464 465 //eachFrom是对pot元素的同步迭代器,函数为f, 466 //从某个邻近订单po开始,作为第二个参数传递。 467 //如果函数返回false或没有其他元素,则迭代将结束。 468 func (t *Pot) eachFrom(f func(Val) bool, po int) bool { 469 if t == nil || t.size == 0 { 470 return false 471 } 472 _, beg := t.getPos(po) 473 for i := beg; i < len(t.bins); i++ { 474 if !t.bins[i].each(f) { 475 return false 476 } 477 } 478 return f(t.pin) 479 } 480 481 //eachbin在pivot节点的bin上迭代,并在每个pivot节点上向调用者提供迭代器。 482 //传递接近顺序和大小的子树 483 //迭代将继续,直到函数的返回值为假 484 //或者没有其他子项 485 func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { 486 t.eachBin(val, pof, po, f) 487 } 488 489 func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { 490 if t == nil || t.size == 0 { 491 return 492 } 493 spr, _ := pof(t.pin, val, t.po) 494 _, lim := t.getPos(spr) 495 var size int 496 var n *Pot 497 for i := 0; i < lim; i++ { 498 n = t.bins[i] 499 size += n.size 500 if n.po < po { 501 continue 502 } 503 if !f(n.po, n.size, n.each) { 504 return 505 } 506 } 507 if lim == len(t.bins) { 508 if spr >= po { 509 f(spr, 1, func(g func(Val) bool) bool { 510 return g(t.pin) 511 }) 512 } 513 return 514 } 515 516 n = t.bins[lim] 517 518 spo := spr 519 if n.po == spr { 520 spo++ 521 size += n.size 522 } 523 if spr >= po { 524 if !f(spr, t.size-size, func(g func(Val) bool) bool { 525 return t.eachFrom(func(v Val) bool { 526 return g(v) 527 }, spo) 528 }) { 529 return 530 } 531 } 532 if n.po == spr { 533 n.eachBin(val, pof, po, f) 534 } 535 536 } 537 538 //eachneighbur是任何目标val的邻居上的同步迭代器。 539 //元素的检索顺序反映了目标的接近顺序。 540 //TODO:将最大proxybin添加到迭代的开始范围 541 func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 542 return t.eachNeighbour(val, pof, f) 543 } 544 545 func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 546 if t == nil || t.size == 0 { 547 return false 548 } 549 var next bool 550 l := len(t.bins) 551 var n *Pot 552 ir := l 553 il := l 554 po, eq := pof(t.pin, val, t.po) 555 if !eq { 556 n, il = t.getPos(po) 557 if n != nil { 558 next = n.eachNeighbour(val, pof, f) 559 if !next { 560 return false 561 } 562 ir = il 563 } else { 564 ir = il - 1 565 } 566 } 567 568 next = f(t.pin, po) 569 if !next { 570 return false 571 } 572 573 for i := l - 1; i > ir; i-- { 574 next = t.bins[i].each(func(v Val) bool { 575 return f(v, po) 576 }) 577 if !next { 578 return false 579 } 580 } 581 582 for i := il - 1; i >= 0; i-- { 583 n := t.bins[i] 584 next = n.each(func(v Val) bool { 585 return f(v, n.po) 586 }) 587 if !next { 588 return false 589 } 590 } 591 return true 592 } 593 594 //调用的eachneighbourasync(val、max、maxpos、f、wait)是异步迭代器 595 //在不小于maxpos wrt val的元素上。 596 //val不需要与pot元素匹配,但如果匹配,并且 597 //maxpos是keylength,而不是包含在迭代中的keylength 598 //对f的调用是并行的,调用顺序未定义。 599 //在锅中没有元素 600 //如果访问了更近的节点,则不会访问。 601 //当访问最大最近节点数时,迭代完成。 602 //或者,如果整个系统中没有不比未访问的maxpos更近的节点 603 //如果wait为true,则仅当对f的所有调用都完成时,迭代器才返回 604 //TODO:为正确的代理范围迭代实现minpos 605 func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { 606 if max > t.size { 607 max = t.size 608 } 609 var wg *sync.WaitGroup 610 if wait { 611 wg = &sync.WaitGroup{} 612 } 613 t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) 614 if wait { 615 wg.Wait() 616 } 617 } 618 619 func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { 620 l := len(t.bins) 621 622 po, eq := pof(t.pin, val, t.po) 623 624 //如果po太近,将pivot branch(pom)设置为maxpos 625 pom := po 626 if pom > maxPos { 627 pom = maxPos 628 } 629 n, il := t.getPos(pom) 630 ir := il 631 //如果透视分支存在且采购订单不太接近,则迭代透视分支 632 if pom == po { 633 if n != nil { 634 635 m := n.size 636 if max < m { 637 m = max 638 } 639 max -= m 640 641 extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) 642 643 } else { 644 if !eq { 645 ir-- 646 } 647 } 648 } else { 649 extra++ 650 max-- 651 if n != nil { 652 il++ 653 } 654 //在检查max之前,将额外的元素相加 655 //在被跳过的关闭分支上(如果采购订单太近) 656 for i := l - 1; i >= il; i-- { 657 s := t.bins[i] 658 m := s.size 659 if max < m { 660 m = max 661 } 662 max -= m 663 extra += m 664 } 665 } 666 667 var m int 668 if pom == po { 669 670 m, max, extra = need(1, max, extra) 671 if m <= 0 { 672 return 673 } 674 675 if wg != nil { 676 wg.Add(1) 677 } 678 go func() { 679 if wg != nil { 680 defer wg.Done() 681 } 682 f(t.pin, po) 683 }() 684 685 //否则迭代 686 for i := l - 1; i > ir; i-- { 687 n := t.bins[i] 688 689 m, max, extra = need(n.size, max, extra) 690 if m <= 0 { 691 return 692 } 693 694 if wg != nil { 695 wg.Add(m) 696 } 697 go func(pn *Pot, pm int) { 698 pn.each(func(v Val) bool { 699 if wg != nil { 700 defer wg.Done() 701 } 702 f(v, po) 703 pm-- 704 return pm > 0 705 }) 706 }(n, m) 707 708 } 709 } 710 711 //使用自己的po迭代更远的tham pom分支 712 for i := il - 1; i >= 0; i-- { 713 n := t.bins[i] 714 //第一次max小于整个分支的大小 715 //等待轴线程释放额外的元素 716 m, max, extra = need(n.size, max, extra) 717 if m <= 0 { 718 return 719 } 720 721 if wg != nil { 722 wg.Add(m) 723 } 724 go func(pn *Pot, pm int) { 725 pn.each(func(v Val) bool { 726 if wg != nil { 727 defer wg.Done() 728 } 729 f(v, pn.po) 730 pm-- 731 return pm > 0 732 }) 733 }(n, m) 734 735 } 736 return max + extra 737 } 738 739 //getpos called on(n)返回po n处的分叉节点及其索引(如果存在) 740 //否则零 741 //打电话的人应该锁着 742 func (t *Pot) getPos(po int) (n *Pot, i int) { 743 for i, n = range t.bins { 744 if po > n.po { 745 continue 746 } 747 if po < n.po { 748 return nil, i 749 } 750 return n, i 751 } 752 return nil, len(t.bins) 753 } 754 755 //需要调用(m,max,extra)使用max m out extra,然后使用max 756 //如果需要,返回调整后的计数 757 func need(m, max, extra int) (int, int, int) { 758 if m <= extra { 759 return m, max, extra - m 760 } 761 max += extra - m 762 if max <= 0 { 763 return m + max, 0, 0 764 } 765 return m, max, 0 766 } 767 768 func (t *Pot) String() string { 769 return t.sstring("") 770 } 771 772 func (t *Pot) sstring(indent string) string { 773 if t == nil { 774 return "<nil>" 775 } 776 var s string 777 indent += " " 778 s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) 779 for _, n := range t.bins { 780 s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) 781 } 782 return s 783 } 784