Skip to content

Instantly share code, notes, and snippets.

@bbengfort
Created January 26, 2017 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bbengfort/3c0cdfc21050bc3eed06fc93b05f7cd9 to your computer and use it in GitHub Desktop.
Save bbengfort/3c0cdfc21050bc3eed06fc93b05f7cd9 to your computer and use it in GitHub Desktop.
Write various sized files to test access patterns in FUSE
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