code: func (sw *AsyncHasher) Sum(b []byte, length int, meta []byte) (s []byte) {
  	sw.mtx.Lock()
  	t := sw.getTree()
  	if length == 0 {
  		sw.mtx.Unlock()
  		s = sw.pool.zerohashes[sw.pool.Depth]
  	} else {
  		// for non-zero input the rightmost section is written to the tree asynchronously
  		// if the actual last section has been written (t.cursor == length/t.secsize)
  		maxsec := (length - 1) / sw.secsize
  		if t.offset > 0 {
  			go sw.write(t.cursor, t.section, maxsec == t.cursor)
  		}
  		// set cursor to maxsec so final section is written when it arrives
  		t.cursor = maxsec
  		t.offset = length
  		result := t.result
  		sw.mtx.Unlock()
  		// wait for the result or reset
  		s = <-result
  	}
  	// relesase the tree back to the pool
  	sw.releaseTree()
  	// if no meta is given just append digest to b
  	if len(meta) == 0 {
  		return append(b, s...)
  	}
  	// hash together meta and BMT root hash using the pools
  	return doSum(sw.pool.hasher(), b, meta, s)
  }
docs: // Sum can be called any time once the length and the span is known
  // potentially even before all segments have been written
  // in such cases Sum will block until all segments are present and
  // the hash for the length can be calculated.
  //
  // b: digest is appended to b
  // length: known length of the input (unsafe; undefined if out of range)
  // meta: metadata to hash together with BMT root for the final digest
  //   e.g., span for protection against existential forgery