func (w *Writer) shardTop(depth uint) (uint, error) {
	switch depth {
	case w.height:
		return w.split, nil
	case w.split:
		return 0, nil
	}
	return 0, fmt.Errorf("unexpected depth %d", depth)
}
shardTop returns the depth of a shard top based on its bottom depth.
package smt
import (
	"context"
	"errors"
	"fmt"
	"github.com/google/trillian/merkle/smt/node"
)
type NodeBatchAccessor interface {
	Get(ctx context.Context, ids []node.ID) (map[node.ID][]byte, error)
	Set(ctx context.Context, nodes []Node) error
}
type Writer struct {
	h      mapHasher
	height uint  
	split  uint  
}
func NewWriter(treeID int64, hasher Hasher, height, split uint) *Writer {
	if split > height {
		panic(fmt.Errorf("NewWriter: split(%d) > height(%d)", split, height))
	}
	return &Writer{h: bindHasher(hasher, treeID), height: height, split: split}
}
func (w *Writer) Split(nodes []Node) ([][]Node, error) {
	if err := Prepare(nodes, w.height); err != nil {
		return nil, err
	}
	var shards [][]Node
	for begin, i := 0, 0; i < len(nodes); i++ {
		pref := nodes[i].ID.Prefix(w.split)
		next := i + 1
		if next == len(nodes) || nodes[next].ID.Prefix(w.split) != pref {
			shards = append(shards, nodes[begin:next])
			begin = next
		}
	}
	return shards, nil
}
func (w *Writer) Write(ctx context.Context, nodes []Node, acc NodeBatchAccessor) (Node, error) {
	if len(nodes) == 0 {
		return Node{}, errors.New("nothing to write")
	}
	depth := nodes[0].ID.BitLen()
	top, err := w.shardTop(depth)
	if err != nil {
		return Node{}, err
	}
	hs, err := NewHStar3(nodes, w.h.mh.HashChildren, depth, top)
	if err != nil {
		return Node{}, err
	}
	hashes, err := acc.Get(ctx, hs.Prepare())
	if err != nil {
		return Node{}, err
	}
	sa := w.newAccessor(hashes)
	topUpd, err := hs.Update(sa)
	if err != nil {
		return Node{}, err
	} else if ln := len(topUpd); ln != 1 {
		return Node{}, fmt.Errorf("writing across %d shards, want 1", ln)
	}
	if err := acc.Set(ctx, sa.writes); err != nil {
		return Node{}, err
	}
	return topUpd[0], nil
}