github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/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 deletes element v from the Pot t and returns three parameters: 148 // 1. new Pot that contains all the elements of t minus the element v; 149 // 2. proximity order of the removed element v; 150 // 3. boolean indicating whether the item was found. 151 func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { 152 return remove(t, v, pof) 153 } 154 155 func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { 156 size := t.size 157 po, found = pof(t.pin, val, t.po) 158 if found { 159 size-- 160 if size == 0 { 161 return &Pot{}, po, true 162 } 163 i := len(t.bins) - 1 164 last := t.bins[i] 165 r = &Pot{ 166 pin: last.pin, 167 bins: append(t.bins[:i], last.bins...), 168 size: size, 169 po: t.po, 170 } 171 return r, t.po, true 172 } 173 174 var p *Pot 175 var i, j int 176 for i < len(t.bins) { 177 n := t.bins[i] 178 if n.po == po { 179 p, po, found = remove(n, val, pof) 180 if found { 181 size-- 182 } 183 j++ 184 break 185 } 186 if n.po > po { 187 return t, po, false 188 } 189 i++ 190 j++ 191 } 192 bins := t.bins[:i] 193 if p != nil && p.pin != nil { 194 bins = append(bins, p) 195 } 196 bins = append(bins, t.bins[j:]...) 197 r = &Pot{ 198 pin: t.pin, 199 size: size, 200 po: t.po, 201 bins: bins, 202 } 203 return r, po, found 204 } 205 206 // Swap called on (k, f) looks up the item at k 207 // and applies the function f to the value v at k or to nil if the item is not found 208 // if f(v) returns nil, the element is removed 209 // if f(v) returns v' <> v then v' is inserted into the Pot 210 // if (v) == v the Pot is not changed 211 // it panics if Pof(f(v), k) show that v' and v are not key-equal 212 func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { 213 var val Val 214 if t.pin == nil { 215 val = f(nil) 216 if val == nil { 217 return nil, 0, false, false 218 } 219 return NewPot(val, t.po), 0, false, true 220 } 221 size := t.size 222 po, found = pof(k, t.pin, t.po) 223 if found { 224 val = f(t.pin) 225 // remove element 226 if val == nil { 227 size-- 228 if size == 0 { 229 r = &Pot{ 230 po: t.po, 231 } 232 // return empty pot 233 return r, po, true, true 234 } 235 // actually remove pin, by merging last bin 236 i := len(t.bins) - 1 237 last := t.bins[i] 238 r = &Pot{ 239 pin: last.pin, 240 bins: append(t.bins[:i], last.bins...), 241 size: size, 242 po: t.po, 243 } 244 return r, po, true, true 245 } 246 // element found but no change 247 if val == t.pin { 248 return t, po, true, false 249 } 250 // actually modify the pinned element, but no change in structure 251 r = t.clone() 252 r.pin = val 253 return r, po, true, true 254 } 255 256 // recursive step 257 var p *Pot 258 n, i := t.getPos(po) 259 if n != nil { 260 p, po, found, change = Swap(n, k, pof, f) 261 // recursive no change 262 if !change { 263 return t, po, found, false 264 } 265 // recursive change 266 bins := append([]*Pot{}, t.bins[:i]...) 267 if p.size == 0 { 268 size-- 269 } else { 270 size += p.size - n.size 271 bins = append(bins, p) 272 } 273 i++ 274 if i < len(t.bins) { 275 bins = append(bins, t.bins[i:]...) 276 } 277 r = t.clone() 278 r.bins = bins 279 r.size = size 280 return r, po, found, true 281 } 282 // key does not exist 283 val = f(nil) 284 if val == nil { 285 // and it should not be created 286 return t, po, false, false 287 } 288 // otherwise check val if equal to k 289 if _, eq := pof(val, k, po); !eq { 290 panic("invalid value") 291 } 292 /// 293 size++ 294 p = &Pot{ 295 pin: val, 296 size: 1, 297 po: po, 298 } 299 300 bins := append([]*Pot{}, t.bins[:i]...) 301 bins = append(bins, p) 302 if i < len(t.bins) { 303 bins = append(bins, t.bins[i:]...) 304 } 305 r = t.clone() 306 r.bins = bins 307 r.size = size 308 return r, po, found, true 309 } 310 311 // Union called on (t0, t1, pof) returns the union of t0 and t1 312 // calculates the union using the applicative union 313 // the second return value is the number of common elements 314 func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { 315 return union(t0, t1, pof) 316 } 317 318 func union(t0, t1 *Pot, pof Pof) (*Pot, int) { 319 if t0 == nil || t0.size == 0 { 320 return t1, 0 321 } 322 if t1 == nil || t1.size == 0 { 323 return t0, 0 324 } 325 var pin Val 326 var bins []*Pot 327 var mis []int 328 wg := &sync.WaitGroup{} 329 wg.Add(1) 330 pin0 := t0.pin 331 pin1 := t1.pin 332 bins0 := t0.bins 333 bins1 := t1.bins 334 var i0, i1 int 335 var common int 336 337 po, eq := pof(pin0, pin1, 0) 338 339 for { 340 l0 := len(bins0) 341 l1 := len(bins1) 342 var n0, n1 *Pot 343 var p0, p1 int 344 var a0, a1 bool 345 346 for { 347 348 if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { 349 n0 = bins0[i0] 350 p0 = n0.po 351 a0 = p0 == po 352 } else { 353 a0 = true 354 } 355 356 if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { 357 n1 = bins1[i1] 358 p1 = n1.po 359 a1 = p1 == po 360 } else { 361 a1 = true 362 } 363 if a0 && a1 { 364 break 365 } 366 367 switch { 368 case (p0 < p1 || a1) && !a0: 369 bins = append(bins, n0) 370 i0++ 371 n0 = nil 372 case (p1 < p0 || a0) && !a1: 373 bins = append(bins, n1) 374 i1++ 375 n1 = nil 376 case p1 < po: 377 bl := len(bins) 378 bins = append(bins, nil) 379 ml := len(mis) 380 mis = append(mis, 0) 381 // wg.Add(1) 382 // go func(b, m int, m0, m1 *Pot) { 383 // defer wg.Done() 384 // bins[b], mis[m] = union(m0, m1, pof) 385 // }(bl, ml, n0, n1) 386 bins[bl], mis[ml] = union(n0, n1, pof) 387 i0++ 388 i1++ 389 n0 = nil 390 n1 = nil 391 } 392 } 393 394 if eq { 395 common++ 396 pin = pin1 397 break 398 } 399 400 i := i0 401 if len(bins0) > i && bins0[i].po == po { 402 i++ 403 } 404 var size0 int 405 for _, n := range bins0[i:] { 406 size0 += n.size 407 } 408 np := &Pot{ 409 pin: pin0, 410 bins: bins0[i:], 411 size: size0 + 1, 412 po: po, 413 } 414 415 bins2 := []*Pot{np} 416 if n0 == nil { 417 pin0 = pin1 418 po = maxkeylen + 1 419 eq = true 420 common-- 421 422 } else { 423 bins2 = append(bins2, n0.bins...) 424 pin0 = pin1 425 pin1 = n0.pin 426 po, eq = pof(pin0, pin1, n0.po) 427 428 } 429 bins0 = bins1 430 bins1 = bins2 431 i0 = i1 432 i1 = 0 433 434 } 435 436 wg.Done() 437 wg.Wait() 438 for _, c := range mis { 439 common += c 440 } 441 n := &Pot{ 442 pin: pin, 443 bins: bins, 444 size: t0.size + t1.size - common, 445 po: t0.po, 446 } 447 return n, common 448 } 449 450 // Each is a synchronous iterator over the elements of pot with function f. 451 func (t *Pot) Each(f func(Val) bool) bool { 452 return t.each(f) 453 } 454 455 // each is a synchronous iterator over the elements of pot with function f. 456 // the iteration ends if the function return false or there are no more elements. 457 func (t *Pot) each(f func(Val) bool) bool { 458 if t == nil || t.size == 0 { 459 return false 460 } 461 for _, n := range t.bins { 462 if !n.each(f) { 463 return false 464 } 465 } 466 return f(t.pin) 467 } 468 469 // eachFrom is a synchronous iterator over the elements of pot with function f, 470 // starting from certain proximity order po, which is passed as a second parameter. 471 // the iteration ends if the function return false or there are no more elements. 472 func (t *Pot) eachFrom(f func(Val) bool, po int) bool { 473 if t == nil || t.size == 0 { 474 return false 475 } 476 _, beg := t.getPos(po) 477 for i := beg; i < len(t.bins); i++ { 478 if !t.bins[i].each(f) { 479 return false 480 } 481 } 482 return f(t.pin) 483 } 484 485 // EachBin iterates over bins of the pivot node and offers iterators to the caller on each 486 // subtree passing the proximity order and the size 487 // the iteration continues until the function's return value is false 488 // or there are no more subtries 489 func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { 490 t.eachBin(val, pof, po, f) 491 } 492 493 func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { 494 if t == nil || t.size == 0 { 495 return 496 } 497 spr, _ := pof(t.pin, val, t.po) 498 _, lim := t.getPos(spr) 499 var size int 500 var n *Pot 501 for i := 0; i < lim; i++ { 502 n = t.bins[i] 503 size += n.size 504 if n.po < po { 505 continue 506 } 507 if !f(n.po, n.size, n.each) { 508 return 509 } 510 } 511 if lim == len(t.bins) { 512 if spr >= po { 513 f(spr, 1, func(g func(Val) bool) bool { 514 return g(t.pin) 515 }) 516 } 517 return 518 } 519 520 n = t.bins[lim] 521 522 spo := spr 523 if n.po == spr { 524 spo++ 525 size += n.size 526 } 527 if spr >= po { 528 if !f(spr, t.size-size, func(g func(Val) bool) bool { 529 return t.eachFrom(func(v Val) bool { 530 return g(v) 531 }, spo) 532 }) { 533 return 534 } 535 } 536 if n.po == spr { 537 n.eachBin(val, pof, po, f) 538 } 539 540 } 541 542 // EachNeighbour is a synchronous iterator over neighbours of any target val 543 // the order of elements retrieved reflect proximity order to the target 544 // TODO: add maximum proxbin to start range of iteration 545 func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 546 return t.eachNeighbour(val, pof, f) 547 } 548 549 func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { 550 if t == nil || t.size == 0 { 551 return false 552 } 553 var next bool 554 l := len(t.bins) 555 var n *Pot 556 ir := l 557 il := l 558 po, eq := pof(t.pin, val, t.po) 559 if !eq { 560 n, il = t.getPos(po) 561 if n != nil { 562 next = n.eachNeighbour(val, pof, f) 563 if !next { 564 return false 565 } 566 ir = il 567 } else { 568 ir = il - 1 569 } 570 } 571 572 next = f(t.pin, po) 573 if !next { 574 return false 575 } 576 577 for i := l - 1; i > ir; i-- { 578 next = t.bins[i].each(func(v Val) bool { 579 return f(v, po) 580 }) 581 if !next { 582 return false 583 } 584 } 585 586 for i := il - 1; i >= 0; i-- { 587 n := t.bins[i] 588 next = n.each(func(v Val) bool { 589 return f(v, n.po) 590 }) 591 if !next { 592 return false 593 } 594 } 595 return true 596 } 597 598 // EachNeighbourAsync called on (val, max, maxPos, f, wait) is an asynchronous iterator 599 // over elements not closer than maxPos wrt val. 600 // val does not need to be match an element of the Pot, but if it does, and 601 // maxPos is keylength than it is included in the iteration 602 // Calls to f are parallelised, the order of calls is undefined. 603 // proximity order is respected in that there is no element in the Pot that 604 // is not visited if a closer node is visited. 605 // The iteration is finished when max number of nearest nodes is visited 606 // or if the entire there are no nodes not closer than maxPos that is not visited 607 // if wait is true, the iterator returns only if all calls to f are finished 608 // TODO: implement minPos for proper prox range iteration 609 func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { 610 if max > t.size { 611 max = t.size 612 } 613 var wg *sync.WaitGroup 614 if wait { 615 wg = &sync.WaitGroup{} 616 } 617 t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) 618 if wait { 619 wg.Wait() 620 } 621 } 622 623 func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { 624 l := len(t.bins) 625 626 po, eq := pof(t.pin, val, t.po) 627 628 // if po is too close, set the pivot branch (pom) to maxPos 629 pom := po 630 if pom > maxPos { 631 pom = maxPos 632 } 633 n, il := t.getPos(pom) 634 ir := il 635 // if pivot branch exists and po is not too close, iterate on the pivot branch 636 if pom == po { 637 if n != nil { 638 639 m := n.size 640 if max < m { 641 m = max 642 } 643 max -= m 644 645 extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) 646 647 } else { 648 if !eq { 649 ir-- 650 } 651 } 652 } else { 653 extra++ 654 max-- 655 if n != nil { 656 il++ 657 } 658 // before checking max, add up the extra elements 659 // on the close branches that are skipped (if po is too close) 660 for i := l - 1; i >= il; i-- { 661 s := t.bins[i] 662 m := s.size 663 if max < m { 664 m = max 665 } 666 max -= m 667 extra += m 668 } 669 } 670 671 var m int 672 if pom == po { 673 674 m, max, extra = need(1, max, extra) 675 if m <= 0 { 676 return 677 } 678 679 if wg != nil { 680 wg.Add(1) 681 } 682 go func() { 683 if wg != nil { 684 defer wg.Done() 685 } 686 f(t.pin, po) 687 }() 688 689 // otherwise iterats 690 for i := l - 1; i > ir; i-- { 691 n := t.bins[i] 692 693 m, max, extra = need(n.size, max, extra) 694 if m <= 0 { 695 return 696 } 697 698 if wg != nil { 699 wg.Add(m) 700 } 701 go func(pn *Pot, pm int) { 702 pn.each(func(v Val) bool { 703 if wg != nil { 704 defer wg.Done() 705 } 706 f(v, po) 707 pm-- 708 return pm > 0 709 }) 710 }(n, m) 711 712 } 713 } 714 715 // iterate branches that are farther tham pom with their own po 716 for i := il - 1; i >= 0; i-- { 717 n := t.bins[i] 718 // the first time max is less than the size of the entire branch 719 // wait for the pivot thread to release extra elements 720 m, max, extra = need(n.size, max, extra) 721 if m <= 0 { 722 return 723 } 724 725 if wg != nil { 726 wg.Add(m) 727 } 728 go func(pn *Pot, pm int) { 729 pn.each(func(v Val) bool { 730 if wg != nil { 731 defer wg.Done() 732 } 733 f(v, pn.po) 734 pm-- 735 return pm > 0 736 }) 737 }(n, m) 738 739 } 740 return max + extra 741 } 742 743 // getPos called on (n) returns the forking node at PO n and its index if it exists 744 // otherwise nil 745 // caller is supposed to hold the lock 746 func (t *Pot) getPos(po int) (n *Pot, i int) { 747 for i, n = range t.bins { 748 if po > n.po { 749 continue 750 } 751 if po < n.po { 752 return nil, i 753 } 754 return n, i 755 } 756 return nil, len(t.bins) 757 } 758 759 // need called on (m, max, extra) uses max m out of extra, and then max 760 // if needed, returns the adjusted counts 761 func need(m, max, extra int) (int, int, int) { 762 if m <= extra { 763 return m, max, extra - m 764 } 765 max += extra - m 766 if max <= 0 { 767 return m + max, 0, 0 768 } 769 return m, max, 0 770 } 771 772 func (t *Pot) String() string { 773 return t.sstring("") 774 } 775 776 func (t *Pot) sstring(indent string) string { 777 if t == nil { 778 return "<nil>" 779 } 780 var s string 781 indent += " " 782 s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) 783 for _, n := range t.bins { 784 s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) 785 } 786 return s 787 }