15652: Eliminate a malloc when writing a one-segment block.
[arvados.git] / sdk / go / manifest / manifest.go
index 67bd02bec9db6877adae15453d7404cccf7ddee1..a517c064fb475e2102943a9b4b1b0356b6447d92 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: Apache-2.0
+
 /* Deals with parsing Manifest Text. */
 
 // Inspired by the Manifest class in arvados/sdk/ruby/lib/arvados/keep.rb
@@ -162,7 +166,6 @@ func firstBlock(offsets []uint64, range_start uint64) int {
        // assumes that all of the blocks are contiguous, so range_start is guaranteed
        // to either fall into the range of a block or be outside the block range entirely
        for !(range_start >= block_start && range_start < block_end) {
-               fmt.Println(i, block_start, block_end)
                if lo == i {
                        // must be out of range, fail
                        return -1
@@ -349,23 +352,23 @@ func (m *Manifest) segment() (*segmentedManifest, error) {
 
 func (stream segmentedStream) normalizedText(name string) string {
        var sortedfiles []string
-       for k, _ := range stream {
+       for k := range stream {
                sortedfiles = append(sortedfiles, k)
        }
        sort.Strings(sortedfiles)
 
        stream_tokens := []string{EscapeName(name)}
 
-       blocks := make(map[string]int64)
+       blocks := make(map[blockdigest.BlockDigest]int64)
        var streamoffset int64
 
        // Go through each file and add each referenced block exactly once.
        for _, streamfile := range sortedfiles {
                for _, segment := range stream[streamfile] {
-                       if _, ok := blocks[segment.Locator]; !ok {
+                       b, _ := ParseBlockLocator(segment.Locator)
+                       if _, ok := blocks[b.Digest]; !ok {
                                stream_tokens = append(stream_tokens, segment.Locator)
-                               blocks[segment.Locator] = streamoffset
-                               b, _ := ParseBlockLocator(segment.Locator)
+                               blocks[b.Digest] = streamoffset
                                streamoffset += int64(b.Size)
                        }
                }
@@ -382,7 +385,8 @@ func (stream segmentedStream) normalizedText(name string) string {
                fout := EscapeName(streamfile)
                for _, segment := range stream[streamfile] {
                        // Collapse adjacent segments
-                       streamoffset = blocks[segment.Locator] + int64(segment.Offset)
+                       b, _ := ParseBlockLocator(segment.Locator)
+                       streamoffset = blocks[b.Digest] + int64(segment.Offset)
                        if span_start == -1 {
                                span_start = streamoffset
                                span_end = streamoffset + int64(segment.Len)
@@ -442,7 +446,7 @@ func (m segmentedManifest) manifestTextForPath(srcpath, relocate string) string
        }
 
        var sortedstreams []string
-       for k, _ := range m {
+       for k := range m {
                sortedstreams = append(sortedstreams, k)
        }
        sort.Strings(sortedstreams)
@@ -463,20 +467,21 @@ func (m segmentedManifest) manifestTextForPath(srcpath, relocate string) string
 // If 'srcpath' and 'relocate' are '.' it simply returns an equivalent manifest
 // in normalized form.
 //
+//   Extract(".", ".")  // return entire normalized manfest text
+//
 // If 'srcpath' points to a single file, it will return manifest text for just that file.
 // The value of "relocate" is can be used to rename the file or set the file stream.
 //
-// ManifestTextForPath("./foo", ".")  (extract file "foo" and put it in stream ".")
-// ManifestTextForPath("./foo", "./bar")  (extract file "foo", rename it to "bar" in stream ".")
-// ManifestTextForPath("./foo", "./bar/") (extract file "foo", rename it to "./bar/foo")
-// ManifestTextForPath("./foo", "./bar/baz") (extract file "foo", rename it to "./bar/baz")
+//   Extract("./foo", ".")          // extract file "foo" and put it in stream "."
+//   Extract("./foo", "./bar")      // extract file "foo", rename it to "bar" in stream "."
+//   Extract("./foo", "./bar/")     // extract file "foo", rename it to "./bar/foo"
+//   Extract("./foo", "./bar/baz")  // extract file "foo", rename it to "./bar/baz")
 //
 // Otherwise it will return the manifest text for all streams with the prefix in "srcpath" and place
 // them under the path in "relocate".
 //
-// ManifestTextForPath(".", ".")  (return entire normalized manfest text)
-// ManifestTextForPath("./stream", ".")  (extract "./stream" to "." and "./stream/subdir" to "./subdir")
-// ManifestTextForPath("./stream", "./bar")  (extract "./stream" to "./bar" and "./stream/subdir" to "./bar/subdir")
+//   Extract("./stream", ".")      // extract "./stream" to "." and "./stream/subdir" to "./subdir")
+//   Extract("./stream", "./bar")  // extract "./stream" to "./bar" and "./stream/subdir" to "./bar/subdir")
 func (m Manifest) Extract(srcpath, relocate string) (ret Manifest) {
        segmented, err := m.segment()
        if err != nil {