-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpd_mkfile.c
More file actions
131 lines (116 loc) · 2.59 KB
/
Copy pathpd_mkfile.c
File metadata and controls
131 lines (116 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Create a random file for a given probability distribution.
* (too slow in python)
*
* The probability distribution will be given in stdin and must
* be in the form of the following example:
* --- cut here (start) ---
* .5
* .8
* .9
* .95
* .98
* 1.0
* ---- cut here (eof) ---
*
* Note that the the probabilities are sorted and accumulated
* ( P(n) = p(n) + P(n-1) )
*
* number of probabilities must be <=256, so we can directly
* map them to the char range.
*
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <time.h>
#define BUFFSIZE (4*1024*1024)
#define MIN(a,b) ((a<b) ? a:b)
#ifdef PD_MKFILE_REPORT_RATE
#include "timer.h"
#endif
/*
* search for the output byte for a random number in [0,1).
* we start from the end (most wide intervals) and go
* all the way to the start. We could also do binary search
* or a hybrid method
*/
unsigned char search(double *pds, int pds_len, double item)
{
unsigned char i = (unsigned char)(pds_len-1);
for (; i > 0; i--){
if (pds[i] <= item){
return i;
}
}
return 0;
}
int main(int argc, char **argv)
{
double pds[256];
unsigned long i;
unsigned char buff[BUFFSIZE];
srand48(time(NULL));
if (argc < 3){
fprintf(stderr, "Usage: %s <filename> <size>\n", argv[0]);
exit(1);
}
char sbuff[1024];
for (i=0;;){
//printf("i=%lu\n", i);
if ( fgets(sbuff, BUFFSIZE, stdin) == NULL ){
break;
}
pds[i++] = strtod(sbuff, NULL);
}
assert(i <= 256);
int pds_len = i;
unsigned long fsize = atol(argv[2]);
int fd = open(argv[1], O_CREAT | O_RDWR, S_IRUSR|S_IWUSR);
if (fd == -1){
perror("open");
exit(1);
}
ftruncate(fd, fsize);
unsigned long remaining = fsize;
double rand;
#ifdef PD_MKFILE_REPORT_RATE
xtimer_t timer;
timer_init(&timer);
timer_start(&timer);
#endif
do {
unsigned int s = MIN(BUFFSIZE, remaining);
for (i=0; i < s; i++){
rand = drand48();
buff[i] = search(pds, pds_len, rand);
}
unsigned int written = 0;
do {
int ret = write(fd, buff, s);
if (ret == -1){
perror("write");
exit(1);
}
written += ret;
} while (s > written);
remaining -= s;
#ifdef PD_MKFILE_REPORT_RATE
timer_pause(&timer);
double secs = timer_secs(&timer);
unsigned long bytes = (fsize - remaining);
double Mbytes = ((double)bytes)/((double)(1024*1024));
double rate = Mbytes/secs;
printf("%lu (/%lu) in %lf secs [rate=%lf]\n", bytes, fsize, secs, rate);
timer_start(&timer);
#endif
} while (remaining > 0);
close(fd);
return 0;
}