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