foundationdb/fdbclient/zipf.c

130 lines
2.7 KiB
C

/*
* zipfian distribution copied from YCSB
* https://github.com/brianfrankcooper/YCSB
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "fdbclient/zipf.h"
/* global static */
static int items;
static int base;
static double zipfianconstant;
static double alpha, zetan, eta, theta, zeta2theta;
static int countforzeta;
static int allowitemcountdecrease = 0;
/* declarations */
double zetastatic2(int st, int n, double theta, double initialsum);
double zeta2(int st, int n, double theta_val, double initialsum);
double zetastatic(int n, double theta);
double zeta(int n, double theta_val);
double rand_double() {
return (double)rand() / (double)RAND_MAX;
}
int next_int(int itemcount) {
double u, uz;
int ret;
if (itemcount != countforzeta) {
zetan = zeta2(countforzeta, itemcount, theta, zetan);
} else if ((itemcount < countforzeta) && (allowitemcountdecrease)) {
zetan = zeta(itemcount, theta);
}
eta = (1 - pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan);
u = rand_double();
uz = u * zetan;
if (uz < 1.0) {
return base;
}
if (uz < 1.0 + pow(0.5, theta)) {
return base + 1;
}
ret = base + (int)(itemcount * pow(eta * u - eta + 1, alpha));
return ret;
}
int zipfian_next() {
return next_int(items);
}
double zetastatic2(int st, int n, double theta, double initialsum) {
int i;
double sum = initialsum;
for (i = st; i < n; i++) {
sum += 1 / pow(i + 1, theta);
}
return sum;
}
double zeta2(int st, int n, double theta_val, double initialsum) {
countforzeta = n;
return zetastatic2(st, n, theta_val, initialsum);
}
double zetastatic(int n, double theta) {
return zetastatic2(0, n, theta, 0);
}
double zeta(int n, double theta_val) {
countforzeta = n;
return zetastatic(n, theta_val);
}
void zipfian_generator4(int min, int max, double _zipfianconstant, double _zetan) {
items = max - min + 1;
base = min;
zipfianconstant = _zipfianconstant;
theta = zipfianconstant;
zeta2theta = zeta(2, theta);
alpha = 1.0 / (1.0 - theta);
zetan = _zetan;
countforzeta = items;
eta = (1 - pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan);
zipfian_next();
}
void zipfian_generator3(int min, int max, double zipfianconstant) {
zipfian_generator4(min, max, zipfianconstant, zetastatic(max - min + 1, zipfianconstant));
}
void zipfian_generator2(int min, int max) {
zipfian_generator3(min, max, ZIPFIAN_CONSTANT);
}
void zipfian_generator(int items) {
zipfian_generator2(0, items - 1);
}
#if 0 /* test */
void main() {
int i = 0;
int histogram[1000] = { 0 };
srand(time(0));
zipfian_generator(1000);
for (i = 0; i < 1000000; i++) {
int val = next_value();
//printf("%d\n", val);
histogram[val]++;
}
for (i = 0; i < 1000; i++) {
printf("%d\n", histogram[i]);
}
}
#endif