|
|
@ -17,7 +17,6 @@ |
|
|
|
package donut |
|
|
|
package donut |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"bufio" |
|
|
|
|
|
|
|
"bytes" |
|
|
|
"bytes" |
|
|
|
"crypto/md5" |
|
|
|
"crypto/md5" |
|
|
|
"encoding/base64" |
|
|
|
"encoding/base64" |
|
|
@ -419,63 +418,47 @@ func (cache Cache) CreateBucket(bucketName, acl string) error { |
|
|
|
return nil |
|
|
|
return nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func delimiter(object, delimiter string) string { |
|
|
|
func (cache Cache) filterDelimiterPrefix(keys []string, key, prefix, delim string) ([]string, []string) { |
|
|
|
readBuffer := bytes.NewBufferString(object) |
|
|
|
var commonPrefixes []string |
|
|
|
reader := bufio.NewReader(readBuffer) |
|
|
|
|
|
|
|
stringReader := strings.NewReader(delimiter) |
|
|
|
|
|
|
|
delimited, _ := stringReader.ReadByte() |
|
|
|
|
|
|
|
delimitedStr, _ := reader.ReadString(delimited) |
|
|
|
|
|
|
|
return delimitedStr |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func appendUniq(slice []string, i string) []string { |
|
|
|
|
|
|
|
for _, ele := range slice { |
|
|
|
|
|
|
|
if ele == i { |
|
|
|
|
|
|
|
return slice |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return append(slice, i) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (cache Cache) filterDelimiterPrefix(keys []string, key, delim string, r BucketResourcesMetadata) ([]string, BucketResourcesMetadata) { |
|
|
|
|
|
|
|
switch true { |
|
|
|
switch true { |
|
|
|
case key == r.Prefix: |
|
|
|
case key == prefix: |
|
|
|
keys = appendUniq(keys, key) |
|
|
|
keys = append(keys, key) |
|
|
|
// delim - requires r.Prefix as it was trimmed off earlier
|
|
|
|
// delim - requires r.Prefix as it was trimmed off earlier
|
|
|
|
case key == r.Prefix+delim: |
|
|
|
case key == prefix+delim: |
|
|
|
keys = appendUniq(keys, key) |
|
|
|
keys = append(keys, key) |
|
|
|
case delim != "": |
|
|
|
case delim != "": |
|
|
|
r.CommonPrefixes = appendUniq(r.CommonPrefixes, r.Prefix+delim) |
|
|
|
commonPrefixes = append(commonPrefixes, prefix+delim) |
|
|
|
} |
|
|
|
} |
|
|
|
return keys, r |
|
|
|
return RemoveDuplicates(keys), RemoveDuplicates(commonPrefixes) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (cache Cache) listObjects(keys []string, key string, r BucketResourcesMetadata) ([]string, BucketResourcesMetadata) { |
|
|
|
func (cache Cache) listObjects(keys []string, key string, r BucketResourcesMetadata) ([]string, []string) { |
|
|
|
|
|
|
|
var commonPrefixes []string |
|
|
|
switch true { |
|
|
|
switch true { |
|
|
|
// Prefix absent, delimit object key based on delimiter
|
|
|
|
// Prefix absent, delimit object key based on delimiter
|
|
|
|
case r.IsDelimiterSet(): |
|
|
|
case r.IsDelimiterSet(): |
|
|
|
delim := delimiter(key, r.Delimiter) |
|
|
|
delim := Delimiter(key, r.Delimiter) |
|
|
|
switch true { |
|
|
|
switch true { |
|
|
|
case delim == "" || delim == key: |
|
|
|
case delim == "" || delim == key: |
|
|
|
keys = appendUniq(keys, key) |
|
|
|
keys = append(keys, key) |
|
|
|
case delim != "": |
|
|
|
case delim != "": |
|
|
|
r.CommonPrefixes = appendUniq(r.CommonPrefixes, delim) |
|
|
|
commonPrefixes = append(commonPrefixes, delim) |
|
|
|
} |
|
|
|
} |
|
|
|
// Prefix present, delimit object key with prefix key based on delimiter
|
|
|
|
// Prefix present, delimit object key with prefix key based on delimiter
|
|
|
|
case r.IsDelimiterPrefixSet(): |
|
|
|
case r.IsDelimiterPrefixSet(): |
|
|
|
if strings.HasPrefix(key, r.Prefix) { |
|
|
|
if strings.HasPrefix(key, r.Prefix) { |
|
|
|
trimmedName := strings.TrimPrefix(key, r.Prefix) |
|
|
|
trimmedName := strings.TrimPrefix(key, r.Prefix) |
|
|
|
delim := delimiter(trimmedName, r.Delimiter) |
|
|
|
delim := Delimiter(trimmedName, r.Delimiter) |
|
|
|
keys, r = cache.filterDelimiterPrefix(keys, key, delim, r) |
|
|
|
keys, commonPrefixes = cache.filterDelimiterPrefix(keys, key, r.Prefix, delim) |
|
|
|
} |
|
|
|
} |
|
|
|
// Prefix present, nothing to delimit
|
|
|
|
// Prefix present, nothing to delimit
|
|
|
|
case r.IsPrefixSet(): |
|
|
|
case r.IsPrefixSet(): |
|
|
|
keys = appendUniq(keys, key) |
|
|
|
keys = append(keys, key) |
|
|
|
// Prefix and delimiter absent
|
|
|
|
// Prefix and delimiter absent
|
|
|
|
case r.IsDefault(): |
|
|
|
case r.IsDefault(): |
|
|
|
keys = appendUniq(keys, key) |
|
|
|
keys = append(keys, key) |
|
|
|
} |
|
|
|
} |
|
|
|
return keys, r |
|
|
|
return RemoveDuplicates(keys), RemoveDuplicates(commonPrefixes) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ListObjects - list objects from cache
|
|
|
|
// ListObjects - list objects from cache
|
|
|
@ -493,11 +476,12 @@ func (cache Cache) ListObjects(bucket string, resources BucketResourcesMetadata) |
|
|
|
} |
|
|
|
} |
|
|
|
var results []ObjectMetadata |
|
|
|
var results []ObjectMetadata |
|
|
|
var keys []string |
|
|
|
var keys []string |
|
|
|
|
|
|
|
var commonPrefixes []string |
|
|
|
storedBucket := cache.storedBuckets[bucket] |
|
|
|
storedBucket := cache.storedBuckets[bucket] |
|
|
|
for key := range storedBucket.objectMetadata { |
|
|
|
for key := range storedBucket.objectMetadata { |
|
|
|
if strings.HasPrefix(key, bucket+"/") { |
|
|
|
if strings.HasPrefix(key, bucket+"/") { |
|
|
|
key = key[len(bucket)+1:] |
|
|
|
key = key[len(bucket)+1:] |
|
|
|
keys, resources = cache.listObjects(keys, key, resources) |
|
|
|
keys, commonPrefixes = cache.listObjects(keys, key, resources) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
var newKeys []string |
|
|
|
var newKeys []string |
|
|
@ -505,12 +489,13 @@ func (cache Cache) ListObjects(bucket string, resources BucketResourcesMetadata) |
|
|
|
case resources.Marker != "": |
|
|
|
case resources.Marker != "": |
|
|
|
for _, key := range keys { |
|
|
|
for _, key := range keys { |
|
|
|
if key > resources.Marker { |
|
|
|
if key > resources.Marker { |
|
|
|
newKeys = appendUniq(newKeys, key) |
|
|
|
newKeys = append(newKeys, key) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
default: |
|
|
|
default: |
|
|
|
newKeys = keys |
|
|
|
newKeys = keys |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
newKeys = RemoveDuplicates(newKeys) |
|
|
|
sort.Strings(newKeys) |
|
|
|
sort.Strings(newKeys) |
|
|
|
for _, key := range newKeys { |
|
|
|
for _, key := range newKeys { |
|
|
|
if len(results) == resources.Maxkeys { |
|
|
|
if len(results) == resources.Maxkeys { |
|
|
@ -523,6 +508,7 @@ func (cache Cache) ListObjects(bucket string, resources BucketResourcesMetadata) |
|
|
|
object := storedBucket.objectMetadata[bucket+"/"+key] |
|
|
|
object := storedBucket.objectMetadata[bucket+"/"+key] |
|
|
|
results = append(results, object) |
|
|
|
results = append(results, object) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
resources.CommonPrefixes = commonPrefixes |
|
|
|
return results, resources, nil |
|
|
|
return results, resources, nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|