summaryrefslogtreecommitdiff
path: root/xdelta3/badcopy.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3/badcopy.c')
-rwxr-xr-xxdelta3/badcopy.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/xdelta3/badcopy.c b/xdelta3/badcopy.c
new file mode 100755
index 0000000..c42e2b5
--- /dev/null
+++ b/xdelta3/badcopy.c
@@ -0,0 +1,111 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4
5#define BUFSZ (1 << 22)
6
7typedef unsigned int usize_t;
8
9double error_prob = 0.0001;
10usize_t mean_change = 100;
11usize_t total_change = 0;
12usize_t total_size = 0;
13usize_t max_change = 0;
14usize_t num_change = 0;
15
16int last_end = 0;
17
18static int
19edist (usize_t mean, usize_t max)
20{
21 double mean_d = mean;
22 double erand = log (1.0 / drand48 ());
23 usize_t x = (usize_t) (mean_d * erand + 0.5);
24
25 return (x < max) ? (x > 0 ? x : 1) : max;
26}
27
28void modify (char *buf, usize_t size)
29{
30 usize_t bufpos = 0, j;
31
32 last_end = 0;
33
34 for (;; /* bufpos and j are incremented in the inner loop */)
35 {
36 /* The size of the next modification. */
37 usize_t next_size = edist (mean_change, 1 << 31);
38 /* The expected interval of such a change. */
39 double expect_interval = ((double) next_size * (1.0 - error_prob)) / error_prob;
40 /* The number of bytes until the next modification. */
41 usize_t next_mod = edist (expect_interval, 1 << 31);
42
43 if (next_size + next_mod + bufpos > size) { break; }
44
45 if (max_change < next_size) { max_change = next_size; }
46
47 bufpos += next_mod;
48
49 fprintf (stderr, "COPY: %u-%u (%u)\n", total_size + last_end, total_size + bufpos, bufpos - last_end);
50
51 fprintf (stderr, "ADD: %u-%u (%u) is change %u\n", total_size + bufpos , total_size + bufpos + next_size, next_size, num_change);
52
53 total_change += next_size;
54 num_change += 1;
55
56 for (j = 0; j < next_size; j += 1, bufpos += 1)
57 {
58 buf[bufpos] = lrand48 () >> 3;
59 }
60
61 last_end = bufpos;
62 }
63
64 fprintf (stderr, "COPY: %u-%u (%u)\n", total_size + last_end, total_size + size, size - last_end);
65
66 total_size += size;
67}
68
69int main(int argc, char **argv)
70{
71 char buf[BUFSZ];
72 int c, ret;
73
74 if (argc > 3)
75 {
76 fprintf (stderr, "usage: badcopy [byte_error_prob [mean_error_size]]\n");
77 return 1;
78 }
79
80 if (argc > 2) { mean_change = atoi (argv[2]); }
81 if (argc > 1) { error_prob = atof (argv[1]); }
82
83 if (error_prob < 0.0 || error_prob > 1.0)
84 {
85 fprintf (stderr, "warning: error probability out of range\n");
86 return 1;
87 }
88
89 do
90 {
91 c = fread (buf, 1, BUFSZ, stdin);
92
93 if (c == 0) { break; }
94
95 modify (buf, c);
96
97 ret = fwrite (buf, 1, c, stdout);
98 }
99 while (c == BUFSZ);
100
101 if ((ret = fclose (stdout)))
102 {
103 perror ("fclose");
104 return 1;
105 }
106
107 fprintf (stderr, "add_prob %f; %u adds; total_change %u of %u bytes; add percentage %f; max add size %u\n",
108 error_prob, num_change, total_change, total_size, (double) total_change / (double) total_size, max_change);
109
110 return 0;
111}