github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/swarm/pot/pot.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package pot see doc.go 18 package pot 19 20 import ( 21 "fmt" 22 "sync" 23 ) 24 25 const ( 26 maxkeylen = 256 27 ) 28 29 // Pot is the node type (same for root, branching node and leaf) 30 type Pot struct { 31 pin Val 32 bins []*Pot 33 size int 34 po int 35 } 36 37 // Val is the element type for Pots 38 type Val interface{} 39 40 // Pof is the proximity order comparison operator function 41 type Pof func(Val, Val, int) (int, bool) 42 43 // NewPot constructor. Requires a value of type Val to pin 44 // and po to point to a span in the Val key 45 // The pinned item counts towards the size 46 func NewPot(v Val, po int) *Pot { 47 var size int 48 if v != nil { 49 size++ 50 } 51 return &Pot{ 52 pin: v, 53 po: po, 54 size: size, 55 } 56 } 57 58 // Pin returns the pinned element (key) of the Pot 59 func (t *Pot) Pin() Val { 60 return t.pin 61 } 62 63 // Size returns the number of values in the Pot 64 func (t *Pot) Size() int { 65 if t == nil { 66 return 0 67 } 68 return t.size 69 } 70 71 // Add inserts a new value into the Pot and 72 // returns the proximity order of v and a boolean 73 // indicating if the item was found 74 // Add called on (t, v) returns a new Pot that contains all the elements of t 75 // plus the value v, using the applicative add 76 // the second return value is the proximity order of the inserted element 77 // the third is boolean indicating if the item was found 78 func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 79 return add(t, val, pof) 80 } 81 82 func (t *Pot) clone() *Pot { 83 return &Pot{ 84 pin: t.pin, 85 size: t.size, 86 po: t.po, 87 bins: t.bins, 88 } 89 } 90 91 func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { 92 var r *Pot 93 if t == nil || t.pin == nil { 94 r = t.clone() 95 r.pin = val 96 r.size++ 97 return r, 0, false 98 } 99 po, found := pof(t.pin, val, t.po) 100 if found { 101 r = t.clone() 102 r.pin = val 103 return r, po, true 104 } 105 106 var p *Pot 107 var i, j int 108 size := t.size 109 for i < len(t.bins) { 110 n := t.bins[i] 111 if n.po == po { 112 p, _, found = add(n, val, pof) 113 if !found { 114 size++ 115 } 116 j++ 117 break 118 } 119 if n.po > po { 120 break 121 } 122 i++ 123 j++ 124 } 125 if p == nil { 126 size++ 127 p = &Pot{ 128 pin: val, 129 size: 1, 130 po: po, 131 } 132 } 133 134 bins := append([]*Pot{}, t.bins[:i]...) 135 bins = append(bins, p) 136 bins = append(bins, t.bins[j:]...) 137 r = &Pot{ 138 pin: t.pin, 139 size: size, 140 po: t.po, 141 bins: bins, 142 } 143 144 return r, po, found 145 } 146 147 // Remove called on (v) deletes v from the Pot and returns 148 // the proximity order of v and a boolean value indicating 149 // if the value was found 150 // Remove called on (t, v) returns a new Pot that contains all the elements of t 151 // minus the value v, using the applicative remove 152 // the second return value is the proximity order of the inserted element 153 // the third is boolean indicating if the item was found 154 func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { 155 return remove(t, v, pof) 156 } 157 158 func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { 159 size := t.size 160 po, found = pof(t.pin, val, t.po) 161 if found { 162 size-- 163 if size == 0 { 164 r = &Pot{ 165 po: t.po, 166 } 167 return r, po, true 168 } 169 i := len(t.bins) - 1 170 last := t.bins[i] 171 r = &Pot{ 172 pin: last.pin, 173 bins: append(t.bins[:i], last.bins...), 174 size: size, 175 po: t.po, 176 } 177 return r, t.po, true 178 } 179 180 var p *Pot 181 var i, j int 182 for i < len(t.bins) { 183 n := t.bins[i] 184 if n.po == po { 185 p, po, found = remove(n, val, pof) 186 if found { 187 size-- 188 } 189 j++ 190 break 191 } 192 if n.po > po { 193 return t, po, false 194 } 195 i++ 196 j++ 197 } 198 bins := t.bins[:i] 199 if p != nil && p.pin != nil { 200 bins = append(bins, p) 201 } 202 bins = append(bins, t.bins[j:]...) 203 r = &Pot{ 204 pin: val, 205 size: size, 206 po: t.po, 207 bins: bins, 208 } 209 return r, po, found 210 } 211 212 // Swap called on (k, f) looks up the item at k 213 // and applies the function f to the value v at k or to nil if the item is not found 214 // if f(v) returns nil, the element is removed 215 // if f(v) returns v' <> v then v' is inserted into the Pot 216 // if (v) == v the Pot is not changed 217 // it panics if Pof(f(v), k) show that v' and v are not key-equal 218 func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { 219 var val Val 220 if t.pin == nil { 221 val = f(nil) 222 if val == nil { 223 return nil, 0, false, false 224 } 225 return NewPot(val, t.po), 0, false, true 226 } 227 size := t.size 228 po, found = pof(k, t.pin, t.po) 229 if found { 230 val = f(t.pin) 231 // remove element 232 if val == nil { 233 size-- 234 if size == 0 { 235 r = &Pot{ 236 po: t.po, 237 } 238 // return empty pot 239 return r, po, true, true 240 } 241 // actually remove pin, by merging last bin 242 i := len(t.bins) - 1 243 last := t.bins[i] 244 r = &Pot{ 245 pin: last.pin, 246 bins: append(t.bins[:i], last.bins...), 247 size: size, 248 po: t.po, 249 } 250 return r, po, true, true 251 } 252 // element found but no change 253 if val == t.pin { 254 return t, po, true, false 255 } 256 // actually modify the pinned element, but no change in structure 257 r = t.clone() 258 r.pin = val 259 return r, po, true, true 260 } 261 262 // recursive step 263 var p *Pot 264 n, i := t.getPos(po) 265 if n != nil { 266 p, po, found, change = Swap(n, k, pof, f) 267 // recursive no change 268 if !change { 269 return t, po, found, false 270 } 271 // recursive change 272 bins := append([]*Pot{}, t.bins[:i]...) 273 if p.size == 0 { 274 size-- 275 } else { 276 size += p.size - n.size 277 bins = append(bins, p) 278 } 279 i++ 280 if i < len(t.bins) { 281 bins = append(bins, t.bins[i:]...) 282 } 283 r = t.clone() 284 r.bins = bins 285 r.size = size 286 return r, po, found, true 287 } 288 // key does not exist 289 val = f(nil) 290 if val == nil { 291 // and it should not be created 292 return t, po, false, false 293 } 294 // otherwise check val if equal to k 295 if _, eq := pof(val, k, po); !eq { 296 panic("invalid value") 297 } 298 /// 299 size++ 300 p = &Pot{ 301 pin: val, 302 size: 1, 303 po: po, 304 } 305 306 bins := append([]*Pot{}, t.bins[:i]...) 307 bins = append(bins, p) 308 if i < len(t.bins) { 309 bins = append(bins, t.bins[i:]...) 310 } 311 r = t.clone() 312 r.bins = bins 313 r.size = size 314 return r, po, found, true 315 } 316 317 // Union called on (t0, t1, pof) returns the union of t0 and t1 318 // calculates the union using the applicative union 319 // the second return value is the number of common elements 320 func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { 321 return union(t0, t1, pof) 322 } 323 324 func union(t0, t1 *Pot, pof Pof) (*Pot, int) { 325 if t0 == nil || t0.size == 0 { 326 return t1, 0 327 } 328 if t1 == nil || t1.size == 0 { 329 return t0, 0 330 } 331 var pin Val 332 var bins []*Pot 333 var mis []int 334 wg := &sync.WaitGroup{} 335 wg.Add(1) 336 pin0 := t0.pin 337 pin1 := t1.pin 338 bins0 := t0.bins 339 bins1 := t1.bins 340 var i0, i1 int 341 var common int 342 343 po, eq := pof(pin0, pin1, 0) 344 345 for { 346 l0 := len(bins0) 347 l1 := len(bins1) 348 var n0, n1 *Pot 349 var p0, p1 int 350 var a0, a1 bool 351 352 for { 353 354 if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { 355 n0 = bins0[i0] 356 p0 = n0.po 357 a0 = p0 == po 358 } else { 359 a0 = true 360 } 361 362 if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { 363 n1 = bins1[i1] 364 p1 = n1.po 365 a1 = p1 == po 366 } else { 367 a1 = true 368 } 369 if a0 && a1 { 370 break 371 } 372 373 switch { 374 case (p0 < p1 || a1) && !a0: 375 bins = append(bins, n0) 376 i0++ 377 n0 = nil 378 case (p1 < p0 || a0) && !a1: 379 bins = append(bins, n1) 380 i1++ 381 n1 = nil 382 case p1 < po: 383 bl := len(bins) 384 bins = append(bins, nil) 385 ml := len(mis) 386 mis = append(mis, 0) 387 // wg.Add(1) 388 // go func(b, m int, m0, m1 *Pot) { 389 // defer wg.Done() 390 // bins[b], mis[m] = union(m0, m1, pof) 391 // }(bl, ml, n0, n1) 392 bins[bl], mis[ml] = union(n0, n1, pof) 393 i0++ 394 i1++ 395 n0 = nil 396 n1 = nil 397 } 398 } 399 400 if eq { 401 common++ 402 pin = pin1 403 break 404 } 405 406 i := i0 407 if len(bins0) > i && bins0[i].po == po { 408 i++ 409 } 410 var size0 int 411 for _, n := range bins0[i:] { 412 size0 += n.size 413 } 414 np := &Pot{ 415 pin: pin0, 416 bins: bins0[i:], 417 size: size0 + 1, 418 po: po, 419 } 420 421 bins2 := []*Pot{np} 422 if n0 == nil { 423 pin0 = pin1 424 po = maxkeylen + 1 425 eq = true 426 common-- 427 428 } else { 429 bins2 = append(bins2, n0.bins...) 430 pin0 = pin1 431 pin1 = n0.pin 432 po, eq = pof(pin0, pin1, n0.po) 433 434 } 435 bins0 = bins1 436 bins1 = bins2 437 i0 = i1 438 i1 = 0 439 440 } 441 442 wg.Done() 443 wg.Wait() 444 for _, c := range mis { 445 common += c 446 } 447 n := &Pot{ 448 pin: pin, 449 bins: bins, 450 size: t0.size + t1.size - common, 451 po: t0.po, 452 } 453 return n, common 454 } 455 456 // Each called with (f) is a synchronous iterator over the bins of a node 457 // respecting an ordering 458 // proximity > pinnedness 459 func (t *Pot) Each(f func(Val, int) bool) bool { 460 return t.each(f) 461 } 462 463 func (t *Pot) each(f func(Val, int) bool) bool { 464 var next bool 465 for _, n := range t.bins { 466 if n == nil { 467 return true 468 } 469 next = n.each(f) 470 if !next { 471 return false 472 } 473 } 474 if t.size == 0 { 475 return false 476 } 477 return f(t.pin, t.po) 478 } 479 480 // EachFrom called with (f, start) is a synchronous iterator over the elements of a Pot 481 // within the inclusive range starting from proximity order start 482 // the function argument is passed the value and the proximity order wrt the root pin 483 // it does NOT include the pinned item of the root 484 // respecting an ordering 485 // proximity > pinnedness 486 // the iteration ends if the function return false or there are no more elements 487 // end of a po range can be implemented since po is passed to the function 488 func (t *Pot) EachFrom(f func(Val, int) bool, po int) bool { 489 return t.eachFrom(f, po) 490 } 491 492 func (t *Pot) eachFrom(f func(Val, int) bool, po int) bool { 493 var next bool 494 _, lim := t.getPos(po) 495 for i := lim; i < len(t.bins); i++ { 496 n := t.bins[i] 497 next = n.each(f) 498 if !next { 499 return false 500 } 501 } 502 return f(t.pin, t.po) 503 } 504 505 // EachBin iterates over bins of the pivot node and offers iterators to the caller on each 506 // subtree passing the proximity order and the size 507 // the iteration continues until the function's return value is false 508 // or there are no more subtries 509 func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { 510 t.eachBin(val, pof, po, f) 511 } 512 513 func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) { 514 if t == nil || t.size == 0 { 515 return 516 } 517 spr, _ := pof(t.pin, val, t.po) 518 _, lim := t.getPos(spr) 519 var size int 520 var n *Pot 521 for i := 0; i < lim; i++ { 522 n = t.bins[i] 523 size += n.size 524 if n.po < po { 525 continue 526 } 527 if !f(n.po, n.size, n.each) { 528 return 529 } 530 } 531 if lim == len(t.bins) { 532 if spr >= po { 533 f(spr, 1, func(g func(Val, int) bool) bool { 534 return g(t.pin, spr) 535 }) 536 } 537 return 538 } 539 540 n = t.bins[lim] 541 542 spo := spr 543 if n.po == spr { 544 spo++ 545 size += n.size 546 } 547 if spr >= po { 548 if !f(spr, t.size-size, func(g func(Val, int) bool) bool { 549 return t.eachFrom(func(v Val, j int) bool { 550 return g(v, spr) 551 }, spo) 552 }) { 553 return 554 } 555 } 556 if n.po == spr { 557 n.eachBin(val, pof, po, f) 558 } 559 560 } 561 562 // EachNeighbour is a synchronous iterator over neighbours of any target val 563 // the order of elements retrieved reflect proximity order to the target 564 // TODO: add maximum proxbin to start range of iteration 565 func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 566 return t.eachNeighbour(val, pof, f) 567 } 568 569 func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 570 if t == nil || t.size == 0 { 571 return false 572 } 573 var next bool 574 l := len(t.bins) 575 var n *Pot 576 ir := l 577 il := l 578 po, eq := pof(t.pin, val, t.po) 579 if !eq { 580 n, il = t.getPos(po) 581 if n != nil { 582 next = n.eachNeighbour(val, pof, f) 583 if !next { 584 return false 585 } 586 ir = il 587 } else { 588 ir = il - 1 589 } 590 } 591 592 next = f(t.pin, po) 593 if !next { 594 return false 595 } 596 597 for i := l - 1; i > ir; i-- { 598 next = t.bins[i].each(func(v Val, _ int) bool { 599 return f(v, po) 600 }) 601 if !next { 602 return false 603 } 604 } 605 606 for i := il - 1; i >= 0; i-- { 607 n := t.bins[i] 608 next = n.each(func(v Val, _ int) bool { 609 return f(v, n.po) 610 }) 611 if !next { 612 return false 613 } 614 } 615 return true 616 } 617 618 // EachNeighbourAsync called on (val, max, maxPos, f, wait) is an asynchronous iterator 619 // over elements not closer than maxPos wrt val. 620 // val does not need to be match an element of the Pot, but if it does, and 621 // maxPos is keylength than it is included in the iteration 622 // Calls to f are parallelised, the order of calls is undefined. 623 // proximity order is respected in that there is no element in the Pot that 624 // is not visited if a closer node is visited. 625 // The iteration is finished when max number of nearest nodes is visited 626 // or if the entire there are no nodes not closer than maxPos that is not visited 627 // if wait is true, the iterator returns only if all calls to f are finished 628 // TODO: implement minPos for proper prox range iteration 629 func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { 630 if max > t.size { 631 max = t.size 632 } 633 var wg *sync.WaitGroup 634 if wait { 635 wg = &sync.WaitGroup{} 636 } 637 t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) 638 if wait { 639 wg.Wait() 640 } 641 } 642 643 func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { 644 l := len(t.bins) 645 646 po, eq := pof(t.pin, val, t.po) 647 648 // if po is too close, set the pivot branch (pom) to maxPos 649 pom := po 650 if pom > maxPos { 651 pom = maxPos 652 } 653 n, il := t.getPos(pom) 654 ir := il 655 // if pivot branch exists and po is not too close, iterate on the pivot branch 656 if pom == po { 657 if n != nil { 658 659 m := n.size 660 if max < m { 661 m = max 662 } 663 max -= m 664 665 extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) 666 667 } else { 668 if !eq { 669 ir-- 670 } 671 } 672 } else { 673 extra++ 674 max-- 675 if n != nil { 676 il++ 677 } 678 // before checking max, add up the extra elements 679 // on the close branches that are skipped (if po is too close) 680 for i := l - 1; i >= il; i-- { 681 s := t.bins[i] 682 m := s.size 683 if max < m { 684 m = max 685 } 686 max -= m 687 extra += m 688 } 689 } 690 691 var m int 692 if pom == po { 693 694 m, max, extra = need(1, max, extra) 695 if m <= 0 { 696 return 697 } 698 699 if wg != nil { 700 wg.Add(1) 701 } 702 go func() { 703 if wg != nil { 704 defer wg.Done() 705 } 706 f(t.pin, po) 707 }() 708 709 // otherwise iterats 710 for i := l - 1; i > ir; i-- { 711 n := t.bins[i] 712 713 m, max, extra = need(n.size, max, extra) 714 if m <= 0 { 715 return 716 } 717 718 if wg != nil { 719 wg.Add(m) 720 } 721 go func(pn *Pot, pm int) { 722 pn.each(func(v Val, _ int) bool { 723 if wg != nil { 724 defer wg.Done() 725 } 726 f(v, po) 727 pm-- 728 return pm > 0 729 }) 730 }(n, m) 731 732 } 733 } 734 735 // iterate branches that are farther tham pom with their own po 736 for i := il - 1; i >= 0; i-- { 737 n := t.bins[i] 738 // the first time max is less than the size of the entire branch 739 // wait for the pivot thread to release extra elements 740 m, max, extra = need(n.size, max, extra) 741 if m <= 0 { 742 return 743 } 744 745 if wg != nil { 746 wg.Add(m) 747 } 748 go func(pn *Pot, pm int) { 749 pn.each(func(v Val, _ int) bool { 750 if wg != nil { 751 defer wg.Done() 752 } 753 f(v, pn.po) 754 pm-- 755 return pm > 0 756 }) 757 }(n, m) 758 759 } 760 return max + extra 761 } 762 763 // getPos called on (n) returns the forking node at PO n and its index if it exists 764 // otherwise nil 765 // caller is supposed to hold the lock 766 func (t *Pot) getPos(po int) (n *Pot, i int) { 767 for i, n = range t.bins { 768 if po > n.po { 769 continue 770 } 771 if po < n.po { 772 return nil, i 773 } 774 return n, i 775 } 776 return nil, len(t.bins) 777 } 778 779 // need called on (m, max, extra) uses max m out of extra, and then max 780 // if needed, returns the adjusted counts 781 func need(m, max, extra int) (int, int, int) { 782 if m <= extra { 783 return m, max, extra - m 784 } 785 max += extra - m 786 if max <= 0 { 787 return m + max, 0, 0 788 } 789 return m, max, 0 790 } 791 792 func (t *Pot) String() string { 793 return t.sstring("") 794 } 795 796 func (t *Pot) sstring(indent string) string { 797 if t == nil { 798 return "<nil>" 799 } 800 var s string 801 indent += " " 802 s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) 803 for _, n := range t.bins { 804 s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) 805 } 806 return s 807 }