Created
January 26, 2017 22:04
-
-
Save bbengfort/3c0cdfc21050bc3eed06fc93b05f7cd9 to your computer and use it in GitHub Desktop.
Write various sized files to test access patterns in FUSE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"fmt" | |
"io/ioutil" | |
"math/rand" | |
"os" | |
"github.com/urfave/cli" | |
) | |
// Runes for the random string function | |
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n ") | |
// Create a random string of length n | |
func randString(n int) string { | |
b := make([]rune, n) | |
for i := range b { | |
b[i] = letterRunes[rand.Intn(len(letterRunes))] | |
} | |
return string(b) | |
} | |
func writeIoutil(path string, nbytes int) error { | |
fmt.Printf("ioutil write %d random characters into %s\n", nbytes, path) | |
return ioutil.WriteFile(path, []byte(randString(nbytes)), 0644) | |
} | |
func writeDump(path string, nbytes int, sync bool) error { | |
fmt.Printf("dump write %d random characters into %s\n", nbytes, path) | |
fobj, err := os.Create(path) | |
if err != nil { | |
return err | |
} | |
defer fobj.Close() | |
_, err = fobj.Write([]byte(randString(nbytes))) | |
if err != nil { | |
return err | |
} | |
if sync { | |
return fobj.Sync() | |
} | |
return nil | |
} | |
func writeChunks(path string, nbytes int, chunks int, sync bool) error { | |
fmt.Printf("chunked write %d random characters into %s\n", nbytes, path) | |
fobj, err := os.Create(path) | |
if err != nil { | |
return err | |
} | |
defer fobj.Close() | |
for i := 0; i < nbytes; i += chunks { | |
var n int | |
if nbytes-i < chunks { | |
n = nbytes - i | |
} else { | |
n = chunks | |
} | |
_, err = fobj.Write([]byte(randString(n))) | |
if err != nil { | |
return err | |
} | |
if sync { | |
err = fobj.Sync() | |
if err != nil { | |
return err | |
} | |
} | |
} | |
return nil | |
} | |
func main() { | |
var chunks int | |
var nbytes int | |
var method string | |
var sync bool | |
app := cli.NewApp() | |
app.Name = "write" | |
app.Usage = "writes a large amount of random data to a file" | |
app.ArgsUsage = "files" | |
app.Flags = []cli.Flag{ | |
cli.IntFlag{ | |
Name: "nbytes, n", | |
Usage: "number of random characters to write into the file", | |
Value: 1.049e+8, | |
Destination: &nbytes, | |
}, | |
cli.IntFlag{ | |
Name: "chunk, c", | |
Usage: "size of chunk to write to file at a time", | |
Value: 24576, | |
Destination: &chunks, | |
}, | |
cli.StringFlag{ | |
Name: "method, m", | |
Usage: "write method: ioutil, dump, or chunks", | |
Value: "ioutil", | |
Destination: &method, | |
}, | |
cli.BoolTFlag{ | |
Name: "sync, s", | |
Usage: "call sync after each operation where applicable", | |
Destination: &sync, | |
}, | |
} | |
app.Action = func(c *cli.Context) error { | |
if c.NArg() < 1 { | |
return cli.NewExitError("specify path(s) to write data into", 1) | |
} | |
for _, path := range c.Args() { | |
var err error | |
switch method { | |
case "ioutil": | |
err = writeIoutil(path, nbytes) | |
case "dump": | |
err = writeDump(path, nbytes, sync) | |
case "chunks": | |
err = writeChunks(path, nbytes, chunks, sync) | |
default: | |
err = errors.New("no method named " + method) | |
} | |
if err != nil { | |
return cli.NewExitError(err.Error(), 1) | |
} | |
} | |
return nil | |
} | |
app.Run(os.Args) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment