github.com/maynardminer/ethereumprogpow@v1.8.23/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  }