func Fuzz(data []byte) int {
	var impls []string
	for impl := range openers {
		impls = append(impls, impl)
	}
	defaultLoc, _ := ioutil.TempDir("", "fuzz-*")
	if len(impls) == 0 {
		fmt.Fprintf(os.Stderr, "No datastores to fuzz.\n")
		return -1
	} else if len(impls) == 1 {
		return FuzzDB(impls[0], defaultLoc, true, data)
	} else {
		impl := impls[int(data[0])%len(impls)]
		return FuzzDB(impl, defaultLoc, true, data[1:])
	}
}
Fuzz is a go-fuzzer compatible input point for replaying
data (interpreted as a script of commands)
to known ipfs datastore implementations
package fuzzer
import (
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"sync"
	"sync/atomic"
	ds "github.com/ipfs/go-datastore"
	dsq "github.com/ipfs/go-datastore/query"
)
var openers map[string]func(string) ds.Datastore
func AddOpener(name string, opener func(loc string) ds.Datastore) {
	if openers == nil {
		openers = make(map[string]func(string) ds.Datastore)
	}
	openers[name] = opener
}
var Threads int
func init() {
	if openers == nil {
		openers = make(map[string]func(string) ds.Datastore)
	}
	Threads = 1
}
type RunState struct {
	inst ds.Datastore
	opMax         op
	inputChannels []chan<- byte
	wg            sync.WaitGroup
	Cancel        context.CancelFunc
	keyCache   [128]ds.Key
	cachedKeys int32
	ctr        int32  
}
func (r *RunState) DB() ds.Datastore {
	return r.inst
}
func (r *RunState) TxnDB() ds.TxnDatastore {
	if txdb, ok := r.inst.(ds.TxnDatastore); ok {
		return txdb
	}
	return nil
}
type threadState struct {
	op
	keyReady bool
	key      ds.Key
	valReady bool
	val      []byte
	reader   ds.Read
	writer   ds.Write
	txn      ds.Txn
	*RunState
}
func Open(driver string, location string, cleanup bool) (*RunState, error) {
	ctx, cncl := context.WithCancel(context.Background())
	opener, ok := openers[driver]
	if !ok {
		cncl()
		return nil, fmt.Errorf("no such driver: %s", driver)
	}
	state := RunState{}
	state.inst = opener(location)
	state.opMax = opMax
	if state.TxnDB() == nil {
		state.opMax = opNewTX
	}
	state.keyCache[0] = ds.NewKey("/")
	state.cachedKeys = 1
	state.wg.Add(Threads)
	doneCh := make(chan struct{})
	state.Cancel = func() {
		for i := 0; i < Threads; i++ {
			close(state.inputChannels[i])
		}
		cncl()
		<-doneCh
	}
	go func() {
		state.wg.Wait()
		state.inst.Close()
		if cleanup {
			os.RemoveAll(location)
		}
		close(doneCh)
	}()
	state.inputChannels = make([]chan<- byte, Threads)
	for i := 0; i < Threads; i++ {
		dr := make(chan byte, 15)
		go threadDriver(ctx, &state, dr)
		state.inputChannels[i] = dr
	}
	return &state, nil
}