Add sample zipf distribution randomizer

Instead of just doing purely random IO where each block is
touched exactly (or close to, depending on random map) once,
add a zipf distribution scheme where a selectable theta
defines the spread and frequency of blocks read/written.

Committing this so I don't lose it. Needs a few changes,
for instance we need to hash the zipf output so that
the spread doesn't always just favor the lower LBA range.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
diff --git a/options.c b/options.c
index 380df36..05a6a50 100644
--- a/options.c
+++ b/options.c
@@ -728,6 +728,29 @@
 }
 #endif
 
+static int str_random_distribution_cb(void *data, const char *str)
+{
+	struct thread_data *td = data;
+	double val;
+	char *nr;
+
+	if (td->o.random_distribution == FIO_RAND_DIST_RANDOM)
+		return 0;
+
+	nr = get_opt_postfix(str);
+	if (!nr)
+		val = 0.6;
+	else if (!str_to_float(nr, &val)) {
+		log_err("fio: random postfix parsing failed\n");
+		free(nr);
+		return 1;
+	}
+
+	td->o.zipf_theta = val;
+	free(nr);
+	return 0;
+}
+
 static int check_dir(struct thread_data *td, char *fname)
 {
 #if 0
@@ -1473,6 +1496,24 @@
 		.def	= "0",
 	},
 	{
+		.name	= "random_distribution",
+		.type	= FIO_OPT_STR,
+		.off1	= td_var_offset(random_distribution),
+		.cb	= str_random_distribution_cb,
+		.help	= "Random offset distribution generator",
+		.def	= "random",
+		.posval	= {
+			  { .ival = "random",
+			    .oval = FIO_RAND_DIST_RANDOM,
+			    .help = "Completely random",
+			  },
+			  { .ival = "zipf",
+			    .oval = FIO_RAND_DIST_ZIPF,
+			    .help = "Zipf distribution",
+			  },
+		},
+	},
+	{
 		.name	= "nrfiles",
 		.alias	= "nr_files",
 		.type	= FIO_OPT_INT,