Package memory is a storage backend base on memory
package memory

import (
	
	

	
	
	
	
	
)

var ErrUnsupportedObjectType = fmt.Errorf("unsupported object type")
Storage is an implementation of git.Storer that stores data on memory, being ephemeral. The use of this storage should be done in controlled environments, since the representation in memory of some repository can fill the machine memory. in the other hand this storage has the best performance.
NewStorage returns a new Storage base on memory
func () *Storage {
	return &Storage{
		ReferenceStorage: make(ReferenceStorage),
		ConfigStorage:    ConfigStorage{},
		ShallowStorage:   ShallowStorage{},
		ObjectStorage: ObjectStorage{
			Objects: make(map[plumbing.Hash]plumbing.EncodedObject),
			Commits: make(map[plumbing.Hash]plumbing.EncodedObject),
			Trees:   make(map[plumbing.Hash]plumbing.EncodedObject),
			Blobs:   make(map[plumbing.Hash]plumbing.EncodedObject),
			Tags:    make(map[plumbing.Hash]plumbing.EncodedObject),
		},
		ModuleStorage: make(ModuleStorage),
	}
}

type ConfigStorage struct {
	config *config.Config
}

func ( *ConfigStorage) ( *config.Config) error {
	if  := .Validate();  != nil {
		return 
	}

	.config = 
	return nil
}

func ( *ConfigStorage) () (*config.Config, error) {
	if .config == nil {
		.config = config.NewConfig()
	}

	return .config, nil
}

type IndexStorage struct {
	index *index.Index
}

func ( *IndexStorage) ( *index.Index) error {
	.index = 
	return nil
}

func ( *IndexStorage) () (*index.Index, error) {
	if .index == nil {
		.index = &index.Index{Version: 2}
	}

	return .index, nil
}

type ObjectStorage struct {
	Objects map[plumbing.Hash]plumbing.EncodedObject
	Commits map[plumbing.Hash]plumbing.EncodedObject
	Trees   map[plumbing.Hash]plumbing.EncodedObject
	Blobs   map[plumbing.Hash]plumbing.EncodedObject
	Tags    map[plumbing.Hash]plumbing.EncodedObject
}

func ( *ObjectStorage) () plumbing.EncodedObject {
	return &plumbing.MemoryObject{}
}

func ( *ObjectStorage) ( plumbing.EncodedObject) (plumbing.Hash, error) {
	 := .Hash()
	.Objects[] = 

	switch .Type() {
	case plumbing.CommitObject:
		.Commits[] = .Objects[]
	case plumbing.TreeObject:
		.Trees[] = .Objects[]
	case plumbing.BlobObject:
		.Blobs[] = .Objects[]
	case plumbing.TagObject:
		.Tags[] = .Objects[]
	default:
		return , ErrUnsupportedObjectType
	}

	return , nil
}

func ( *ObjectStorage) ( plumbing.Hash) ( error) {
	if ,  := .Objects[]; ! {
		return plumbing.ErrObjectNotFound
	}
	return nil
}

func ( *ObjectStorage) ( plumbing.Hash) (
	 int64,  error) {
	,  := .Objects[]
	if ! {
		return 0, plumbing.ErrObjectNotFound
	}

	return .Size(), nil
}

func ( *ObjectStorage) ( plumbing.ObjectType,  plumbing.Hash) (plumbing.EncodedObject, error) {
	,  := .Objects[]
	if ! || (plumbing.AnyObject !=  && .Type() != ) {
		return nil, plumbing.ErrObjectNotFound
	}

	return , nil
}

func ( *ObjectStorage) ( plumbing.ObjectType) (storer.EncodedObjectIter, error) {
	var  []plumbing.EncodedObject
	switch  {
	case plumbing.AnyObject:
		 = flattenObjectMap(.Objects)
	case plumbing.CommitObject:
		 = flattenObjectMap(.Commits)
	case plumbing.TreeObject:
		 = flattenObjectMap(.Trees)
	case plumbing.BlobObject:
		 = flattenObjectMap(.Blobs)
	case plumbing.TagObject:
		 = flattenObjectMap(.Tags)
	}

	return storer.NewEncodedObjectSliceIter(), nil
}

func ( map[plumbing.Hash]plumbing.EncodedObject) []plumbing.EncodedObject {
	 := make([]plumbing.EncodedObject, 0, len())
	for ,  := range  {
		 = append(, )
	}
	return 
}

func ( *ObjectStorage) () storer.Transaction {
	return &TxObjectStorage{
		Storage: ,
		Objects: make(map[plumbing.Hash]plumbing.EncodedObject),
	}
}

func ( *ObjectStorage) ( func(plumbing.Hash) error) error {
	for  := range .Objects {
		 := ()
		if  != nil {
			if  == storer.ErrStop {
				return nil
			}
			return 
		}
	}
	return nil
}

func ( *ObjectStorage) () ([]plumbing.Hash, error) {
	return nil, nil
}
func ( *ObjectStorage) (plumbing.Hash, time.Time) error {
	return nil
}

var errNotSupported = fmt.Errorf("Not supported")

func ( *ObjectStorage) ( plumbing.Hash) (time.Time, error) {
	return time.Time{}, errNotSupported
}
func ( *ObjectStorage) (plumbing.Hash) error {
	return errNotSupported
}

type TxObjectStorage struct {
	Storage *ObjectStorage
	Objects map[plumbing.Hash]plumbing.EncodedObject
}

func ( *TxObjectStorage) ( plumbing.EncodedObject) (plumbing.Hash, error) {
	 := .Hash()
	.Objects[] = 

	return , nil
}

func ( *TxObjectStorage) ( plumbing.ObjectType,  plumbing.Hash) (plumbing.EncodedObject, error) {
	,  := .Objects[]
	if ! || (plumbing.AnyObject !=  && .Type() != ) {
		return nil, plumbing.ErrObjectNotFound
	}

	return , nil
}

func ( *TxObjectStorage) () error {
	for ,  := range .Objects {
		delete(.Objects, )
		if ,  := .Storage.SetEncodedObject();  != nil {
			return 
		}
	}

	return nil
}

func ( *TxObjectStorage) () error {
	.Objects = make(map[plumbing.Hash]plumbing.EncodedObject)
	return nil
}

type ReferenceStorage map[plumbing.ReferenceName]*plumbing.Reference

func ( ReferenceStorage) ( *plumbing.Reference) error {
	if  != nil {
		[.Name()] = 
	}

	return nil
}

func ( ReferenceStorage) (,  *plumbing.Reference) error {
	if  == nil {
		return nil
	}

	if  != nil {
		 := [.Name()]
		if  != nil && .Hash() != .Hash() {
			return storage.ErrReferenceHasChanged
		}
	}
	[.Name()] = 
	return nil
}

func ( ReferenceStorage) ( plumbing.ReferenceName) (*plumbing.Reference, error) {
	,  := []
	if ! {
		return nil, plumbing.ErrReferenceNotFound
	}

	return , nil
}

func ( ReferenceStorage) () (storer.ReferenceIter, error) {
	var  []*plumbing.Reference
	for ,  := range  {
		 = append(, )
	}

	return storer.NewReferenceSliceIter(), nil
}

func ( ReferenceStorage) () (int, error) {
	return len(), nil
}

func ( ReferenceStorage) () error {
	return nil
}

func ( ReferenceStorage) ( plumbing.ReferenceName) error {
	delete(, )
	return nil
}

type ShallowStorage []plumbing.Hash

func ( *ShallowStorage) ( []plumbing.Hash) error {
	* = 
	return nil
}

func ( ShallowStorage) () ([]plumbing.Hash, error) {
	return , nil
}

type ModuleStorage map[string]*Storage

func ( ModuleStorage) ( string) (storage.Storer, error) {
	if ,  := [];  {
		return , nil
	}

	 := NewStorage()
	[] = 

	return , nil