5748: Write index data to http.ResponseWriter, instead of using string
[arvados.git] / services / keepstore / volume_unix.go
index f82598849c8ad5d9e63fb703bf479c1bbcfa888d..7df0b11245d643e4d62e2eaa90239df88769201f 100644 (file)
@@ -4,6 +4,7 @@ package main
 
 import (
        "fmt"
+       "io"
        "io/ioutil"
        "log"
        "os"
@@ -70,12 +71,12 @@ func (v *UnixVolume) IOHandler() {
 
 func MakeUnixVolume(root string, serialize bool, readonly bool) *UnixVolume {
        v := &UnixVolume{
-               root: root,
-               queue: nil,
+               root:     root,
+               queue:    nil,
                readonly: readonly,
        }
        if serialize {
-               v.queue =make(chan *IORequest)
+               v.queue = make(chan *IORequest)
                go v.IOHandler()
        }
        return v
@@ -215,14 +216,13 @@ func (v *UnixVolume) Status() *VolumeStatus {
        return &VolumeStatus{v.root, devnum, free, used}
 }
 
-// Index returns a list of blocks found on this volume which begin with
-// the specified prefix. If the prefix is an empty string, Index returns
-// a complete list of blocks.
+// IndexTo writes (to the given Writer) a list of blocks found on this
+// volume which begin with the specified prefix. If the prefix is an
+// empty string, Index writes a complete list of blocks.
 //
-// The return value is a multiline string (separated by
-// newlines). Each line is in the format
+// Each block is given in the format
 //
-//     locator+size modification-time
+//     locator+size modification-time {newline}
 //
 // e.g.:
 //
@@ -230,14 +230,11 @@ func (v *UnixVolume) Status() *VolumeStatus {
 //     e4d41e6fd68460e0e3fc18cc746959d2+67108864 1377796043
 //     e4de7a2810f5554cd39b36d8ddb132ff+67108864 1388701136
 //
-func (v *UnixVolume) Index(prefix string) (output string) {
-       filepath.Walk(v.root,
+func (v *UnixVolume) IndexTo(prefix string, w io.Writer) error {
+       return filepath.Walk(v.root,
                func(path string, info os.FileInfo, err error) error {
-                       // This WalkFunc inspects each path in the volume
-                       // and prints an index line for all files that begin
-                       // with prefix.
                        if err != nil {
-                               log.Printf("IndexHandler: %s: walking to %s: %s",
+                               log.Printf("%s: IndexTo Walk error at %s: %s",
                                        v, path, err)
                                return nil
                        }
@@ -250,18 +247,17 @@ func (v *UnixVolume) Index(prefix string) (output string) {
                                return filepath.SkipDir
                        }
                        // Skip any file that is not apparently a locator, e.g. .meta files
-                       if !IsValidLocator(locator) {
+                       if info.IsDir() || !IsValidLocator(locator) {
                                return nil
                        }
                        // Print filenames beginning with prefix
-                       if !info.IsDir() && strings.HasPrefix(locator, prefix) {
-                               output = output + fmt.Sprintf(
-                                       "%s+%d %d\n", locator, info.Size(), info.ModTime().Unix())
+                       if !strings.HasPrefix(locator, prefix) {
+                               return nil
                        }
-                       return nil
+                       _, err = fmt.Fprintf(w, "%s+%d %d\n",
+                               locator, info.Size(), info.ModTime().Unix())
+                       return err
                })
-
-       return
 }
 
 func (v *UnixVolume) Delete(loc string) error {