github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:44</date>
    10  //</624450116220096512>
    11  
    12  
    13  //包装罐见Go医生
    14  package pot
    15  
    16  import (
    17  	"fmt"
    18  	"sync"
    19  )
    20  
    21  const (
    22  	maxkeylen = 256
    23  )
    24  
    25  //pot是节点类型(根、分支节点和叶相同)
    26  type Pot struct {
    27  	pin  Val
    28  	bins []*Pot
    29  	size int
    30  	po   int
    31  }
    32  
    33  //VAL是锅的元件类型
    34  type Val interface{}
    35  
    36  //pof是邻近订单比较运算符函数
    37  type Pof func(Val, Val, int) (int, bool)
    38  
    39  //Newpot构造函数。需要VAL类型的值才能固定
    40  //和po指向val键中的跨度
    41  //钉住的项目按大小计算
    42  func NewPot(v Val, po int) *Pot {
    43  	var size int
    44  	if v != nil {
    45  		size++
    46  	}
    47  	return &Pot{
    48  		pin:  v,
    49  		po:   po,
    50  		size: size,
    51  	}
    52  }
    53  
    54  //pin返回pot的pinned元素(键)
    55  func (t *Pot) Pin() Val {
    56  	return t.pin
    57  }
    58  
    59  //SIZE返回pot中的值数
    60  func (t *Pot) Size() int {
    61  	if t == nil {
    62  		return 0
    63  	}
    64  	return t.size
    65  }
    66  
    67  //添加将新值插入到容器中,然后
    68  //返回v和布尔值的接近顺序
    69  //指示是否找到该项
    70  //add called on(t,v)返回包含t的所有元素的新pot
    71  //加上V值,使用应用加法
    72  //第二个返回值是插入元素的接近顺序。
    73  //第三个是布尔值,指示是否找到该项
    74  func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) {
    75  	return add(t, val, pof)
    76  }
    77  
    78  func (t *Pot) clone() *Pot {
    79  	return &Pot{
    80  		pin:  t.pin,
    81  		size: t.size,
    82  		po:   t.po,
    83  		bins: t.bins,
    84  	}
    85  }
    86  
    87  func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) {
    88  	var r *Pot
    89  	if t == nil || t.pin == nil {
    90  		r = t.clone()
    91  		r.pin = val
    92  		r.size++
    93  		return r, 0, false
    94  	}
    95  	po, found := pof(t.pin, val, t.po)
    96  	if found {
    97  		r = t.clone()
    98  		r.pin = val
    99  		return r, po, true
   100  	}
   101  
   102  	var p *Pot
   103  	var i, j int
   104  	size := t.size
   105  	for i < len(t.bins) {
   106  		n := t.bins[i]
   107  		if n.po == po {
   108  			p, _, found = add(n, val, pof)
   109  			if !found {
   110  				size++
   111  			}
   112  			j++
   113  			break
   114  		}
   115  		if n.po > po {
   116  			break
   117  		}
   118  		i++
   119  		j++
   120  	}
   121  	if p == nil {
   122  		size++
   123  		p = &Pot{
   124  			pin:  val,
   125  			size: 1,
   126  			po:   po,
   127  		}
   128  	}
   129  
   130  	bins := append([]*Pot{}, t.bins[:i]...)
   131  	bins = append(bins, p)
   132  	bins = append(bins, t.bins[j:]...)
   133  	r = &Pot{
   134  		pin:  t.pin,
   135  		size: size,
   136  		po:   t.po,
   137  		bins: bins,
   138  	}
   139  
   140  	return r, po, found
   141  }
   142  
   143  //remove从pot t t中删除元素v并返回三个参数:
   144  //1。新锅,包含所有元素t减去元素v;
   145  //2。拆除元件V的接近顺序;
   146  //三。指示是否找到该项的布尔值。
   147  func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) {
   148  	return remove(t, v, pof)
   149  }
   150  
   151  func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) {
   152  	size := t.size
   153  	po, found = pof(t.pin, val, t.po)
   154  	if found {
   155  		size--
   156  		if size == 0 {
   157  			return &Pot{}, po, true
   158  		}
   159  		i := len(t.bins) - 1
   160  		last := t.bins[i]
   161  		r = &Pot{
   162  			pin:  last.pin,
   163  			bins: append(t.bins[:i], last.bins...),
   164  			size: size,
   165  			po:   t.po,
   166  		}
   167  		return r, t.po, true
   168  	}
   169  
   170  	var p *Pot
   171  	var i, j int
   172  	for i < len(t.bins) {
   173  		n := t.bins[i]
   174  		if n.po == po {
   175  			p, po, found = remove(n, val, pof)
   176  			if found {
   177  				size--
   178  			}
   179  			j++
   180  			break
   181  		}
   182  		if n.po > po {
   183  			return t, po, false
   184  		}
   185  		i++
   186  		j++
   187  	}
   188  	bins := t.bins[:i]
   189  	if p != nil && p.pin != nil {
   190  		bins = append(bins, p)
   191  	}
   192  	bins = append(bins, t.bins[j:]...)
   193  	r = &Pot{
   194  		pin:  t.pin,
   195  		size: size,
   196  		po:   t.po,
   197  		bins: bins,
   198  	}
   199  	return r, po, found
   200  }
   201  
   202  //调用的swap(k,f)在k处查找项
   203  //
   204  //如果f(v)返回nil,则删除元素
   205  //如果f(v)返回v'<>v,则v'插入锅中。
   206  //如果(v)==v,则罐不更换。
   207  //如果pof(f(v),k)显示v'和v不是键相等,则会恐慌。
   208  func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) {
   209  	var val Val
   210  	if t.pin == nil {
   211  		val = f(nil)
   212  		if val == nil {
   213  			return nil, 0, false, false
   214  		}
   215  		return NewPot(val, t.po), 0, false, true
   216  	}
   217  	size := t.size
   218  	po, found = pof(k, t.pin, t.po)
   219  	if found {
   220  		val = f(t.pin)
   221  //移除元素
   222  		if val == nil {
   223  			size--
   224  			if size == 0 {
   225  				r = &Pot{
   226  					po: t.po,
   227  				}
   228  //返回空罐
   229  				return r, po, true, true
   230  			}
   231  //实际上,通过合并最后一个bin来删除pin
   232  			i := len(t.bins) - 1
   233  			last := t.bins[i]
   234  			r = &Pot{
   235  				pin:  last.pin,
   236  				bins: append(t.bins[:i], last.bins...),
   237  				size: size,
   238  				po:   t.po,
   239  			}
   240  			return r, po, true, true
   241  		}
   242  //找到元素,但没有更改
   243  		if val == t.pin {
   244  			return t, po, true, false
   245  		}
   246  //实际修改固定元素,但结构没有更改
   247  		r = t.clone()
   248  		r.pin = val
   249  		return r, po, true, true
   250  	}
   251  
   252  //递归阶段
   253  	var p *Pot
   254  	n, i := t.getPos(po)
   255  	if n != nil {
   256  		p, po, found, change = Swap(n, k, pof, f)
   257  //递归无更改
   258  		if !change {
   259  			return t, po, found, false
   260  		}
   261  //递归更改
   262  		bins := append([]*Pot{}, t.bins[:i]...)
   263  		if p.size == 0 {
   264  			size--
   265  		} else {
   266  			size += p.size - n.size
   267  			bins = append(bins, p)
   268  		}
   269  		i++
   270  		if i < len(t.bins) {
   271  			bins = append(bins, t.bins[i:]...)
   272  		}
   273  		r = t.clone()
   274  		r.bins = bins
   275  		r.size = size
   276  		return r, po, found, true
   277  	}
   278  //密钥不存在
   279  	val = f(nil)
   280  	if val == nil {
   281  //它不应该被创建
   282  		return t, po, false, false
   283  	}
   284  //否则,如果等于k,则检查val
   285  	if _, eq := pof(val, k, po); !eq {
   286  		panic("invalid value")
   287  	}
   288  ///
   289  	size++
   290  	p = &Pot{
   291  		pin:  val,
   292  		size: 1,
   293  		po:   po,
   294  	}
   295  
   296  	bins := append([]*Pot{}, t.bins[:i]...)
   297  	bins = append(bins, p)
   298  	if i < len(t.bins) {
   299  		bins = append(bins, t.bins[i:]...)
   300  	}
   301  	r = t.clone()
   302  	r.bins = bins
   303  	r.size = size
   304  	return r, po, found, true
   305  }
   306  
   307  //在(t0,t1,pof)上调用的union返回t0和t1的union
   308  //使用应用联合计算联合
   309  //第二个返回值是公共元素的数目
   310  func Union(t0, t1 *Pot, pof Pof) (*Pot, int) {
   311  	return union(t0, t1, pof)
   312  }
   313  
   314  func union(t0, t1 *Pot, pof Pof) (*Pot, int) {
   315  	if t0 == nil || t0.size == 0 {
   316  		return t1, 0
   317  	}
   318  	if t1 == nil || t1.size == 0 {
   319  		return t0, 0
   320  	}
   321  	var pin Val
   322  	var bins []*Pot
   323  	var mis []int
   324  	wg := &sync.WaitGroup{}
   325  	wg.Add(1)
   326  	pin0 := t0.pin
   327  	pin1 := t1.pin
   328  	bins0 := t0.bins
   329  	bins1 := t1.bins
   330  	var i0, i1 int
   331  	var common int
   332  
   333  	po, eq := pof(pin0, pin1, 0)
   334  
   335  	for {
   336  		l0 := len(bins0)
   337  		l1 := len(bins1)
   338  		var n0, n1 *Pot
   339  		var p0, p1 int
   340  		var a0, a1 bool
   341  
   342  		for {
   343  
   344  			if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po {
   345  				n0 = bins0[i0]
   346  				p0 = n0.po
   347  				a0 = p0 == po
   348  			} else {
   349  				a0 = true
   350  			}
   351  
   352  			if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po {
   353  				n1 = bins1[i1]
   354  				p1 = n1.po
   355  				a1 = p1 == po
   356  			} else {
   357  				a1 = true
   358  			}
   359  			if a0 && a1 {
   360  				break
   361  			}
   362  
   363  			switch {
   364  			case (p0 < p1 || a1) && !a0:
   365  				bins = append(bins, n0)
   366  				i0++
   367  				n0 = nil
   368  			case (p1 < p0 || a0) && !a1:
   369  				bins = append(bins, n1)
   370  				i1++
   371  				n1 = nil
   372  			case p1 < po:
   373  				bl := len(bins)
   374  				bins = append(bins, nil)
   375  				ml := len(mis)
   376  				mis = append(mis, 0)
   377  //添加(1)
   378  //go func(b,m int,m0,m1*pot)
   379  //推迟WG.DONE()
   380  //箱[B],MIS[M]=联管节(M0、M1、POF)
   381  //(bl,ml,n0,n1)
   382  				bins[bl], mis[ml] = union(n0, n1, pof)
   383  				i0++
   384  				i1++
   385  				n0 = nil
   386  				n1 = nil
   387  			}
   388  		}
   389  
   390  		if eq {
   391  			common++
   392  			pin = pin1
   393  			break
   394  		}
   395  
   396  		i := i0
   397  		if len(bins0) > i && bins0[i].po == po {
   398  			i++
   399  		}
   400  		var size0 int
   401  		for _, n := range bins0[i:] {
   402  			size0 += n.size
   403  		}
   404  		np := &Pot{
   405  			pin:  pin0,
   406  			bins: bins0[i:],
   407  			size: size0 + 1,
   408  			po:   po,
   409  		}
   410  
   411  		bins2 := []*Pot{np}
   412  		if n0 == nil {
   413  			pin0 = pin1
   414  			po = maxkeylen + 1
   415  			eq = true
   416  			common--
   417  
   418  		} else {
   419  			bins2 = append(bins2, n0.bins...)
   420  			pin0 = pin1
   421  			pin1 = n0.pin
   422  			po, eq = pof(pin0, pin1, n0.po)
   423  
   424  		}
   425  		bins0 = bins1
   426  		bins1 = bins2
   427  		i0 = i1
   428  		i1 = 0
   429  
   430  	}
   431  
   432  	wg.Done()
   433  	wg.Wait()
   434  	for _, c := range mis {
   435  		common += c
   436  	}
   437  	n := &Pot{
   438  		pin:  pin,
   439  		bins: bins,
   440  		size: t0.size + t1.size - common,
   441  		po:   t0.po,
   442  	}
   443  	return n, common
   444  }
   445  
   446  //每个函数都是pot元素上的同步迭代器,函数为f。
   447  func (t *Pot) Each(f func(Val) bool) bool {
   448  	return t.each(f)
   449  }
   450  
   451  //每个函数都是pot元素上的同步迭代器,函数为f。
   452  //如果函数返回false或没有其他元素,则迭代将结束。
   453  func (t *Pot) each(f func(Val) bool) bool {
   454  	if t == nil || t.size == 0 {
   455  		return false
   456  	}
   457  	for _, n := range t.bins {
   458  		if !n.each(f) {
   459  			return false
   460  		}
   461  	}
   462  	return f(t.pin)
   463  }
   464  
   465  //eachFrom是对pot元素的同步迭代器,函数为f,
   466  //从某个邻近订单po开始,作为第二个参数传递。
   467  //如果函数返回false或没有其他元素,则迭代将结束。
   468  func (t *Pot) eachFrom(f func(Val) bool, po int) bool {
   469  	if t == nil || t.size == 0 {
   470  		return false
   471  	}
   472  	_, beg := t.getPos(po)
   473  	for i := beg; i < len(t.bins); i++ {
   474  		if !t.bins[i].each(f) {
   475  			return false
   476  		}
   477  	}
   478  	return f(t.pin)
   479  }
   480  
   481  //eachbin在pivot节点的bin上迭代,并在每个pivot节点上向调用者提供迭代器。
   482  //传递接近顺序和大小的子树
   483  //迭代将继续,直到函数的返回值为假
   484  //或者没有其他子项
   485  func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) {
   486  	t.eachBin(val, pof, po, f)
   487  }
   488  
   489  func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) {
   490  	if t == nil || t.size == 0 {
   491  		return
   492  	}
   493  	spr, _ := pof(t.pin, val, t.po)
   494  	_, lim := t.getPos(spr)
   495  	var size int
   496  	var n *Pot
   497  	for i := 0; i < lim; i++ {
   498  		n = t.bins[i]
   499  		size += n.size
   500  		if n.po < po {
   501  			continue
   502  		}
   503  		if !f(n.po, n.size, n.each) {
   504  			return
   505  		}
   506  	}
   507  	if lim == len(t.bins) {
   508  		if spr >= po {
   509  			f(spr, 1, func(g func(Val) bool) bool {
   510  				return g(t.pin)
   511  			})
   512  		}
   513  		return
   514  	}
   515  
   516  	n = t.bins[lim]
   517  
   518  	spo := spr
   519  	if n.po == spr {
   520  		spo++
   521  		size += n.size
   522  	}
   523  	if spr >= po {
   524  		if !f(spr, t.size-size, func(g func(Val) bool) bool {
   525  			return t.eachFrom(func(v Val) bool {
   526  				return g(v)
   527  			}, spo)
   528  		}) {
   529  			return
   530  		}
   531  	}
   532  	if n.po == spr {
   533  		n.eachBin(val, pof, po, f)
   534  	}
   535  
   536  }
   537  
   538  //eachneighbur是任何目标val的邻居上的同步迭代器。
   539  //元素的检索顺序反映了目标的接近顺序。
   540  //TODO:将最大proxybin添加到迭代的开始范围
   541  func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
   542  	return t.eachNeighbour(val, pof, f)
   543  }
   544  
   545  func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool {
   546  	if t == nil || t.size == 0 {
   547  		return false
   548  	}
   549  	var next bool
   550  	l := len(t.bins)
   551  	var n *Pot
   552  	ir := l
   553  	il := l
   554  	po, eq := pof(t.pin, val, t.po)
   555  	if !eq {
   556  		n, il = t.getPos(po)
   557  		if n != nil {
   558  			next = n.eachNeighbour(val, pof, f)
   559  			if !next {
   560  				return false
   561  			}
   562  			ir = il
   563  		} else {
   564  			ir = il - 1
   565  		}
   566  	}
   567  
   568  	next = f(t.pin, po)
   569  	if !next {
   570  		return false
   571  	}
   572  
   573  	for i := l - 1; i > ir; i-- {
   574  		next = t.bins[i].each(func(v Val) bool {
   575  			return f(v, po)
   576  		})
   577  		if !next {
   578  			return false
   579  		}
   580  	}
   581  
   582  	for i := il - 1; i >= 0; i-- {
   583  		n := t.bins[i]
   584  		next = n.each(func(v Val) bool {
   585  			return f(v, n.po)
   586  		})
   587  		if !next {
   588  			return false
   589  		}
   590  	}
   591  	return true
   592  }
   593  
   594  //调用的eachneighbourasync(val、max、maxpos、f、wait)是异步迭代器
   595  //在不小于maxpos wrt val的元素上。
   596  //val不需要与pot元素匹配,但如果匹配,并且
   597  //maxpos是keylength,而不是包含在迭代中的keylength
   598  //对f的调用是并行的,调用顺序未定义。
   599  //在锅中没有元素
   600  //如果访问了更近的节点,则不会访问。
   601  //当访问最大最近节点数时,迭代完成。
   602  //或者,如果整个系统中没有不比未访问的maxpos更近的节点
   603  //如果wait为true,则仅当对f的所有调用都完成时,迭代器才返回
   604  //TODO:为正确的代理范围迭代实现minpos
   605  func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) {
   606  	if max > t.size {
   607  		max = t.size
   608  	}
   609  	var wg *sync.WaitGroup
   610  	if wait {
   611  		wg = &sync.WaitGroup{}
   612  	}
   613  	t.eachNeighbourAsync(val, pof, max, maxPos, f, wg)
   614  	if wait {
   615  		wg.Wait()
   616  	}
   617  }
   618  
   619  func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) {
   620  	l := len(t.bins)
   621  
   622  	po, eq := pof(t.pin, val, t.po)
   623  
   624  //如果po太近,将pivot branch(pom)设置为maxpos
   625  	pom := po
   626  	if pom > maxPos {
   627  		pom = maxPos
   628  	}
   629  	n, il := t.getPos(pom)
   630  	ir := il
   631  //如果透视分支存在且采购订单不太接近,则迭代透视分支
   632  	if pom == po {
   633  		if n != nil {
   634  
   635  			m := n.size
   636  			if max < m {
   637  				m = max
   638  			}
   639  			max -= m
   640  
   641  			extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg)
   642  
   643  		} else {
   644  			if !eq {
   645  				ir--
   646  			}
   647  		}
   648  	} else {
   649  		extra++
   650  		max--
   651  		if n != nil {
   652  			il++
   653  		}
   654  //在检查max之前,将额外的元素相加
   655  //在被跳过的关闭分支上(如果采购订单太近)
   656  		for i := l - 1; i >= il; i-- {
   657  			s := t.bins[i]
   658  			m := s.size
   659  			if max < m {
   660  				m = max
   661  			}
   662  			max -= m
   663  			extra += m
   664  		}
   665  	}
   666  
   667  	var m int
   668  	if pom == po {
   669  
   670  		m, max, extra = need(1, max, extra)
   671  		if m <= 0 {
   672  			return
   673  		}
   674  
   675  		if wg != nil {
   676  			wg.Add(1)
   677  		}
   678  		go func() {
   679  			if wg != nil {
   680  				defer wg.Done()
   681  			}
   682  			f(t.pin, po)
   683  		}()
   684  
   685  //否则迭代
   686  		for i := l - 1; i > ir; i-- {
   687  			n := t.bins[i]
   688  
   689  			m, max, extra = need(n.size, max, extra)
   690  			if m <= 0 {
   691  				return
   692  			}
   693  
   694  			if wg != nil {
   695  				wg.Add(m)
   696  			}
   697  			go func(pn *Pot, pm int) {
   698  				pn.each(func(v Val) bool {
   699  					if wg != nil {
   700  						defer wg.Done()
   701  					}
   702  					f(v, po)
   703  					pm--
   704  					return pm > 0
   705  				})
   706  			}(n, m)
   707  
   708  		}
   709  	}
   710  
   711  //使用自己的po迭代更远的tham pom分支
   712  	for i := il - 1; i >= 0; i-- {
   713  		n := t.bins[i]
   714  //第一次max小于整个分支的大小
   715  //等待轴线程释放额外的元素
   716  		m, max, extra = need(n.size, max, extra)
   717  		if m <= 0 {
   718  			return
   719  		}
   720  
   721  		if wg != nil {
   722  			wg.Add(m)
   723  		}
   724  		go func(pn *Pot, pm int) {
   725  			pn.each(func(v Val) bool {
   726  				if wg != nil {
   727  					defer wg.Done()
   728  				}
   729  				f(v, pn.po)
   730  				pm--
   731  				return pm > 0
   732  			})
   733  		}(n, m)
   734  
   735  	}
   736  	return max + extra
   737  }
   738  
   739  //getpos called on(n)返回po n处的分叉节点及其索引(如果存在)
   740  //否则零
   741  //打电话的人应该锁着
   742  func (t *Pot) getPos(po int) (n *Pot, i int) {
   743  	for i, n = range t.bins {
   744  		if po > n.po {
   745  			continue
   746  		}
   747  		if po < n.po {
   748  			return nil, i
   749  		}
   750  		return n, i
   751  	}
   752  	return nil, len(t.bins)
   753  }
   754  
   755  //需要调用(m,max,extra)使用max m out extra,然后使用max
   756  //如果需要,返回调整后的计数
   757  func need(m, max, extra int) (int, int, int) {
   758  	if m <= extra {
   759  		return m, max, extra - m
   760  	}
   761  	max += extra - m
   762  	if max <= 0 {
   763  		return m + max, 0, 0
   764  	}
   765  	return m, max, 0
   766  }
   767  
   768  func (t *Pot) String() string {
   769  	return t.sstring("")
   770  }
   771  
   772  func (t *Pot) sstring(indent string) string {
   773  	if t == nil {
   774  		return "<nil>"
   775  	}
   776  	var s string
   777  	indent += "  "
   778  	s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size)
   779  	for _, n := range t.bins {
   780  		s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent))
   781  	}
   782  	return s
   783  }
   784