| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | // Copyright 2017 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Package pot see doc.go | 
					
						
							|  |  |  | package pot | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	maxkeylen = 256 | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Pot is the node type (same for root, branching node and leaf) | 
					
						
							|  |  |  | type Pot struct { | 
					
						
							|  |  |  | 	pin  Val | 
					
						
							|  |  |  | 	bins []*Pot | 
					
						
							|  |  |  | 	size int | 
					
						
							|  |  |  | 	po   int | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Val is the element type for Pots | 
					
						
							|  |  |  | type Val interface{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Pof is the proximity order comparison operator function | 
					
						
							|  |  |  | type Pof func(Val, Val, int) (int, bool) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewPot constructor. Requires a value of type Val to pin | 
					
						
							|  |  |  | // and po to point to a span in the Val key | 
					
						
							|  |  |  | // The pinned item counts towards the size | 
					
						
							|  |  |  | func NewPot(v Val, po int) *Pot { | 
					
						
							|  |  |  | 	var size int | 
					
						
							|  |  |  | 	if v != nil { | 
					
						
							|  |  |  | 		size++ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return &Pot{ | 
					
						
							|  |  |  | 		pin:  v, | 
					
						
							|  |  |  | 		po:   po, | 
					
						
							|  |  |  | 		size: size, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Pin returns the pinned element (key) of the Pot | 
					
						
							|  |  |  | func (t *Pot) Pin() Val { | 
					
						
							|  |  |  | 	return t.pin | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Size returns the number of values in the Pot | 
					
						
							|  |  |  | func (t *Pot) Size() int { | 
					
						
							|  |  |  | 	if t == nil { | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return t.size | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Add inserts a new value into the Pot and | 
					
						
							|  |  |  | // returns the proximity order of v and a boolean | 
					
						
							|  |  |  | // indicating if the item was found | 
					
						
							|  |  |  | // Add called on (t, v) returns a new Pot that contains all the elements of t | 
					
						
							|  |  |  | // plus the value v, using the applicative add | 
					
						
							|  |  |  | // the second return value is the proximity order of the inserted element | 
					
						
							|  |  |  | // the third is boolean indicating if the item was found | 
					
						
							|  |  |  | func Add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { | 
					
						
							|  |  |  | 	return add(t, val, pof) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Pot) clone() *Pot { | 
					
						
							|  |  |  | 	return &Pot{ | 
					
						
							|  |  |  | 		pin:  t.pin, | 
					
						
							|  |  |  | 		size: t.size, | 
					
						
							|  |  |  | 		po:   t.po, | 
					
						
							|  |  |  | 		bins: t.bins, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func add(t *Pot, val Val, pof Pof) (*Pot, int, bool) { | 
					
						
							|  |  |  | 	var r *Pot | 
					
						
							|  |  |  | 	if t == nil || t.pin == nil { | 
					
						
							|  |  |  | 		r = t.clone() | 
					
						
							|  |  |  | 		r.pin = val | 
					
						
							|  |  |  | 		r.size++ | 
					
						
							|  |  |  | 		return r, 0, false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	po, found := pof(t.pin, val, t.po) | 
					
						
							|  |  |  | 	if found { | 
					
						
							|  |  |  | 		r = t.clone() | 
					
						
							|  |  |  | 		r.pin = val | 
					
						
							|  |  |  | 		return r, po, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var p *Pot | 
					
						
							|  |  |  | 	var i, j int | 
					
						
							|  |  |  | 	size := t.size | 
					
						
							|  |  |  | 	for i < len(t.bins) { | 
					
						
							|  |  |  | 		n := t.bins[i] | 
					
						
							|  |  |  | 		if n.po == po { | 
					
						
							|  |  |  | 			p, _, found = add(n, val, pof) | 
					
						
							|  |  |  | 			if !found { | 
					
						
							|  |  |  | 				size++ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			j++ | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if n.po > po { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 		j++ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if p == nil { | 
					
						
							|  |  |  | 		size++ | 
					
						
							|  |  |  | 		p = &Pot{ | 
					
						
							|  |  |  | 			pin:  val, | 
					
						
							|  |  |  | 			size: 1, | 
					
						
							|  |  |  | 			po:   po, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bins := append([]*Pot{}, t.bins[:i]...) | 
					
						
							|  |  |  | 	bins = append(bins, p) | 
					
						
							|  |  |  | 	bins = append(bins, t.bins[j:]...) | 
					
						
							|  |  |  | 	r = &Pot{ | 
					
						
							|  |  |  | 		pin:  t.pin, | 
					
						
							|  |  |  | 		size: size, | 
					
						
							|  |  |  | 		po:   t.po, | 
					
						
							|  |  |  | 		bins: bins, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return r, po, found | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-11 23:42:33 +04:00
										 |  |  | // Remove deletes element v from the Pot t and returns three parameters: | 
					
						
							|  |  |  | // 1. new Pot that contains all the elements of t minus the element v; | 
					
						
							|  |  |  | // 2. proximity order of the removed element v; | 
					
						
							|  |  |  | // 3. boolean indicating whether the item was found. | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | func Remove(t *Pot, v Val, pof Pof) (*Pot, int, bool) { | 
					
						
							|  |  |  | 	return remove(t, v, pof) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func remove(t *Pot, val Val, pof Pof) (r *Pot, po int, found bool) { | 
					
						
							|  |  |  | 	size := t.size | 
					
						
							|  |  |  | 	po, found = pof(t.pin, val, t.po) | 
					
						
							|  |  |  | 	if found { | 
					
						
							|  |  |  | 		size-- | 
					
						
							|  |  |  | 		if size == 0 { | 
					
						
							| 
									
										
										
										
											2019-01-11 23:42:33 +04:00
										 |  |  | 			return &Pot{}, po, true | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		i := len(t.bins) - 1 | 
					
						
							|  |  |  | 		last := t.bins[i] | 
					
						
							|  |  |  | 		r = &Pot{ | 
					
						
							|  |  |  | 			pin:  last.pin, | 
					
						
							|  |  |  | 			bins: append(t.bins[:i], last.bins...), | 
					
						
							|  |  |  | 			size: size, | 
					
						
							|  |  |  | 			po:   t.po, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return r, t.po, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var p *Pot | 
					
						
							|  |  |  | 	var i, j int | 
					
						
							|  |  |  | 	for i < len(t.bins) { | 
					
						
							|  |  |  | 		n := t.bins[i] | 
					
						
							|  |  |  | 		if n.po == po { | 
					
						
							|  |  |  | 			p, po, found = remove(n, val, pof) | 
					
						
							|  |  |  | 			if found { | 
					
						
							|  |  |  | 				size-- | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			j++ | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if n.po > po { | 
					
						
							|  |  |  | 			return t, po, false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 		j++ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	bins := t.bins[:i] | 
					
						
							|  |  |  | 	if p != nil && p.pin != nil { | 
					
						
							|  |  |  | 		bins = append(bins, p) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	bins = append(bins, t.bins[j:]...) | 
					
						
							|  |  |  | 	r = &Pot{ | 
					
						
							| 
									
										
										
										
											2019-01-11 23:42:33 +04:00
										 |  |  | 		pin:  t.pin, | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 		size: size, | 
					
						
							|  |  |  | 		po:   t.po, | 
					
						
							|  |  |  | 		bins: bins, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r, po, found | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Swap called on (k, f) looks up the item at k | 
					
						
							|  |  |  | // and applies the function f to the value v at k or to nil if the item is not found | 
					
						
							|  |  |  | // if f(v) returns nil, the element is removed | 
					
						
							|  |  |  | // if f(v) returns v' <> v then v' is inserted into the Pot | 
					
						
							|  |  |  | // if (v) == v the Pot is not changed | 
					
						
							|  |  |  | // it panics if Pof(f(v), k) show that v' and v are not key-equal | 
					
						
							|  |  |  | func Swap(t *Pot, k Val, pof Pof, f func(v Val) Val) (r *Pot, po int, found bool, change bool) { | 
					
						
							|  |  |  | 	var val Val | 
					
						
							|  |  |  | 	if t.pin == nil { | 
					
						
							|  |  |  | 		val = f(nil) | 
					
						
							|  |  |  | 		if val == nil { | 
					
						
							|  |  |  | 			return nil, 0, false, false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return NewPot(val, t.po), 0, false, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	size := t.size | 
					
						
							|  |  |  | 	po, found = pof(k, t.pin, t.po) | 
					
						
							|  |  |  | 	if found { | 
					
						
							|  |  |  | 		val = f(t.pin) | 
					
						
							|  |  |  | 		// remove element | 
					
						
							|  |  |  | 		if val == nil { | 
					
						
							|  |  |  | 			size-- | 
					
						
							|  |  |  | 			if size == 0 { | 
					
						
							|  |  |  | 				r = &Pot{ | 
					
						
							|  |  |  | 					po: t.po, | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				// return empty pot | 
					
						
							|  |  |  | 				return r, po, true, true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// actually remove pin, by merging last bin | 
					
						
							|  |  |  | 			i := len(t.bins) - 1 | 
					
						
							|  |  |  | 			last := t.bins[i] | 
					
						
							|  |  |  | 			r = &Pot{ | 
					
						
							|  |  |  | 				pin:  last.pin, | 
					
						
							|  |  |  | 				bins: append(t.bins[:i], last.bins...), | 
					
						
							|  |  |  | 				size: size, | 
					
						
							|  |  |  | 				po:   t.po, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return r, po, true, true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// element found but no change | 
					
						
							|  |  |  | 		if val == t.pin { | 
					
						
							|  |  |  | 			return t, po, true, false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// actually modify the pinned element, but no change in structure | 
					
						
							|  |  |  | 		r = t.clone() | 
					
						
							|  |  |  | 		r.pin = val | 
					
						
							|  |  |  | 		return r, po, true, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// recursive step | 
					
						
							|  |  |  | 	var p *Pot | 
					
						
							|  |  |  | 	n, i := t.getPos(po) | 
					
						
							|  |  |  | 	if n != nil { | 
					
						
							|  |  |  | 		p, po, found, change = Swap(n, k, pof, f) | 
					
						
							|  |  |  | 		// recursive no change | 
					
						
							|  |  |  | 		if !change { | 
					
						
							|  |  |  | 			return t, po, found, false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// recursive change | 
					
						
							|  |  |  | 		bins := append([]*Pot{}, t.bins[:i]...) | 
					
						
							|  |  |  | 		if p.size == 0 { | 
					
						
							|  |  |  | 			size-- | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			size += p.size - n.size | 
					
						
							|  |  |  | 			bins = append(bins, p) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		i++ | 
					
						
							|  |  |  | 		if i < len(t.bins) { | 
					
						
							|  |  |  | 			bins = append(bins, t.bins[i:]...) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		r = t.clone() | 
					
						
							|  |  |  | 		r.bins = bins | 
					
						
							|  |  |  | 		r.size = size | 
					
						
							|  |  |  | 		return r, po, found, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// key does not exist | 
					
						
							|  |  |  | 	val = f(nil) | 
					
						
							|  |  |  | 	if val == nil { | 
					
						
							|  |  |  | 		// and it should not be created | 
					
						
							|  |  |  | 		return t, po, false, false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// otherwise check val if equal to k | 
					
						
							|  |  |  | 	if _, eq := pof(val, k, po); !eq { | 
					
						
							|  |  |  | 		panic("invalid value") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	/// | 
					
						
							|  |  |  | 	size++ | 
					
						
							|  |  |  | 	p = &Pot{ | 
					
						
							|  |  |  | 		pin:  val, | 
					
						
							|  |  |  | 		size: 1, | 
					
						
							|  |  |  | 		po:   po, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bins := append([]*Pot{}, t.bins[:i]...) | 
					
						
							|  |  |  | 	bins = append(bins, p) | 
					
						
							|  |  |  | 	if i < len(t.bins) { | 
					
						
							|  |  |  | 		bins = append(bins, t.bins[i:]...) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r = t.clone() | 
					
						
							|  |  |  | 	r.bins = bins | 
					
						
							|  |  |  | 	r.size = size | 
					
						
							|  |  |  | 	return r, po, found, true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Union called on (t0, t1, pof) returns the union of t0 and t1 | 
					
						
							|  |  |  | // calculates the union using the applicative union | 
					
						
							|  |  |  | // the second return value is the number of common elements | 
					
						
							|  |  |  | func Union(t0, t1 *Pot, pof Pof) (*Pot, int) { | 
					
						
							|  |  |  | 	return union(t0, t1, pof) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func union(t0, t1 *Pot, pof Pof) (*Pot, int) { | 
					
						
							|  |  |  | 	if t0 == nil || t0.size == 0 { | 
					
						
							|  |  |  | 		return t1, 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if t1 == nil || t1.size == 0 { | 
					
						
							|  |  |  | 		return t0, 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var pin Val | 
					
						
							|  |  |  | 	var bins []*Pot | 
					
						
							|  |  |  | 	var mis []int | 
					
						
							|  |  |  | 	wg := &sync.WaitGroup{} | 
					
						
							|  |  |  | 	wg.Add(1) | 
					
						
							|  |  |  | 	pin0 := t0.pin | 
					
						
							|  |  |  | 	pin1 := t1.pin | 
					
						
							|  |  |  | 	bins0 := t0.bins | 
					
						
							|  |  |  | 	bins1 := t1.bins | 
					
						
							|  |  |  | 	var i0, i1 int | 
					
						
							|  |  |  | 	var common int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	po, eq := pof(pin0, pin1, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		l0 := len(bins0) | 
					
						
							|  |  |  | 		l1 := len(bins1) | 
					
						
							|  |  |  | 		var n0, n1 *Pot | 
					
						
							|  |  |  | 		var p0, p1 int | 
					
						
							|  |  |  | 		var a0, a1 bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !a0 && i0 < l0 && bins0[i0] != nil && bins0[i0].po <= po { | 
					
						
							|  |  |  | 				n0 = bins0[i0] | 
					
						
							|  |  |  | 				p0 = n0.po | 
					
						
							|  |  |  | 				a0 = p0 == po | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				a0 = true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !a1 && i1 < l1 && bins1[i1] != nil && bins1[i1].po <= po { | 
					
						
							|  |  |  | 				n1 = bins1[i1] | 
					
						
							|  |  |  | 				p1 = n1.po | 
					
						
							|  |  |  | 				a1 = p1 == po | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				a1 = true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if a0 && a1 { | 
					
						
							|  |  |  | 				break | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			switch { | 
					
						
							|  |  |  | 			case (p0 < p1 || a1) && !a0: | 
					
						
							|  |  |  | 				bins = append(bins, n0) | 
					
						
							|  |  |  | 				i0++ | 
					
						
							|  |  |  | 				n0 = nil | 
					
						
							|  |  |  | 			case (p1 < p0 || a0) && !a1: | 
					
						
							|  |  |  | 				bins = append(bins, n1) | 
					
						
							|  |  |  | 				i1++ | 
					
						
							|  |  |  | 				n1 = nil | 
					
						
							|  |  |  | 			case p1 < po: | 
					
						
							|  |  |  | 				bl := len(bins) | 
					
						
							|  |  |  | 				bins = append(bins, nil) | 
					
						
							|  |  |  | 				ml := len(mis) | 
					
						
							|  |  |  | 				mis = append(mis, 0) | 
					
						
							|  |  |  | 				// wg.Add(1) | 
					
						
							|  |  |  | 				// go func(b, m int, m0, m1 *Pot) { | 
					
						
							|  |  |  | 				// 	defer wg.Done() | 
					
						
							|  |  |  | 				// bins[b], mis[m] = union(m0, m1, pof) | 
					
						
							|  |  |  | 				// }(bl, ml, n0, n1) | 
					
						
							|  |  |  | 				bins[bl], mis[ml] = union(n0, n1, pof) | 
					
						
							|  |  |  | 				i0++ | 
					
						
							|  |  |  | 				i1++ | 
					
						
							|  |  |  | 				n0 = nil | 
					
						
							|  |  |  | 				n1 = nil | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if eq { | 
					
						
							|  |  |  | 			common++ | 
					
						
							|  |  |  | 			pin = pin1 | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		i := i0 | 
					
						
							|  |  |  | 		if len(bins0) > i && bins0[i].po == po { | 
					
						
							|  |  |  | 			i++ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var size0 int | 
					
						
							|  |  |  | 		for _, n := range bins0[i:] { | 
					
						
							|  |  |  | 			size0 += n.size | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		np := &Pot{ | 
					
						
							|  |  |  | 			pin:  pin0, | 
					
						
							|  |  |  | 			bins: bins0[i:], | 
					
						
							|  |  |  | 			size: size0 + 1, | 
					
						
							|  |  |  | 			po:   po, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		bins2 := []*Pot{np} | 
					
						
							|  |  |  | 		if n0 == nil { | 
					
						
							|  |  |  | 			pin0 = pin1 | 
					
						
							|  |  |  | 			po = maxkeylen + 1 | 
					
						
							|  |  |  | 			eq = true | 
					
						
							|  |  |  | 			common-- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			bins2 = append(bins2, n0.bins...) | 
					
						
							|  |  |  | 			pin0 = pin1 | 
					
						
							|  |  |  | 			pin1 = n0.pin | 
					
						
							|  |  |  | 			po, eq = pof(pin0, pin1, n0.po) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		bins0 = bins1 | 
					
						
							|  |  |  | 		bins1 = bins2 | 
					
						
							|  |  |  | 		i0 = i1 | 
					
						
							|  |  |  | 		i1 = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wg.Done() | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | 	for _, c := range mis { | 
					
						
							|  |  |  | 		common += c | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	n := &Pot{ | 
					
						
							|  |  |  | 		pin:  pin, | 
					
						
							|  |  |  | 		bins: bins, | 
					
						
							|  |  |  | 		size: t0.size + t1.size - common, | 
					
						
							|  |  |  | 		po:   t0.po, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return n, common | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | // Each is a synchronous iterator over the elements of pot with function f. | 
					
						
							|  |  |  | func (t *Pot) Each(f func(Val) bool) bool { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	return t.each(f) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | // each is a synchronous iterator over the elements of pot with function f. | 
					
						
							|  |  |  | // the iteration ends if the function return false or there are no more elements. | 
					
						
							|  |  |  | func (t *Pot) each(f func(Val) bool) bool { | 
					
						
							|  |  |  | 	if t == nil || t.size == 0 { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	for _, n := range t.bins { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 		if !n.each(f) { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 	return f(t.pin) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | // eachFrom is a synchronous iterator over the elements of pot with function f, | 
					
						
							|  |  |  | // starting from certain proximity order po, which is passed as a second parameter. | 
					
						
							|  |  |  | // the iteration ends if the function return false or there are no more elements. | 
					
						
							|  |  |  | func (t *Pot) eachFrom(f func(Val) bool, po int) bool { | 
					
						
							|  |  |  | 	if t == nil || t.size == 0 { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, beg := t.getPos(po) | 
					
						
							|  |  |  | 	for i := beg; i < len(t.bins); i++ { | 
					
						
							|  |  |  | 		if !t.bins[i].each(f) { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 	return f(t.pin) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // EachBin iterates over bins of the pivot node and offers iterators to the caller on each | 
					
						
							|  |  |  | // subtree passing the proximity order and the size | 
					
						
							|  |  |  | // the iteration continues until the function's return value is false | 
					
						
							|  |  |  | // or there are no more subtries | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | func (t *Pot) EachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	t.eachBin(val, pof, po, f) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | func (t *Pot) eachBin(val Val, pof Pof, po int, f func(int, int, func(func(val Val) bool) bool) bool) { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 	if t == nil || t.size == 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	spr, _ := pof(t.pin, val, t.po) | 
					
						
							|  |  |  | 	_, lim := t.getPos(spr) | 
					
						
							|  |  |  | 	var size int | 
					
						
							|  |  |  | 	var n *Pot | 
					
						
							|  |  |  | 	for i := 0; i < lim; i++ { | 
					
						
							|  |  |  | 		n = t.bins[i] | 
					
						
							|  |  |  | 		size += n.size | 
					
						
							|  |  |  | 		if n.po < po { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if !f(n.po, n.size, n.each) { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if lim == len(t.bins) { | 
					
						
							|  |  |  | 		if spr >= po { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 			f(spr, 1, func(g func(Val) bool) bool { | 
					
						
							|  |  |  | 				return g(t.pin) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	n = t.bins[lim] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	spo := spr | 
					
						
							|  |  |  | 	if n.po == spr { | 
					
						
							|  |  |  | 		spo++ | 
					
						
							|  |  |  | 		size += n.size | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if spr >= po { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 		if !f(spr, t.size-size, func(g func(Val) bool) bool { | 
					
						
							|  |  |  | 			return t.eachFrom(func(v Val) bool { | 
					
						
							|  |  |  | 				return g(v) | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			}, spo) | 
					
						
							|  |  |  | 		}) { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if n.po == spr { | 
					
						
							|  |  |  | 		n.eachBin(val, pof, po, f) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // EachNeighbour is a synchronous iterator over neighbours of any target val | 
					
						
							|  |  |  | // the order of elements retrieved reflect proximity order to the target | 
					
						
							|  |  |  | // TODO: add maximum proxbin to start range of iteration | 
					
						
							|  |  |  | func (t *Pot) EachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { | 
					
						
							|  |  |  | 	return t.eachNeighbour(val, pof, f) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Pot) eachNeighbour(val Val, pof Pof, f func(Val, int) bool) bool { | 
					
						
							|  |  |  | 	if t == nil || t.size == 0 { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var next bool | 
					
						
							|  |  |  | 	l := len(t.bins) | 
					
						
							|  |  |  | 	var n *Pot | 
					
						
							|  |  |  | 	ir := l | 
					
						
							|  |  |  | 	il := l | 
					
						
							|  |  |  | 	po, eq := pof(t.pin, val, t.po) | 
					
						
							|  |  |  | 	if !eq { | 
					
						
							|  |  |  | 		n, il = t.getPos(po) | 
					
						
							|  |  |  | 		if n != nil { | 
					
						
							|  |  |  | 			next = n.eachNeighbour(val, pof, f) | 
					
						
							|  |  |  | 			if !next { | 
					
						
							|  |  |  | 				return false | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ir = il | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			ir = il - 1 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	next = f(t.pin, po) | 
					
						
							|  |  |  | 	if !next { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := l - 1; i > ir; i-- { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 		next = t.bins[i].each(func(v Val) bool { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			return f(v, po) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		if !next { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := il - 1; i >= 0; i-- { | 
					
						
							|  |  |  | 		n := t.bins[i] | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 		next = n.each(func(v Val) bool { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 			return f(v, n.po) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		if !next { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // EachNeighbourAsync called on (val, max, maxPos, f, wait) is an asynchronous iterator | 
					
						
							|  |  |  | // over elements not closer than maxPos wrt val. | 
					
						
							|  |  |  | // val does not need to be match an element of the Pot, but if it does, and | 
					
						
							|  |  |  | // maxPos is keylength than it is included in the iteration | 
					
						
							|  |  |  | // Calls to f are parallelised, the order of calls is undefined. | 
					
						
							|  |  |  | // proximity order is respected in that there is no element in the Pot that | 
					
						
							|  |  |  | // is not visited if a closer node is visited. | 
					
						
							|  |  |  | // The iteration is finished when max number of nearest nodes is visited | 
					
						
							|  |  |  | // or if the entire there are no nodes not closer than maxPos that is not visited | 
					
						
							|  |  |  | // if wait is true, the iterator returns only if all calls to f are finished | 
					
						
							|  |  |  | // TODO: implement minPos for proper prox range iteration | 
					
						
							|  |  |  | func (t *Pot) EachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wait bool) { | 
					
						
							|  |  |  | 	if max > t.size { | 
					
						
							|  |  |  | 		max = t.size | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var wg *sync.WaitGroup | 
					
						
							|  |  |  | 	if wait { | 
					
						
							|  |  |  | 		wg = &sync.WaitGroup{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	t.eachNeighbourAsync(val, pof, max, maxPos, f, wg) | 
					
						
							|  |  |  | 	if wait { | 
					
						
							|  |  |  | 		wg.Wait() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Pot) eachNeighbourAsync(val Val, pof Pof, max int, maxPos int, f func(Val, int), wg *sync.WaitGroup) (extra int) { | 
					
						
							|  |  |  | 	l := len(t.bins) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	po, eq := pof(t.pin, val, t.po) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// if po is too close, set the pivot branch (pom) to maxPos | 
					
						
							|  |  |  | 	pom := po | 
					
						
							|  |  |  | 	if pom > maxPos { | 
					
						
							|  |  |  | 		pom = maxPos | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	n, il := t.getPos(pom) | 
					
						
							|  |  |  | 	ir := il | 
					
						
							|  |  |  | 	// if pivot branch exists and po is not too close, iterate on the pivot branch | 
					
						
							|  |  |  | 	if pom == po { | 
					
						
							|  |  |  | 		if n != nil { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m := n.size | 
					
						
							|  |  |  | 			if max < m { | 
					
						
							|  |  |  | 				m = max | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			max -= m | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			extra = n.eachNeighbourAsync(val, pof, m, maxPos, f, wg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if !eq { | 
					
						
							|  |  |  | 				ir-- | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		extra++ | 
					
						
							|  |  |  | 		max-- | 
					
						
							|  |  |  | 		if n != nil { | 
					
						
							|  |  |  | 			il++ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// before checking max, add up the extra elements | 
					
						
							|  |  |  | 		// on the close branches that are skipped (if po is too close) | 
					
						
							|  |  |  | 		for i := l - 1; i >= il; i-- { | 
					
						
							|  |  |  | 			s := t.bins[i] | 
					
						
							|  |  |  | 			m := s.size | 
					
						
							|  |  |  | 			if max < m { | 
					
						
							|  |  |  | 				m = max | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			max -= m | 
					
						
							|  |  |  | 			extra += m | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var m int | 
					
						
							|  |  |  | 	if pom == po { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		m, max, extra = need(1, max, extra) | 
					
						
							|  |  |  | 		if m <= 0 { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if wg != nil { | 
					
						
							|  |  |  | 			wg.Add(1) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		go func() { | 
					
						
							|  |  |  | 			if wg != nil { | 
					
						
							|  |  |  | 				defer wg.Done() | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			f(t.pin, po) | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// otherwise iterats | 
					
						
							|  |  |  | 		for i := l - 1; i > ir; i-- { | 
					
						
							|  |  |  | 			n := t.bins[i] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			m, max, extra = need(n.size, max, extra) | 
					
						
							|  |  |  | 			if m <= 0 { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if wg != nil { | 
					
						
							|  |  |  | 				wg.Add(m) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			go func(pn *Pot, pm int) { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 				pn.each(func(v Val) bool { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 					if wg != nil { | 
					
						
							|  |  |  | 						defer wg.Done() | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					f(v, po) | 
					
						
							|  |  |  | 					pm-- | 
					
						
							|  |  |  | 					return pm > 0 | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 			}(n, m) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// iterate branches that are farther tham pom with their own po | 
					
						
							|  |  |  | 	for i := il - 1; i >= 0; i-- { | 
					
						
							|  |  |  | 		n := t.bins[i] | 
					
						
							|  |  |  | 		// the first time max is less than the size of the entire branch | 
					
						
							|  |  |  | 		// wait for the pivot thread to release extra elements | 
					
						
							|  |  |  | 		m, max, extra = need(n.size, max, extra) | 
					
						
							|  |  |  | 		if m <= 0 { | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if wg != nil { | 
					
						
							|  |  |  | 			wg.Add(m) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		go func(pn *Pot, pm int) { | 
					
						
							| 
									
										
										
										
											2019-01-15 14:51:33 +04:00
										 |  |  | 			pn.each(func(v Val) bool { | 
					
						
							| 
									
										
										
										
											2018-06-20 14:06:27 +02:00
										 |  |  | 				if wg != nil { | 
					
						
							|  |  |  | 					defer wg.Done() | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				f(v, pn.po) | 
					
						
							|  |  |  | 				pm-- | 
					
						
							|  |  |  | 				return pm > 0 | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}(n, m) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return max + extra | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // getPos called on (n) returns the forking node at PO n and its index if it exists | 
					
						
							|  |  |  | // otherwise nil | 
					
						
							|  |  |  | // caller is supposed to hold the lock | 
					
						
							|  |  |  | func (t *Pot) getPos(po int) (n *Pot, i int) { | 
					
						
							|  |  |  | 	for i, n = range t.bins { | 
					
						
							|  |  |  | 		if po > n.po { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if po < n.po { | 
					
						
							|  |  |  | 			return nil, i | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return n, i | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil, len(t.bins) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // need called on (m, max, extra) uses max m out of extra, and then max | 
					
						
							|  |  |  | // if needed, returns the adjusted counts | 
					
						
							|  |  |  | func need(m, max, extra int) (int, int, int) { | 
					
						
							|  |  |  | 	if m <= extra { | 
					
						
							|  |  |  | 		return m, max, extra - m | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	max += extra - m | 
					
						
							|  |  |  | 	if max <= 0 { | 
					
						
							|  |  |  | 		return m + max, 0, 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return m, max, 0 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Pot) String() string { | 
					
						
							|  |  |  | 	return t.sstring("") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (t *Pot) sstring(indent string) string { | 
					
						
							|  |  |  | 	if t == nil { | 
					
						
							|  |  |  | 		return "<nil>" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var s string | 
					
						
							|  |  |  | 	indent += "  " | 
					
						
							|  |  |  | 	s += fmt.Sprintf("%v%v (%v) %v \n", indent, t.pin, t.po, t.size) | 
					
						
							|  |  |  | 	for _, n := range t.bins { | 
					
						
							|  |  |  | 		s += fmt.Sprintf("%v%v\n", indent, n.sstring(indent)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return s | 
					
						
							|  |  |  | } |