diff --git a/pkg/sync/sync.go b/pkg/sync/sync.go index 5aaaf46584b7..80aa46431a96 100644 --- a/pkg/sync/sync.go +++ b/pkg/sync/sync.go @@ -1109,6 +1109,29 @@ func listCommonPrefix(store object.ObjectStorage, prefix string, cp chan object. } func startProducer(tasks chan<- object.Object, src, dst object.ObjectStorage, prefix string, config *Config) error { + if prefix == "" && config.Limit == 1 && len(config.rules) == 0 { + // fast path for single key + obj, err := src.Head(config.Start) + if err == nil && (!obj.IsDir() || config.Dirs) { + var srckeys = make(chan object.Object, 1) + srckeys <- obj + close(srckeys) + var dstkeys = make(chan object.Object, 1) + if dobj, err := dst.Head(config.Start); err == nil || os.IsNotExist(err) { + if dobj != nil { + dstkeys <- dobj + } + close(dstkeys) + logger.Debugf("produce single key %s", config.Start) + produce(tasks, srckeys, dstkeys, config) + return nil + } else { + logger.Warnf("head %s from %s: %s", config.Start, dst, err) + } + } else if err != nil && !os.IsNotExist(err) { + logger.Warnf("head %s from %s: %s", config.Start, src, err) + } + } if config.ListThreads <= 1 || strings.Count(prefix, "/") >= config.ListDepth { return startSingleProducer(tasks, src, dst, prefix, config) }