bmt: golint updates for this or self warning (#16628)

* bmt/*: golint updates for this or self warning

* Update bmt.go
This commit is contained in:
kiel barry 2018-05-10 03:36:01 -07:00 committed by Péter Szilágyi
parent fcc18f4c80
commit 784aa83942

View File

@ -150,29 +150,29 @@ func NewTreePool(hasher BaseHasher, segmentCount, capacity int) *TreePool {
}
// Drain drains the pool until it has no more than n resources
func (self *TreePool) Drain(n int) {
self.lock.Lock()
defer self.lock.Unlock()
for len(self.c) > n {
<-self.c
self.count--
func (p *TreePool) Drain(n int) {
p.lock.Lock()
defer p.lock.Unlock()
for len(p.c) > n {
<-p.c
p.count--
}
}
// Reserve is blocking until it returns an available Tree
// it reuses free Trees or creates a new one if size is not reached
func (self *TreePool) Reserve() *Tree {
self.lock.Lock()
defer self.lock.Unlock()
func (p *TreePool) Reserve() *Tree {
p.lock.Lock()
defer p.lock.Unlock()
var t *Tree
if self.count == self.Capacity {
return <-self.c
if p.count == p.Capacity {
return <-p.c
}
select {
case t = <-self.c:
case t = <-p.c:
default:
t = NewTree(self.hasher, self.SegmentSize, self.SegmentCount)
self.count++
t = NewTree(p.hasher, p.SegmentSize, p.SegmentCount)
p.count++
}
return t
}
@ -180,8 +180,8 @@ func (self *TreePool) Reserve() *Tree {
// Release gives back a Tree to the pool.
// This Tree is guaranteed to be in reusable state
// does not need locking
func (self *TreePool) Release(t *Tree) {
self.c <- t // can never fail but...
func (p *TreePool) Release(t *Tree) {
p.c <- t // can never fail but...
}
// Tree is a reusable control structure representing a BMT
@ -193,17 +193,17 @@ type Tree struct {
}
// Draw draws the BMT (badly)
func (self *Tree) Draw(hash []byte, d int) string {
func (t *Tree) Draw(hash []byte, d int) string {
var left, right []string
var anc []*Node
for i, n := range self.leaves {
for i, n := range t.leaves {
left = append(left, fmt.Sprintf("%v", hashstr(n.left)))
if i%2 == 0 {
anc = append(anc, n.parent)
}
right = append(right, fmt.Sprintf("%v", hashstr(n.right)))
}
anc = self.leaves
anc = t.leaves
var hashes [][]string
for l := 0; len(anc) > 0; l++ {
var nodes []*Node
@ -277,42 +277,42 @@ func NewTree(hasher BaseHasher, segmentSize, segmentCount int) *Tree {
// methods needed by hash.Hash
// Size returns the size
func (self *Hasher) Size() int {
return self.size
func (h *Hasher) Size() int {
return h.size
}
// BlockSize returns the block size
func (self *Hasher) BlockSize() int {
return self.blocksize
func (h *Hasher) BlockSize() int {
return h.blocksize
}
// Sum returns the hash of the buffer
// hash.Hash interface Sum method appends the byte slice to the underlying
// data before it calculates and returns the hash of the chunk
func (self *Hasher) Sum(b []byte) (r []byte) {
t := self.bmt
i := self.cur
func (h *Hasher) Sum(b []byte) (r []byte) {
t := h.bmt
i := h.cur
n := t.leaves[i]
j := i
// must run strictly before all nodes calculate
// datanodes are guaranteed to have a parent
if len(self.segment) > self.size && i > 0 && n.parent != nil {
if len(h.segment) > h.size && i > 0 && n.parent != nil {
n = n.parent
} else {
i *= 2
}
d := self.finalise(n, i)
self.writeSegment(j, self.segment, d)
c := <-self.result
self.releaseTree()
d := h.finalise(n, i)
h.writeSegment(j, h.segment, d)
c := <-h.result
h.releaseTree()
// sha3(length + BMT(pure_chunk))
if self.blockLength == nil {
if h.blockLength == nil {
return c
}
res := self.pool.hasher()
res := h.pool.hasher()
res.Reset()
res.Write(self.blockLength)
res.Write(h.blockLength)
res.Write(c)
return res.Sum(nil)
}
@ -321,8 +321,8 @@ func (self *Hasher) Sum(b []byte) (r []byte) {
// Hash waits for the hasher result and returns it
// caller must call this on a BMT Hasher being written to
func (self *Hasher) Hash() []byte {
return <-self.result
func (h *Hasher) Hash() []byte {
return <-h.result
}
// Hasher implements the io.Writer interface
@ -330,16 +330,16 @@ func (self *Hasher) Hash() []byte {
// Write fills the buffer to hash
// with every full segment complete launches a hasher go routine
// that shoots up the BMT
func (self *Hasher) Write(b []byte) (int, error) {
func (h *Hasher) Write(b []byte) (int, error) {
l := len(b)
if l <= 0 {
return 0, nil
}
s := self.segment
i := self.cur
count := (self.count + 1) / 2
need := self.count*self.size - self.cur*2*self.size
size := self.size
s := h.segment
i := h.cur
count := (h.count + 1) / 2
need := h.count*h.size - h.cur*2*h.size
size := h.size
if need > size {
size *= 2
}
@ -356,7 +356,7 @@ func (self *Hasher) Write(b []byte) (int, error) {
// read full segments and the last possibly partial segment
for need > 0 && i < count-1 {
// push all finished chunks we read
self.writeSegment(i, s, self.depth)
h.writeSegment(i, s, h.depth)
need -= size
if need < 0 {
size += need
@ -365,8 +365,8 @@ func (self *Hasher) Write(b []byte) (int, error) {
rest += size
i++
}
self.segment = s
self.cur = i
h.segment = s
h.cur = i
// otherwise, we can assume len(s) == 0, so all buffer is read and chunk is not yet full
return l, nil
}
@ -376,8 +376,8 @@ func (self *Hasher) Write(b []byte) (int, error) {
// ReadFrom reads from io.Reader and appends to the data to hash using Write
// it reads so that chunk to hash is maximum length or reader reaches EOF
// caller must Reset the hasher prior to call
func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
bufsize := self.size*self.count - self.size*self.cur - len(self.segment)
func (h *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
bufsize := h.size*h.count - h.size*h.cur - len(h.segment)
buf := make([]byte, bufsize)
var read int
for {
@ -385,7 +385,7 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
n, err = r.Read(buf)
read += n
if err == io.EOF || read == len(buf) {
hash := self.Sum(buf[:n])
hash := h.Sum(buf[:n])
if read == len(buf) {
err = NewEOC(hash)
}
@ -394,7 +394,7 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
if err != nil {
break
}
n, err = self.Write(buf[:n])
n, err = h.Write(buf[:n])
if err != nil {
break
}
@ -403,9 +403,9 @@ func (self *Hasher) ReadFrom(r io.Reader) (m int64, err error) {
}
// Reset needs to be called before writing to the hasher
func (self *Hasher) Reset() {
self.getTree()
self.blockLength = nil
func (h *Hasher) Reset() {
h.getTree()
h.blockLength = nil
}
// Hasher implements the SwarmHash interface
@ -413,52 +413,52 @@ func (self *Hasher) Reset() {
// ResetWithLength needs to be called before writing to the hasher
// the argument is supposed to be the byte slice binary representation of
// the length of the data subsumed under the hash
func (self *Hasher) ResetWithLength(l []byte) {
self.Reset()
self.blockLength = l
func (h *Hasher) ResetWithLength(l []byte) {
h.Reset()
h.blockLength = l
}
// Release gives back the Tree to the pool whereby it unlocks
// it resets tree, segment and index
func (self *Hasher) releaseTree() {
if self.bmt != nil {
n := self.bmt.leaves[self.cur]
func (h *Hasher) releaseTree() {
if h.bmt != nil {
n := h.bmt.leaves[h.cur]
for ; n != nil; n = n.parent {
n.unbalanced = false
if n.parent != nil {
n.root = false
}
}
self.pool.Release(self.bmt)
self.bmt = nil
h.pool.Release(h.bmt)
h.bmt = nil
}
self.cur = 0
self.segment = nil
h.cur = 0
h.segment = nil
}
func (self *Hasher) writeSegment(i int, s []byte, d int) {
h := self.pool.hasher()
n := self.bmt.leaves[i]
func (h *Hasher) writeSegment(i int, s []byte, d int) {
hash := h.pool.hasher()
n := h.bmt.leaves[i]
if len(s) > self.size && n.parent != nil {
if len(s) > h.size && n.parent != nil {
go func() {
h.Reset()
h.Write(s)
s = h.Sum(nil)
hash.Reset()
hash.Write(s)
s = hash.Sum(nil)
if n.root {
self.result <- s
h.result <- s
return
}
self.run(n.parent, h, d, n.index, s)
h.run(n.parent, hash, d, n.index, s)
}()
return
}
go self.run(n, h, d, i*2, s)
go h.run(n, hash, d, i*2, s)
}
func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
func (h *Hasher) run(n *Node, hash hash.Hash, d int, i int, s []byte) {
isLeft := i%2 == 0
for {
if isLeft {
@ -470,18 +470,18 @@ func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
return
}
if !n.unbalanced || !isLeft || i == 0 && d == 0 {
h.Reset()
h.Write(n.left)
h.Write(n.right)
s = h.Sum(nil)
hash.Reset()
hash.Write(n.left)
hash.Write(n.right)
s = hash.Sum(nil)
} else {
s = append(n.left, n.right...)
}
self.hash = s
h.hash = s
if n.root {
self.result <- s
h.result <- s
return
}
@ -492,20 +492,20 @@ func (self *Hasher) run(n *Node, h hash.Hash, d int, i int, s []byte) {
}
// getTree obtains a BMT resource by reserving one from the pool
func (self *Hasher) getTree() *Tree {
if self.bmt != nil {
return self.bmt
func (h *Hasher) getTree() *Tree {
if h.bmt != nil {
return h.bmt
}
t := self.pool.Reserve()
self.bmt = t
t := h.pool.Reserve()
h.bmt = t
return t
}
// atomic bool toggle implementing a concurrent reusable 2-state object
// atomic addint with %2 implements atomic bool toggle
// it returns true if the toggler just put it in the active/waiting state
func (self *Node) toggle() bool {
return atomic.AddInt32(&self.state, 1)%2 == 1
func (n *Node) toggle() bool {
return atomic.AddInt32(&n.state, 1)%2 == 1
}
func hashstr(b []byte) string {
@ -525,7 +525,7 @@ func depth(n int) (d int) {
// finalise is following the zigzags on the tree belonging
// to the final datasegment
func (self *Hasher) finalise(n *Node, i int) (d int) {
func (h *Hasher) finalise(n *Node, i int) (d int) {
isLeft := i%2 == 0
for {
// when the final segment's path is going via left segments
@ -550,8 +550,8 @@ type EOC struct {
}
// Error returns the error string
func (self *EOC) Error() string {
return fmt.Sprintf("hasher limit reached, chunk hash: %x", self.Hash)
func (e *EOC) Error() string {
return fmt.Sprintf("hasher limit reached, chunk hash: %x", e.Hash)
}
// NewEOC creates new end of chunk error with the hash