// NewStorageProviderRegistry returns a storage.ProviderRegistry that chains
// the provided registry with the common storage providers.
7300
func NewStorageProviderRegistry(reg storage.ProviderRegistry) storage.ProviderRegistry {
	return storage.ChainedProviderRegistry{reg, provider.CommonStorageProviders()}
}
1030936
func NewStorage(base, temporal storage.Storer) Storage {
	st := &basic{
		s:        base,
		temporal: temporal,

		ObjectStorage:    NewObjectStorage(base, temporal),
		ReferenceStorage: NewReferenceStorage(base, temporal),
		IndexStorage:     NewIndexStorage(base, temporal),
		ShallowStorage:   NewShallowStorage(base, temporal),
		ConfigStorage:    NewConfigStorage(base, temporal),
	}

	pw, ok := temporal.(storer.PackfileWriter)
	if ok {
		return &packageWriter{
			basic: st,
			pw:    pw,
		}
	}

	return st
}
1343249
func NewStore(c *s3.S3, sess *session.Session, conf *cloudstorage.Config) (*FS, error) {

	if conf.TmpDir == "" {
		return nil, fmt.Errorf("unable to create cachepath. config.tmpdir=%q", conf.TmpDir)
	}
	err := os.MkdirAll(conf.TmpDir, 0775)
	if err != nil {
		return nil, fmt.Errorf("unable to create cachepath. config.tmpdir=%q err=%v", conf.TmpDir, err)
	}

	uid := uuid.NewUUID().String()
	uid = strings.Replace(uid, "-", "", -1)

	return &FS{
		client:    c,
		sess:      sess,
		bucket:    conf.Bucket,
		cachepath: conf.TmpDir,
		ID:        uid,
		PageSize:  cloudstorage.MaxResults,
	}, nil
}
320065
func RegisterStorageExecutor(name string, ctor types.NewStorageExecutor) {
	storExecsCtorsRWL.Lock()
	defer storExecsCtorsRWL.Unlock()
	storExecsCtors[strings.ToLower(name)] = ctor
}
1176177
func NewStore(c *az.Client, blobClient *az.BlobStorageClient, conf *cloudstorage.Config) (*FS, error) {

	if conf.TmpDir == "" {
		return nil, fmt.Errorf("unable to create cachepath. config.tmpdir=%q", conf.TmpDir)
	}

	err := os.MkdirAll(conf.TmpDir, 0775)
	if err != nil {
		return nil, fmt.Errorf("unable to create cachepath. config.tmpdir=%q err=%v", conf.TmpDir, err)
	}

	uid := uuid.NewUUID().String()
	uid = strings.Replace(uid, "-", "", -1)

	return &FS{
		baseClient: c,
		client:     blobClient,
		bucket:     conf.Bucket,
		cachepath:  conf.TmpDir,
		ID:         uid,
		PageSize:   10000,
	}, nil
}
682398
func BlobDescriptorCacheProvider(blobDescriptorCacheProvider cache.BlobDescriptorCacheProvider) RegistryOption {
	// TODO(aaronl): The duplication of statter across several objects is
	// ugly, and prevents us from using interface types in the registry
	// struct. Ideally, blobStore and blobServer should be lazily
	// initialized, and use the current value of
	// blobDescriptorCacheProvider.
	return func(registry *registry) error {
		if blobDescriptorCacheProvider != nil {
			statter := cache.NewCachedBlobStatter(blobDescriptorCacheProvider, registry.statter)
			registry.blobStore.statter = statter
			registry.blobServer.statter = statter
			registry.blobDescriptorCacheProvider = blobDescriptorCacheProvider
		}
		return nil
	}
}
176012
func NewStore(conf *Config) (Store, error) {

	if conf.Type == "" {
		return nil, fmt.Errorf("Type is required on Config")
	}
	registryMu.RLock()
	st, ok := storeProviders[conf.Type]
	registryMu.RUnlock()
	if !ok {
		return nil, fmt.Errorf("config.Type=%q was not found", conf.Type)
	}

	if conf.PageSize == 0 {
		conf.PageSize = MaxResults
	}

	if conf.TmpDir == "" {
		conf.TmpDir = os.TempDir()
	}
	return st(conf)
}
425136
func (e *Environ) StorageProviderTypes() ([]storage.ProviderType, error) {
	return []storage.ProviderType{ociStorageProviderType}, nil
}
1300108
func NewStorage(ctx context.Context, id StorageBackend, url *URL) (Storage, error) {
	if be, found := storageRegistry[id]; found {
		return be.New(ctx, url)
	}
	return nil, errors.Wrapf(ErrNotFound, "unknown backend: %s", url.String())
}
1178167
func RegisterStorage(id StorageBackend, name string, loader StorageLoader) {
	storageRegistry[id] = loader
	storageNameToBackendMap[name] = id
	storageBackendToNameMap[id] = name
}
121781
func (e *Environ) StorageProvider(t storage.ProviderType) (storage.Provider, error) {
	if t == ociStorageProviderType {
		return &storageProvider{
			env: e,
			api: e.Storage,
		}, nil
	}

	return nil, errors.NotFoundf("storage provider %q", t)
}
299543
func NewRegistry(localID enode.ID, delivery *Delivery, syncChunkStore storage.SyncChunkStore, intervalsStore state.Store, options *RegistryOptions, balance protocols.Balance) *Registry {
	if options == nil {
		options = &RegistryOptions{}
	}
	if options.SyncUpdateDelay <= 0 {
		options.SyncUpdateDelay = 15 * time.Second
	}
	// check if retrieval has been disabled
	retrieval := options.Retrieval != RetrievalDisabled

	quit := make(chan struct{})

	streamer := &Registry{
		addr:           localID,
		skipCheck:      options.SkipCheck,
		serverFuncs:    make(map[string]func(*Peer, string, bool) (Server, error)),
		clientFuncs:    make(map[string]func(*Peer, string, bool) (Client, error)),
		peers:          make(map[enode.ID]*Peer),
		delivery:       delivery,
		intervalsStore: intervalsStore,
		autoRetrieval:  retrieval,
		maxPeerServers: options.MaxPeerServers,
		balance:        balance,
		quit:           quit,
	}

	streamer.setupSpec()

	streamer.api = NewAPI(streamer)
	delivery.getPeer = streamer.getPeer

	// if retrieval is enabled, register the server func, so that retrieve requests will be served (non-light nodes only)
	if options.Retrieval == RetrievalEnabled {
		streamer.RegisterServerFunc(swarmChunkServerStreamName, func(_ *Peer, _ string, live bool) (Server, error) {
			if !live {
				return nil, errors.New("only live retrieval requests supported")
			}
			return NewSwarmChunkServer(delivery.chunkStore), nil
		})
	}

	// if retrieval is not disabled, register the client func (both light nodes and normal nodes can issue retrieve requests)
	if options.Retrieval != RetrievalDisabled {
		streamer.RegisterClientFunc(swarmChunkServerStreamName, func(p *Peer, t string, live bool) (Client, error) {
			return NewSwarmSyncerClient(p, syncChunkStore, NewStream(swarmChunkServerStreamName, t, live))
		})
	}

	// If syncing is not disabled, the syncing functions are registered (both client and server)
	if options.Syncing != SyncingDisabled {
		RegisterSwarmSyncerServer(streamer, syncChunkStore)
		RegisterSwarmSyncerClient(streamer, syncChunkStore)
	}

	// if syncing is set to automatically subscribe to the syncing stream, start the subscription process
	if options.Syncing == SyncingAutoSubscribe {
		// latestIntC function ensures that
		//   - receiving from the in chan is not blocked by processing inside the for loop
		// 	 - the latest int value is delivered to the loop after the processing is done
		// In context of NeighbourhoodDepthC:
		// after the syncing is done updating inside the loop, we do not need to update on the intermediate
		// depth changes, only to the latest one
		latestIntC := func(in <-chan int) <-chan int {
			out := make(chan int, 1)

			go func() {
				defer close(out)

				for {
					select {
					case i, ok := <-in:
						if !ok {
							return
						}
						select {
						case <-out:
						default:
						}
						out <- i
					case <-quit:
						return
					}
				}
			}()

			return out
		}

		kad := streamer.delivery.kad
		// get notification channels from Kademlia before returning
		// from this function to avoid race with Close method and
		// the goroutine created below
		depthC := latestIntC(kad.NeighbourhoodDepthC())
		addressBookSizeC := latestIntC(kad.AddrCountC())

		go func() {
			// wait for kademlia table to be healthy
			// but return if Registry is closed before
			select {
			case <-time.After(options.SyncUpdateDelay):
			case <-quit:
				return
			}

			// initial requests for syncing subscription to peers
			streamer.updateSyncing()

			for depth := range depthC {
				log.Debug("Kademlia neighbourhood depth change", "depth", depth)

				// Prevent too early sync subscriptions by waiting until there are no
				// new peers connecting. Sync streams updating will be done after no
				// peers are connected for at least SyncUpdateDelay period.
				timer := time.NewTimer(options.SyncUpdateDelay)
				// Hard limit to sync update delay, preventing long delays
				// on a very dynamic network
				maxTimer := time.NewTimer(3 * time.Minute)
			loop:
				for {
					select {
					case <-maxTimer.C:
						// force syncing update when a hard timeout is reached
						log.Trace("Sync subscriptions update on hard timeout")
						// request for syncing subscription to new peers
						streamer.updateSyncing()
						break loop
					case <-timer.C:
						// start syncing as no new peers has been added to kademlia
						// for some time
						log.Trace("Sync subscriptions update")
						// request for syncing subscription to new peers
						streamer.updateSyncing()
						break loop
					case size := <-addressBookSizeC:
						log.Trace("Kademlia address book size changed on depth change", "size", size)
						// new peers has been added to kademlia,
						// reset the timer to prevent early sync subscriptions
						if !timer.Stop() {
							<-timer.C
						}
						timer.Reset(options.SyncUpdateDelay)
					case <-quit:
						break loop
					}
				}
				timer.Stop()
				maxTimer.Stop()
			}
		}()
	}

	return streamer
}
740864
func NewSingleProvider(provider secretProvider) *Vangoh {
	vg := New()
	vg.singleProvider = &provider
	return vg
}
642442
func (*environ) StorageProvider(t storage.ProviderType) (storage.Provider, error) {
	return nil, errors.NotFoundf("storage provider %q", t)
}
541965
func NewShallowStorage(base, temporal storer.ShallowStorer) *ShallowStorage {
	return &ShallowStorage{
		ShallowStorer: base,
		temporal:      temporal,
	}
}
650679
func (p Protos) RegisterProvider(rtype string) error {
	req, err := http.NewRequest("POST", p.createURL("provider/"+rtype), bytes.NewBuffer([]byte{}))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")

	_, err = p.makeRequest(req)
	if err != nil {
		return err
	}

	return nil
}
1131794
func (sp *statePersistence) NewStorage() storage.Storage {
	modelUUID := sp.st.ModelUUID()
	// TODO(ericsnow) Copy the session?
	session := sp.st.session
	store := storage.NewStorage(modelUUID, session)
	return store
}