func (o *orbitDB) GetAccessControllerType(controllerType string) (iface.AccessControllerConstructor, bool) {
	o.muAccessControllerTypes.RLock()
	defer o.muAccessControllerTypes.RUnlock()
	acType, ok := o.accessControllerTypes[controllerType]
	return acType, ok
}
GetAccessControllerType Gets an access controller type
package baseorbitdb
import (
	"context"
	"encoding/json"
	"fmt"
	"path"
	"strings"
	"sync"
	"time"
	ipfslog "berty.tech/go-ipfs-log"
	"berty.tech/go-ipfs-log/enc"
	"berty.tech/go-ipfs-log/entry"
	"berty.tech/go-ipfs-log/identityprovider"
	idp "berty.tech/go-ipfs-log/identityprovider"
	"berty.tech/go-ipfs-log/io"
	"berty.tech/go-ipfs-log/keystore"
	"berty.tech/go-orbit-db/accesscontroller"
	acutils "berty.tech/go-orbit-db/accesscontroller/utils"
	"berty.tech/go-orbit-db/address"
	"berty.tech/go-orbit-db/cache"
	"berty.tech/go-orbit-db/cache/cacheleveldown"
	"berty.tech/go-orbit-db/iface"
	_ "berty.tech/go-orbit-db/internal/buildconstraints"  
	"berty.tech/go-orbit-db/pubsub/oneonone"
	"berty.tech/go-orbit-db/pubsub/pubsubcoreapi"
	"berty.tech/go-orbit-db/stores"
	"berty.tech/go-orbit-db/utils"
	cid "github.com/ipfs/go-cid"
	datastore "github.com/ipfs/go-datastore"
	leveldb "github.com/ipfs/go-ds-leveldb"
	cbornode "github.com/ipfs/go-ipld-cbor"
	coreapi "github.com/ipfs/interface-go-ipfs-core"
	p2pcore "github.com/libp2p/go-libp2p-core"
	"github.com/pkg/errors"
	"go.opentelemetry.io/otel/trace"
	"go.uber.org/zap"
)
type BaseOrbitDB = iface.BaseOrbitDB
type Store = iface.Store
type EventLogStore = iface.EventLogStore
type KeyValueStore = iface.KeyValueStore
type StoreIndex = iface.StoreIndex
type StoreConstructor = iface.StoreConstructor
type IndexConstructor = iface.IndexConstructor
type OnWritePrototype = iface.OnWritePrototype
type StreamOptions = iface.StreamOptions
type CreateDBOptions = iface.CreateDBOptions
type DetermineAddressOptions = iface.DetermineAddressOptions
type DirectChannelFactory = iface.DirectChannelFactory
type exchangedHeads struct {
	Address string         `json:"address,omitempty"`
	Heads   []*entry.Entry `json:"heads,omitempty"`
}
func boolPtr(val bool) *bool {
	return &val
}
type NewOrbitDBOptions struct {
	ID                   *string
	PeerID               *p2pcore.PeerID
	Directory            *string
	Keystore             keystore.Interface
	Cache                cache.Interface
	Identity             *idp.Identity
	CloseKeystore        func() error
	Logger               *zap.Logger
	Tracer               trace.Tracer
	DirectChannelFactory iface.DirectChannelFactory
	PubSub               iface.PubSubInterface
}
type orbitDB struct {
	storeTypes            map[string]iface.StoreConstructor
	accessControllerTypes map[string]iface.AccessControllerConstructor
	ipfs                  coreapi.CoreAPI
	identity              *idp.Identity
	id                    p2pcore.PeerID
	pubsub                iface.PubSubInterface
	keystore              keystore.Interface
	closeKeystore         func() error
	stores                map[string]Store
	directConnections     map[p2pcore.PeerID]iface.DirectChannel
	directConnFactory     iface.DirectChannelFactory
	directory             string
	cache                 cache.Interface
	logger                *zap.Logger
	tracer                trace.Tracer
	muStoreTypes            sync.RWMutex
	muStores                sync.RWMutex
	muIdentity              sync.RWMutex
	muID                    sync.RWMutex
	muIPFS                  sync.RWMutex
	muKeyStore              sync.RWMutex
	muCaches                sync.RWMutex
	muDirectConnections     sync.RWMutex
	muAccessControllerTypes sync.RWMutex
}
func (o *orbitDB) Logger() *zap.Logger {
	return o.logger
}
func (o *orbitDB) Tracer() trace.Tracer {
	return o.tracer
}
func (o *orbitDB) IPFS() coreapi.CoreAPI {
	o.muIPFS.RLock()
	defer o.muIPFS.RUnlock()
	return o.ipfs
}
func (o *orbitDB) Identity() *identityprovider.Identity {
	o.muIdentity.RLock()
	defer o.muIdentity.RUnlock()
	return o.identity
}
func (o *orbitDB) PeerID() p2pcore.PeerID {
	o.muID.RLock()
	defer o.muID.RUnlock()
	return o.id
}
func (o *orbitDB) KeyStore() keystore.Interface {
	o.muKeyStore.RLock()
	defer o.muKeyStore.RUnlock()
	return o.keystore
}
func (o *orbitDB) CloseKeyStore() func() error {
	o.muKeyStore.RLock()
	defer o.muKeyStore.RUnlock()
	return o.closeKeystore
}
func (o *orbitDB) setStore(address string, store iface.Store) {
	o.muStores.Lock()
	defer o.muStores.Unlock()
	o.stores[address] = store
}
func (o *orbitDB) getStore(address string) (iface.Store, bool) {
	o.muStores.RLock()
	defer o.muStores.RUnlock()
	store, ok := o.stores[address]
	return store, ok
}
func (o *orbitDB) deleteStore(address string) {
	o.muStores.Lock()
	defer o.muStores.Unlock()
	delete(o.stores, address)
}
func (o *orbitDB) closeAllStores() {
	o.muStores.Lock()
	defer o.muStores.Unlock()
	for _, store := range o.stores {
		if err := store.Close(); err != nil {
			o.logger.Error("unable to close store", zap.Error(err))
		}
	}
	o.stores = map[string]Store{}
}
func (o *orbitDB) closeCache() {
	o.muCaches.Lock()
	defer o.muCaches.Unlock()
	if err := o.cache.Close(); err != nil {
		o.logger.Error("unable to close cache", zap.Error(err))
	}
}
func (o *orbitDB) closeDirectConnections() {
	o.muDirectConnections.Lock()
	defer o.muDirectConnections.Unlock()
	for _, conn := range o.directConnections {
		if err := conn.Close(); err != nil {
			o.logger.Error("unable to close connection", zap.Error(err))
		}
	}
	o.directConnections = map[p2pcore.PeerID]iface.DirectChannel{}
}
func (o *orbitDB) closeKeyStore() {
	o.muKeyStore.Lock()
	defer o.muKeyStore.Unlock()
	if o.closeKeystore != nil {
		if err := o.closeKeystore(); err != nil {
			o.logger.Error("unable to close key store", zap.Error(err))
		}
	}
}