Switch SaveFrom() to Reader/Writer

benchcmp:

    benchmark             old ns/op     new ns/op     delta
    BenchmarkSaveFrom     76159512      74795081      -1.79%

    benchmark             old MB/s     new MB/s     speedup
    BenchmarkSaveFrom     55.07        56.08        1.02x

    benchmark             old allocs     new allocs     delta
    BenchmarkSaveFrom     97             117            +20.62%

    benchmark             old bytes     new bytes     delta
    BenchmarkSaveFrom     433826        40117         -90.75%

    benchmark                       old ns/op       new ns/op       delta
    BenchmarkArchiveDirectory-4     29539886128     29262480891     -0.94%

    benchmark                       old allocs     new allocs     delta
    BenchmarkArchiveDirectory-4     540048         709662         +31.41%

    benchmark                       old bytes     new bytes     delta
    BenchmarkArchiveDirectory-4     404573416     443098816     +9.52%
This commit is contained in:
Alexander Neumann 2015-02-16 22:42:11 +01:00
parent 874b29b91f
commit a5e13f1280

View file

@ -213,69 +213,41 @@ func (s Server) SaveFrom(t backend.Type, id backend.ID, length uint, rd io.Reade
return Blob{}, errors.New("id is nil") return Blob{}, errors.New("id is nil")
} }
// create a new blob
blob := Blob{
ID: id,
Size: uint64(length),
}
var ciphertext []byte
// allocate slice for plaintext
plaintext := GetChunkBuf("ch.Save()")
defer FreeChunkBuf("ch.Save()", plaintext)
// if the data is small enough, use a slice from the pool for the ciphertext
if length <= maxCiphertextSize-ivSize-hmacSize {
ciphertext = GetChunkBuf("ch.Save()")
defer FreeChunkBuf("ch.Save()", ciphertext)
} else {
l := length + ivSize + hmacSize
debug.Log("Server.Save", "create large slice of %d bytes for ciphertext", l)
// use a new slice
ciphertext = make([]byte, l)
}
plaintext = plaintext[:length]
_, err := io.ReadFull(rd, plaintext)
if err != nil {
return Blob{}, err
}
// encrypt blob
n, err := s.Encrypt(ciphertext, plaintext)
if err != nil {
return Blob{}, err
}
ciphertext = ciphertext[:n]
backendBlob, err := s.Create(t) backendBlob, err := s.Create(t)
if err != nil { if err != nil {
return Blob{}, err return Blob{}, err
} }
_, err = backendBlob.Write(ciphertext) encWr := s.key.EncryptTo(backendBlob)
_, err = io.Copy(encWr, rd)
if err != nil { if err != nil {
return Blob{}, err return Blob{}, err
} }
// finish encryption
err = encWr.Close()
if err != nil {
return Blob{}, fmt.Errorf("EncryptedWriter.Close(): %v", err)
}
// finish backend blob
err = backendBlob.Close() err = backendBlob.Close()
if err != nil { if err != nil {
return Blob{}, err return Blob{}, fmt.Errorf("backend.Blob.Close(): %v", err)
} }
sid, err := backendBlob.ID() storageID, err := backendBlob.ID()
if err != nil { if err != nil {
return Blob{}, err return Blob{}, fmt.Errorf("backend.Blob.ID(): %v", err)
} }
blob.Storage = sid return Blob{
blob.StorageSize = uint64(len(ciphertext)) ID: id,
Size: uint64(length),
return blob, nil Storage: storageID,
StorageSize: uint64(backendBlob.Size()),
}, nil
} }
var zWriterPool = sync.Pool{ var zWriterPool = sync.Pool{