From d63064b8afb3ca6b842e01d91baa2476feab22c9 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 4 May 2015 15:26:56 -0700 Subject: [PATCH] Optimize memory usage in GetPartialObject() for memory driver --- pkg/storage/drivers/donut/donut.go | 2 +- pkg/storage/drivers/memory/memory.go | 36 +++++++++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/pkg/storage/drivers/donut/donut.go b/pkg/storage/drivers/donut/donut.go index 8f69d99b6..bb9ed1922 100644 --- a/pkg/storage/drivers/donut/donut.go +++ b/pkg/storage/drivers/donut/donut.go @@ -248,13 +248,13 @@ func (d donutDriver) GetPartialObject(w io.Writer, bucketName, objectName string }, errParams) } reader, size, err := d.donut.GetObject(bucketName, objectName) - defer reader.Close() if err != nil { return 0, iodine.New(drivers.ObjectNotFound{ Bucket: bucketName, Object: objectName, }, nil) } + defer reader.Close() if start > size || (start+length-1) > size { return 0, iodine.New(drivers.InvalidRange{ Start: start, diff --git a/pkg/storage/drivers/memory/memory.go b/pkg/storage/drivers/memory/memory.go index 6c6e0b6f6..7100be074 100644 --- a/pkg/storage/drivers/memory/memory.go +++ b/pkg/storage/drivers/memory/memory.go @@ -24,10 +24,10 @@ import ( "encoding/hex" "errors" "io" - "io/ioutil" "log" "runtime/debug" "sort" + "strconv" "strings" "sync" "time" @@ -100,29 +100,43 @@ func (memory *memoryDriver) GetObject(w io.Writer, bucket string, object string) memory.lock.RUnlock() return 0, iodine.New(drivers.ObjectNotFound{Bucket: bucket, Object: object}, nil) } - memory.lock.RUnlock() written, err := io.Copy(w, bytes.NewBuffer(data)) + memory.lock.RUnlock() return written, iodine.New(err, nil) } // GetPartialObject - GET object from memory buffer range func (memory *memoryDriver) GetPartialObject(w io.Writer, bucket, object string, start, length int64) (int64, error) { + errParams := map[string]string{ + "bucket": bucket, + "object": object, + "start": strconv.FormatInt(start, 10), + "length": strconv.FormatInt(length, 10), + } memory.lock.RLock() - defer memory.lock.RUnlock() - var sourceBuffer bytes.Buffer if !drivers.IsValidBucket(bucket) { - return 0, iodine.New(drivers.BucketNameInvalid{Bucket: bucket}, nil) + memory.lock.RUnlock() + return 0, iodine.New(drivers.BucketNameInvalid{Bucket: bucket}, errParams) } if !drivers.IsValidObjectName(object) { - return 0, iodine.New(drivers.ObjectNameInvalid{Object: object}, nil) + memory.lock.RUnlock() + return 0, iodine.New(drivers.ObjectNameInvalid{Object: object}, errParams) } - if _, err := memory.GetObject(&sourceBuffer, bucket, object); err != nil { - return 0, iodine.New(err, nil) + if start < 0 { + return 0, iodine.New(drivers.InvalidRange{ + Start: start, + Length: length, + }, errParams) } - if _, err := io.CopyN(ioutil.Discard, &sourceBuffer, start); err != nil { - return 0, iodine.New(err, nil) + objectKey := bucket + "/" + object + data, ok := memory.objects.Get(objectKey) + if !ok { + memory.lock.RUnlock() + return 0, iodine.New(drivers.ObjectNotFound{Bucket: bucket, Object: object}, errParams) } - return io.CopyN(w, &sourceBuffer, length) + written, err := io.CopyN(w, bytes.NewBuffer(data[start:]), length) + memory.lock.RUnlock() + return written, iodine.New(err, nil) } // GetBucketMetadata -