github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pot/pot.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  //
    26  package pot
    27  
    28  import (
    29  	"fmt"
    30  	"sync"
    31  )
    32  
    33  const (
    34  	maxkeylen = 256
    35  )
    36  
    37  //
    38  type Pot struct {
    39  	pin  Val
    40  	bins []*Pot
    41  	size int
    42  	po   int
    43  }
    44  
    45  //
    46  type Val interface{}
    47  
    48  //
    49  type Pof func(Val, Val, int) (int, bool)
    50  
    51  //
    52  //
    53  //
    54  func NewPot(v Val, po int) *Pot {
    55  	var size int
    56  	if v != nil {
    57  		size++
    58  	}
    59  	return &Pot{
    60  		pin:  v,
    61  		po:   po,
    62  		size: size,
    63  	}
    64  }
    65  
    66  //
    67  func (t *Pot) Pin() Val {
    68  	return t.pin
    69  }
    70  
    71  //
    72  func (t *Pot) Size() int {
    73  	if t == nil {
    74  		return 0
    75  	}
    76  	return t.size
    77  }
    78  
    79  //
    80  //
    81  //
    82  //
    83  //
    84  //
    85  //
    86  func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) {
    87  	return add(t, val, pof)
    88  }
    89  
    90  func (t *Pot) clone() *Pot {
    91  	return &Pot{
    92  		pin:  t.pin,
    93  		size: t.size,
    94  		po:   t.po,
    95  		bins: t.bins,
    96  	}
    97  }
    98  
    99  func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) {
   100  	var r *Pot
   101  	if t == nil || t.pin == nil {
   102  		r = t.clone()
   103  		r.pin = val
   104  		r.size++
   105  		return r, 0, false
   106  	}
   107  	po, found := pof(t.pin, val, t.po)
   108  	if found {
   109  		r = t.clone()
   110  		r.pin = val
   111  		return r, po, true
   112  	}
   113  
   114  	var p *Pot
   115  	var i, j int
   116  	size := t.size
   117  	for i < len(t.bins) {
   118  		n := t.bins[i]
   119  		if n.po == po {
   120  			p, _, found = add(n, val, pof)
   121  			if !found {
   122  				size++
   123  			}
   124  			j++
   125  			break
   126  		}
   127  		if n.po > po {
   128  			break
   129  		}
   130  		i++
   131  		j++
   132  	}
   133  	if p == nil {
   134  		size++
   135  		p = &Pot{
   136  			pin:  val,
   137  			size: 1,
   138  			po:   po,
   139  		}
   140  	}
   141  
   142  	bins := append([]*Pot{}, t.bins[:i]...)
   143  	bins = append(bins, p)
   144  	bins = append(bins, t.bins[j:]...)
   145  	r = &Pot{
   146  		pin:  t.pin,
   147  		size: size,
   148  		po:   t.po,
   149  		bins: bins,
   150  	}
   151  
   152  	return r, po, found
   153  }
   154  
   155  //
   156  //
   157  //
   158  //
   159  //
   160  //
   161  //
   162  func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) {
   163  	return remove(t, v, pof)
   164  }
   165  
   166  func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) {
   167  	size := t.size
   168  	po, found = pof(t.pin, val, t.po)
   169  	if found {
   170  		size--
   171  		if size == 0 {
   172  			r = &Pot{
   173  				po: t.po,
   174  			}
   175  			return r, po, true
   176  		}
   177  		i := len(t.bins) - 1
   178  		last := t.bins[i]
   179  		r = &Pot{
   180  			pin:  last.pin,
   181  			bins: append(t.bins[:i], last.bins...),
   182  			size: size,
   183  			po:   t.po,
   184  		}
   185  		return r, t.po, true
   186  	}
   187  
   188  	var p *Pot
   189  	var i, j int
   190  	for i < len(t.bins) {
   191  		n := t.bins[i]
   192  		if n.po == po {
   193  			p, po, found = remove(n, val, pof)
   194  			if found {
   195  				size--
   196  			}
   197  			j++
   198  			break
   199  		}
   200  		if n.po > po {
   201  			return t, po, false
   202  		}
   203  		i++
   204  		j++
   205  	}
   206  	bins := t.bins[:i]
   207  	if p != nil && p.pin != nil {
   208  		bins = append(bins, p)
   209  	}
   210  	bins = append(bins, t.bins[j:]...)
   211  	r = &Pot{
   212  		pin:  val,
   213  		size: size,
   214  		po:   t.po,
   215  		bins: bins,
   216  	}
   217  	return r, po, found
   218  }
   219  
   220  //
   221  //
   222  //
   223  //
   224  //
   225  //
   226  func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) {
   227  	var val Val
   228  	if t.pin == nil {
   229  		val = f(nil)
   230  		if val == nil {
   231  			return nil, 0, false, false
   232  		}
   233  		return NewPot(val, t.po), 0, false, true
   234  	}
   235  	size := t.size
   236  	po, found = pof(k, t.pin, t.po)
   237  	if found {
   238  		val = f(t.pin)
   239  //
   240  		if val == nil {
   241  			size--
   242  			if size == 0 {
   243  				r = &Pot{
   244  					po: t.po,
   245  				}
   246  //
   247  				return r, po, true, true
   248  			}
   249  //
   250  			i := len(t.bins) - 1
   251  			last := t.bins[i]
   252  			r = &Pot{
   253  				pin:  last.pin,
   254  				bins: append(t.bins[:i], last.bins...),
   255  				size: size,
   256  				po:   t.po,
   257  			}
   258  			return r, po, true, true
   259  		}
   260  //
   261  		if val == t.pin {
   262  			return t, po, true, false
   263  		}
   264  //
   265  		r = t.clone()
   266  		r.pin = val
   267  		return r, po, true, true
   268  	}
   269  
   270  //
   271  	var p *Pot
   272  	n, i := t.getPos(po)
   273  	if n != nil {
   274  		p, po, found, change = Swap(n, k, pof, f)
   275  //
   276  		if !change {
   277  			return t, po, found, false
   278  		}
   279  //
   280  		bins := append([]*Pot{}, t.bins[:i]...)
   281  		if p.size == 0 {
   282  			size--
   283  		} else {
   284  			size += p.size - n.size
   285  			bins = append(bins, p)
   286  		}
   287  		i++
   288  		if i < len(t.bins) {
   289  			bins = append(bins, t.bins[i:]...)
   290  		}
   291  		r = t.clone()
   292  		r.bins = bins
   293  		r.size = size
   294  		return r, po, found, true
   295  	}
   296  //
   297  	val = f(nil)
   298  	if val == nil {
   299  //
   300  		return t, po, false, false
   301  	}
   302  //
   303  	if _, eq := pof(val, k, po); !eq {
   304  		panic("invalid value")
   305  	}
   306  //
   307  	size++
   308  	p = &Pot{
   309  		pin:  val,
   310  		size: 1,
   311  		po:   po,
   312  	}
   313  
   314  	bins := append([]*Pot{}, t.bins[:i]...)
   315  	bins = append(bins, p)
   316  	if i < len(t.bins) {
   317  		bins = append(bins, t.bins[i:]...)
   318  	}
   319  	r = t.clone()
   320  	r.bins = bins
   321  	r.size = size
   322  	return r, po, found, true
   323  }
   324  
   325  //
   326  //
   327  //
   328  func Union(t0, t1 *Pot, pof Pof) (*Pot, int) {
   329  	return union(t0, t1, pof)
   330  }
   331  
   332  func union(t0, t1 *Pot, pof Pof) (*Pot, int) {
   333  	if t0 == nil || t0.size == 0 {
   334  		return t1, 0
   335  	}
   336  	if t1 == nil || t1.size == 0 {
   337  		return t0, 0
   338  	}
   339  	var pin Val
   340  	var bins []*Pot
   341  	var mis []int
   342  	wg := &sync.WaitGroup{}
   343  	wg.Add(1)
   344  	pin0 := t0.pin
   345  	pin1 := t1.pin
   346  	bins0 := t0.bins
   347  	bins1 := t1.bins
   348  	var i0, i1 int
   349  	var common int
   350  
   351  	po, eq := pof(pin0, pin1, 0)
   352  
   353  	for {
   354  		l0 := len(bins0)
   355  		l1 := len(bins1)
   356  		var n0, n1 *Pot
   357  		var p0, p1 int
   358  		var a0, a1 bool
   359  
   360  		for {
   361  
   362  			if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po {
   363  				n0 = bins0[i0]
   364  				p0 = n0.po
   365  				a0 = p0 == po
   366  			} else {
   367  				a0 = true
   368  			}
   369  
   370  			if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po {
   371  				n1 = bins1[i1]
   372  				p1 = n1.po
   373  				a1 = p1 == po
   374  			} else {
   375  				a1 = true
   376  			}
   377  			if a0 && a1 {
   378  				break
   379  			}
   380  
   381  			switch {
   382  			case (p0 < p1 || a1) && !a0:
   383  				bins = append(bins, n0)
   384  				i0++
   385  				n0 = nil
   386  			case (p1 < p0 || a0) && !a1:
   387  				bins = append(bins, n1)
   388  				i1++
   389  				n1 = nil
   390  			case p1 < po:
   391  				bl := len(bins)
   392  				bins = append(bins, nil)
   393  				ml := len(mis)
   394  				mis = append(mis, 0)
   395  //
   396  //
   397  //
   398  //
   399  //
   400  				bins[bl], mis[ml] = union(n0, n1, pof)
   401  				i0++
   402  				i1++
   403  				n0 = nil
   404  				n1 = nil
   405  			}
   406  		}
   407  
   408  		if eq {
   409  			common++
   410  			pin = pin1
   411  			break
   412  		}
   413  
   414  		i := i0
   415  		if len(bins0) > i && bins0[i].po == po {
   416  			i++
   417  		}
   418  		var size0 int
   419  		for _, n := range bins0[i:] {
   420  			size0 += n.size
   421  		}
   422  		np := &Pot{
   423  			pin:  pin0,
   424  			bins: bins0[i:],
   425  			size: size0 + 1,
   426  			po:   po,
   427  		}
   428  
   429  		bins2 := []*Pot{np}
   430  		if n0 == nil {
   431  			pin0 = pin1
   432  			po = maxkeylen + 1
   433  			eq = true
   434  			common--
   435  
   436  		} else {
   437  			bins2 = append(bins2, n0.bins...)
   438  			pin0 = pin1
   439  			pin1 = n0.pin
   440  			po, eq = pof(pin0, pin1, n0.po)
   441  
   442  		}
   443  		bins0 = bins1
   444  		bins1 = bins2
   445  		i0 = i1
   446  		i1 = 0
   447  
   448  	}
   449  
   450  	wg.Done()
   451  	wg.Wait()
   452  	for _, c := range mis {
   453  		common += c
   454  	}
   455  	n := &Pot{
   456  		pin:  pin,
   457  		bins: bins,
   458  		size: t0.size + t1.size - common,
   459  		po:   t0.po,
   460  	}
   461  	return n, common
   462  }
   463  
   464  //
   465  //
   466  //
   467  func (t *Pot) Each(f func(Val, int) bool) bool {
   468  	return t.each(f)
   469  }
   470  
   471  func (t *Pot) each(f func(Val, int) bool) bool {
   472  	var next bool
   473  	for _, n := range t.bins {
   474  		if n == nil {
   475  			return true
   476  		}
   477  		next = n.each(f)
   478  		if !next {
   479  			return false
   480  		}
   481  	}
   482  	if t.size == 0 {
   483  		return false
   484  	}
   485  	return f(t.pin, t.po)
   486  }
   487  
   488  //
   489  //
   490  //
   491  //
   492  //
   493  //
   494  //
   495  //
   496  func (t *Pot) EachFrom(f func(Val, int) bool, po int) bool {
   497  	return t.eachFrom(f, po)
   498  }
   499  
   500  func (t *Pot) eachFrom(f func(Val, int) bool, po int) bool {
   501  	var next bool
   502  	_, lim := t.getPos(po)
   503  	for i := lim; i < len(t.bins); i++ {
   504  		n := t.bins[i]
   505  		next = n.each(f)
   506  		if !next {
   507  			return false
   508  		}
   509  	}
   510  	return f(t.pin, t.po)
   511  }
   512  
   513  //
   514  //
   515  //
   516  //
   517  func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) {
   518  	t.eachBin(val, pof, po, f)
   519  }
   520  
   521  func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val, i int) bool) bool) bool) {
   522  	if t == nil || t.size == 0 {
   523  		return
   524  	}
   525  	spr, _ := pof(t.pin, val, t.po)
   526  	_, lim := t.getPos(spr)
   527  	var size int
   528  	var n *Pot
   529  	for i := 0; i < lim; i++ {
   530  		n = t.bins[i]
   531  		size += n.size
   532  		if n.po < po {
   533  			continue
   534  		}
   535  		if !f(n.po, n.size, n.each) {
   536  			return
   537  		}
   538  	}
   539  	if lim == len(t.bins) {
   540  		if spr >= po {
   541  			f(spr, 1, func(g func(Val, int) bool) bool {
   542  				return g(t.pin, spr)
   543  			})
   544  		}
   545  		return
   546  	}
   547  
   548  	n = t.bins[lim]
   549  
   550  	spo := spr
   551  	if n.po == spr {
   552  		spo++
   553  		size += n.size
   554  	}
   555  	if spr >= po {
   556  		if !f(spr, t.size-size, func(g func(Val, int) bool) bool {
   557  			return t.eachFrom(func(v Val, j int) bool {
   558  				return g(v, spr)
   559  			}, spo)
   560  		}) {
   561  			return
   562  		}
   563  	}
   564  	if n.po == spr {
   565  		n.eachBin(val, pof, po, f)
   566  	}
   567  
   568  }
   569  
   570  //
   571  //
   572  //
   573  func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
   574  	return t.eachNeighbour(val, pof, f)
   575  }
   576  
   577  func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
   578  	if t == nil || t.size == 0 {
   579  		return false
   580  	}
   581  	var next bool
   582  	l := len(t.bins)
   583  	var n *Pot
   584  	ir := l
   585  	il := l
   586  	po, eq := pof(t.pin, val, t.po)
   587  	if !eq {
   588  		n, il = t.getPos(po)
   589  		if n != nil {
   590  			next = n.eachNeighbour(val, pof, f)
   591  			if !next {
   592  				return false
   593  			}
   594  			ir = il
   595  		} else {
   596  			ir = il - 1
   597  		}
   598  	}
   599  
   600  	next = f(t.pin, po)
   601  	if !next {
   602  		return false
   603  	}
   604  
   605  	for i := l - 1; i > ir; i-- {
   606  		next = t.bins[i].each(func(v Val, _ int) bool {
   607  			return f(v, po)
   608  		})
   609  		if !next {
   610  			return false
   611  		}
   612  	}
   613  
   614  	for i := il - 1; i >= 0; i-- {
   615  		n := t.bins[i]
   616  		next = n.each(func(v Val, _ int) bool {
   617  			return f(v, n.po)
   618  		})
   619  		if !next {
   620  			return false
   621  		}
   622  	}
   623  	return true
   624  }
   625  
   626  //
   627  //
   628  //
   629  //
   630  //
   631  //
   632  //
   633  //
   634  //
   635  //
   636  //
   637  func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) {
   638  	if max > t.size {
   639  		max = t.size
   640  	}
   641  	var wg *sync.WaitGroup
   642  	if wait {
   643  		wg = &sync.WaitGroup{}
   644  	}
   645  	t.eachNeighbourAsync(val, pof, max, maxPos, f, wg)
   646  	if wait {
   647  		wg.Wait()
   648  	}
   649  }
   650  
   651  func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) {
   652  	l := len(t.bins)
   653  
   654  	po, eq := pof(t.pin, val, t.po)
   655  
   656  //
   657  	pom := po
   658  	if pom > maxPos {
   659  		pom = maxPos
   660  	}
   661  	n, il := t.getPos(pom)
   662  	ir := il
   663  //
   664  	if pom == po {
   665  		if n != nil {
   666  
   667  			m := n.size
   668  			if max < m {
   669  				m = max
   670  			}
   671  			max -= m
   672  
   673  			extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg)
   674  
   675  		} else {
   676  			if !eq {
   677  				ir--
   678  			}
   679  		}
   680  	} else {
   681  		extra++
   682  		max--
   683  		if n != nil {
   684  			il++
   685  		}
   686  //
   687  //
   688  		for i := l - 1; i >= il; i-- {
   689  			s := t.bins[i]
   690  			m := s.size
   691  			if max < m {
   692  				m = max
   693  			}
   694  			max -= m
   695  			extra += m
   696  		}
   697  	}
   698  
   699  	var m int
   700  	if pom == po {
   701  
   702  		m, max, extra = need(1, max, extra)
   703  		if m <= 0 {
   704  			return
   705  		}
   706  
   707  		if wg != nil {
   708  			wg.Add(1)
   709  		}
   710  		go func() {
   711  			if wg != nil {
   712  				defer wg.Done()
   713  			}
   714  			f(t.pin, po)
   715  		}()
   716  
   717  //
   718  		for i := l - 1; i > ir; i-- {
   719  			n := t.bins[i]
   720  
   721  			m, max, extra = need(n.size, max, extra)
   722  			if m <= 0 {
   723  				return
   724  			}
   725  
   726  			if wg != nil {
   727  				wg.Add(m)
   728  			}
   729  			go func(pn *Pot, pm int) {
   730  				pn.each(func(v Val, _ int) bool {
   731  					if wg != nil {
   732  						defer wg.Done()
   733  					}
   734  					f(v, po)
   735  					pm--
   736  					return pm > 0
   737  				})
   738  			}(n, m)
   739  
   740  		}
   741  	}
   742  
   743  //
   744  	for i := il - 1; i >= 0; i-- {
   745  		n := t.bins[i]
   746  //
   747  //
   748  		m, max, extra = need(n.size, max, extra)
   749  		if m <= 0 {
   750  			return
   751  		}
   752  
   753  		if wg != nil {
   754  			wg.Add(m)
   755  		}
   756  		go func(pn *Pot, pm int) {
   757  			pn.each(func(v Val, _ int) bool {
   758  				if wg != nil {
   759  					defer wg.Done()
   760  				}
   761  				f(v, pn.po)
   762  				pm--
   763  				return pm > 0
   764  			})
   765  		}(n, m)
   766  
   767  	}
   768  	return max + extra
   769  }
   770  
   771  //
   772  //
   773  //
   774  func (t *Pot) getPos(po int) (n *Pot, i int) {
   775  	for i, n = range t.bins {
   776  		if po > n.po {
   777  			continue
   778  		}
   779  		if po < n.po {
   780  			return nil, i
   781  		}
   782  		return n, i
   783  	}
   784  	return nil, len(t.bins)
   785  }
   786  
   787  //
   788  //
   789  func need(m, max, extra int) (int, int, int) {
   790  	if m <= extra {
   791  		return m, max, extra - m
   792  	}
   793  	max += extra - m
   794  	if max <= 0 {
   795  		return m + max, 0, 0
   796  	}
   797  	return m, max, 0
   798  }
   799  
   800  func (t *Pot) String() string {
   801  	return t.sstring("")
   802  }
   803  
   804  func (t *Pot) sstring(indent string) string {
   805  	if t == nil {
   806  		return "<nil>"
   807  	}
   808  	var s string
   809  	indent += "  "
   810  	s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size)
   811  	for _, n := range t.bins {
   812  		s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent))
   813  	}
   814  	return s
   815  }