func generateData(size, maxRandomNum int, dataFilePath string) error {
	fd, err := os.Create(dataFilePath)
	if err != nil {
		return fmt.Errorf("unable to open file :: %v", err)
	}
	defer fd.Close()
	writer := bufio.NewWriter(fd)
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < size; i++ {
		num := (rand.Int() % (2 * maxRandomNum)) - maxRandomNum
		str := strconv.Itoa(num) + "\n"
		writer.WriteString(str)
	}
	return writer.Flush()
}
generateData generates random data and writes them to a file with newline delimiter
package main
import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)
const (
	cMaxRandomNum = 1000000000
)
func main() {
	var numDataElements, maxMemSortSize int
	var inputPath, tempPath, outputPath string
	flag.IntVar(&numDataElements, "num", 1000, "# elements to generate & sort")
	flag.IntVar(&maxMemSortSize, "nummem", 100, "# elements to sort in mem")
	flag.StringVar(&inputPath, "i", "input.dat", "input file (overwritten)")
	flag.StringVar(&tempPath, "t", "bq", "path to write intermediate data")
	flag.StringVar(&outputPath, "o", "output.dat", "output file (overwritten)")
	flag.Parse()
	if _, err := os.Stat(inputPath); os.IsNotExist(err) {
		log.Println("generating random dataset")
		if err := generateData(numDataElements, cMaxRandomNum, inputPath); err != nil {
			panic(err)
		}
	}
	if err := ExternalSort(inputPath, tempPath, outputPath, maxMemSortSize); err != nil {
		panic(err)
	}
	log.Println("validating sort")
	if err := validateSort(outputPath); err != nil {
		panic(err)
	}
}