func BuildTop(cacheReader CacheReader) (*Reader, []byte, error) {
	var maxHeight uint
	for height := range cacheReader.Layers() {
		if height > maxHeight {
			maxHeight = height
		}
	}
	subtreeWriter := NewWriter(
		func(layerHeight uint) bool {
			return cacheReader.GetCachingPolicy()(maxHeight + layerHeight)
		},
		func(layerHeight uint) (LayerReadWriter, error) {
			return cacheReader.GetLayerFactory()(maxHeight + layerHeight)
		})
	subtree, err := merkle.NewTreeBuilder().
		WithHashFunc(cacheReader.GetHashFunc()).
		WithCacheWriter(subtreeWriter).
		Build()
	if err != nil {
		return nil, nil, err
	}
	layer := cacheReader.GetLayerReader(maxHeight)
	for {
		val, err := layer.ReadNext()
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return nil, nil, err
			}
		}
		err = subtree.AddLeaf(val)
		if err != nil {
			return nil, nil, err
		}
	}
	newCache := &cache{
		layers:           cacheReader.Layers(),
		hash:             cacheReader.GetHashFunc(),
		shouldCacheLayer: cacheReader.GetCachingPolicy(),
		generateLayer:    cacheReader.GetLayerFactory(),
	}
	for height, layer := range subtreeWriter.layers {
		if height == 0 {
			continue
		}
		newCache.layers[height+maxHeight] = layer
	}
	err = newCache.validateStructure()
	if err != nil {
		return nil, nil, err
	}
	return &Reader{cache: newCache}, subtree.Root(), nil
}
BuildTop builds the top layers of a cache, and returns
its new version in addition to its root.
package cache
import (
	"errors"
	"github.com/spacemeshos/merkle-tree"
	"io"
)
func Merge(caches []CacheReader) (*Reader, error) {
	if len(caches) < 2 {
		return nil, errors.New("number of caches must be at least 2")
	}
	layerGroups := make(map[uint][]LayerReadWriter)
	for _, cache := range caches {
		for height, layer := range cache.Layers() {
			layerGroups[height] = append(layerGroups[height], layer)
		}
	}
	layers := make(map[uint]LayerReadWriter)
	for height, layerGroup := range layerGroups {
		if len(layerGroup) != len(caches) {
			return nil, errors.New("number of layers per height mismatch")
		}
		layer, err := Group(layerGroup)
		if err != nil {
			return nil, err
		}
		layers[height] = layer
	}
	hashFunc := caches[0].GetHashFunc()
	layerFactory := caches[0].GetLayerFactory()
	cachingPolicy := caches[0].GetCachingPolicy()
	cache := &cache{
		layers:           layers,
		hash:             hashFunc,
		shouldCacheLayer: cachingPolicy,
		generateLayer:    layerFactory,
	}
	return &Reader{cache}, nil
}