github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/git/odb/memory_storer.go (about)

     1  package odb
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"sync"
     9  )
    10  
    11  // memoryStorer is an implementation of the storer interface that holds data for
    12  // the object database in memory.
    13  type memoryStorer struct {
    14  	// mu guards reads and writes to the map "fs" below.
    15  	mu *sync.Mutex
    16  	// fs maps a hex-encoded SHA to a bytes.Buffer wrapped in a no-op closer
    17  	// type.
    18  	fs map[string]*bufCloser
    19  }
    20  
    21  // newMemoryStorer initializes a new memoryStorer instance with the given
    22  // initial set.
    23  //
    24  // A value of "nil" is acceptable and indicates that no entries shall be added
    25  // to the memory storer at/during construction time.
    26  func newMemoryStorer(m map[string]io.ReadWriter) *memoryStorer {
    27  	fs := make(map[string]*bufCloser, len(m))
    28  	for n, rw := range m {
    29  		fs[n] = &bufCloser{rw}
    30  	}
    31  
    32  	return &memoryStorer{
    33  		mu: new(sync.Mutex),
    34  		fs: fs,
    35  	}
    36  }
    37  
    38  // Store implements the storer.Store function and copies the data given in "r"
    39  // into an object entry in the memory. If an object given by that SHA "sha" is
    40  // already indexed in the database, Store will panic().
    41  func (ms *memoryStorer) Store(sha []byte, r io.Reader) (n int64, err error) {
    42  	ms.mu.Lock()
    43  	defer ms.mu.Unlock()
    44  
    45  	key := fmt.Sprintf("%x", sha)
    46  
    47  	ms.fs[key] = &bufCloser{new(bytes.Buffer)}
    48  	return io.Copy(ms.fs[key], r)
    49  }
    50  
    51  // Open implements the storer.Open function, and returns a io.ReadWriteCloser
    52  // for the given SHA. If a reader for the given SHA does not exist an error will
    53  // be returned.
    54  func (ms *memoryStorer) Open(sha []byte) (f io.ReadWriteCloser, err error) {
    55  	ms.mu.Lock()
    56  	defer ms.mu.Unlock()
    57  
    58  	key := fmt.Sprintf("%x", sha)
    59  	if _, ok := ms.fs[key]; !ok {
    60  		return nil, os.ErrNotExist
    61  	}
    62  	return ms.fs[key], nil
    63  }
    64  
    65  // bufCloser wraps a type satisfying the io.ReadWriter interface with a no-op
    66  // Close() function, thus implementing the io.ReadWriteCloser composite
    67  // interface.
    68  type bufCloser struct {
    69  	io.ReadWriter
    70  }
    71  
    72  // Close implements io.Closer, and returns nothing.
    73  func (b *bufCloser) Close() error { return nil }