Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_play / frag_count.c
1 #include <stdio.h>
2 #define RFS_ASSERT(condition)                                       \
3     if (!(condition)) {                                             \
4         fprintf(stderr, "Assertion failed: line %d, file \"%s\"\n", \
5                         __LINE__, __FILE__);                        \
6         fflush(stdout); \
7         fflush(stderr); \
8         exit(-1); \
9     }
10
11 #define DISK_BLOCK_SIZE 4096
12 #define SUB_DISTANCE
13 int f()
14 {}
15 char buf[8024000];
16 main(int argc, char ** argv)
17 {
18         FILE * fp;
19         int ret;
20         char * p;
21         int i;
22         int frag_num, distance, tfrag_num=0;
23         int td=0, td_MB=0;
24         int max_block_num = -1;
25         int block_num = -1;
26         int last_block_num;
27         int tblock_num =0;
28         int last_block = 0;
29         int block_range_start, block_range_stop;
30         int lineno = 0;
31         int format_version = 1;
32         char * p1=NULL, *p2=NULL, *p3=NULL;
33         int size = -1;
34         int max_block = 0;
35         FILE * fpout;
36         char name[1024];
37         int file_num = 0;
38         unsigned long long distancell = 0;
39         int avg_frag_distance;
40         int avg_block_distance;
41 #ifdef SUB_DISTANCE
42 #define MAX_SUB_DISTANCE_NUM 50
43         int sub_distance_index;
44         int SUB_DISTANCE_NUM = 1;
45         int SUB_DISTANCE_SIZE = 1000000;
46         unsigned long long sub_distance[MAX_SUB_DISTANCE_NUM];
47         unsigned int sub_frag_num[MAX_SUB_DISTANCE_NUM], sub_block_num[MAX_SUB_DISTANCE_NUM];
48         memset (&sub_distance, 0, sizeof(sub_distance));
49         memset (&sub_frag_num, 0, sizeof(sub_frag_num));
50         memset (&sub_block_num, 0, sizeof(sub_block_num));
51
52         if (argc == 3) {
53                 SUB_DISTANCE_NUM = atoi(argv[2]);
54                 RFS_ASSERT ((SUB_DISTANCE_NUM >=1) && (SUB_DISTANCE_NUM <= MAX_SUB_DISTANCE_NUM));
55         }
56 #endif
57
58         fp = fopen (argv[1], "r");
59     if (!fp) {
60         printf ("can not opern %s\n", argv[1]);
61         perror("open");
62         exit (0);
63     }
64
65
66         strcpy (name, argv[1]);
67         strcat (name, ".disk");
68
69         fpout = fopen(name, "w");
70         if (!fpout) {
71         printf ("can not opern %s\n", name);
72         perror("open");
73         exit (0);
74         }
75         
76         while (fgets(buf, sizeof(buf), fp)) {
77                 lineno++;
78                 if ((lineno%10000)==0) { // || (lineno >630000)) {
79                         fprintf(stderr, "%d lines processed\n", lineno);
80                 }
81                 if (lineno==122165)
82                         f();
83                 RFS_ASSERT (buf[strlen(buf)-1]=='\n');
84                 if (buf[0]=='U') {
85                         p = strstr (buf, "Size");
86                         RFS_ASSERT (p);
87                         if (size != -1) {
88                                 printf ("lineno %d size %d\n", lineno, size);
89                         }
90                         RFS_ASSERT (size == -1);
91                         sscanf(p, "Size: %d", &size);
92                         continue;
93                 }
94
95
96                 /* For now we ignore symbolic links */
97                 if (!strncmp(buf, "Fast_link_dest", strlen("Fast_link_dest")))  {
98                         f();
99                         goto ENDLOOP;
100                 }
101
102                 if (buf[0]!='B')
103                         continue;
104
105                 RFS_ASSERT (!strcmp(buf, "BLOCKS:\n"));
106                 fgets(buf, sizeof(buf), fp);
107                 lineno++;
108                 if (!(buf[strlen(buf)-1]=='\n')) {
109                         printf ("line[%d] %s\n", lineno, buf);
110                 };
111                 RFS_ASSERT (buf[strlen(buf)-1]=='\n');
112                 if (!strcmp(buf, "\n"))
113                         goto ENDLOOP;
114
115
116                 RFS_ASSERT (size >= 0);
117                 RFS_ASSERT (block_num == -1);
118                 RFS_ASSERT (max_block_num == -1);
119                 block_num = 0; /* the block number of block_range_start of current fragment */
120                 last_block_num = 0; /* the block number of block_range_start of last fragment */
121                 max_block_num = 0;
122                 if (size >0) {
123                         char line[1024];
124                         int i;
125                         fgets(line, sizeof(line), fp);
126                         lineno++;
127                         RFS_ASSERT (line[strlen(line)-1]=='\n');
128                         RFS_ASSERT (strstr(line, "TOTAL: "));
129                         max_block_num = atoi (line+strlen("TOTAL: "));
130                         i = ((size+DISK_BLOCK_SIZE-1)/DISK_BLOCK_SIZE);
131                         RFS_ASSERT ((max_block_num >= i) && ((max_block_num*9/i)<10));
132                 }
133                 tblock_num += max_block_num;
134
135                 p = buf;
136                 frag_num = 0;
137                 distance = 0;
138                 last_block = 0;
139                 //printf ("line %d %s", lineno, buf);
140                 while (p && (*p!='\n')) {
141                         if (format_version == 1) {
142                                 p1 = strchr (p, ')');
143                                 if (p1) {
144                                         p2 = strchr (p, '-');
145                                         p3 = strchr (p, ':');
146                                         RFS_ASSERT (p3);
147                                         p3++;
148                                 } else {
149                                         format_version = 2;
150                                         p3 = p;
151                                 }
152                         } else
153                                 p3 = p;
154
155 #define checkit
156                         /* single block range */
157                         if ((p2==NULL) || p2>p1) {      
158 #ifdef checkit
159                                 char * pt2, a;
160                                 pt2 = strchr(p3, ' ');
161                                 if (!pt2) {
162                                         pt2 = strchr(p3, '\n');
163                                         a = '\n';
164                                 } else
165                                         a = ' ';
166                                 RFS_ASSERT (pt2);
167                                 RFS_ASSERT (pt2!=p3);
168                                 *pt2 = 0;
169                                 block_range_start = atoi (p3);
170                                 *pt2 = a ;
171 #else
172                                 sscanf(p3, "%d", &block_range_start);
173 #endif
174                                 block_range_stop = block_range_start;
175                         } else {
176 #ifdef checkit
177                                 char * pt, * pt2, a;
178                                 pt = strchr(p3, '-');
179                                 RFS_ASSERT (pt);
180                                 *pt = 0;
181                                 block_range_start = atoi (p3);
182                                 *pt = '-';
183                                 pt2 = strchr(pt+1, ',');
184                                 if (!pt2) {
185                                         pt2 = strchr(pt+1, '\n');
186                                         a = '\n';
187                                 } else
188                                         a = ',';
189                                 RFS_ASSERT (pt2);
190                                 *pt2 = 0;
191                                 block_range_stop = atoi (pt+1);
192                                 *pt2 = a ;
193 #else
194                                 sscanf(p3, "%d-%d", &block_range_start, &block_range_stop);
195 #endif
196                         }
197
198                         RFS_ASSERT (block_range_start >0);
199                         RFS_ASSERT (block_range_stop >= block_range_start);
200
201                         block_num += (block_range_stop - block_range_start+1);
202
203                         if (block_range_start != (last_block+1)) {
204                                 frag_num ++;
205
206 #ifdef SUB_DISTANCE
207                                 sub_distance_index = (block_num-1) * SUB_DISTANCE_NUM/max_block_num;
208                                 sub_block_num[sub_distance_index] += block_num - last_block_num;
209                                 last_block_num = block_num;
210                                 //printf ("block_num %d SUB_DISTANCE_NUM %d max_block_num %d index %d\n", block_num, SUB_DISTANCE_NUM,
211 //max_block_num, sub_distance_index);
212                                 RFS_ASSERT ((sub_distance_index>=0) && (sub_distance_index<SUB_DISTANCE_NUM));
213 #endif
214                                 if (last_block!=0) {
215                                         if (block_range_start > last_block+1) {
216                                                 distance += block_range_start - (last_block+1);
217 #ifdef SUB_DISTANCE
218                                                 sub_distance[sub_distance_index] += block_range_start - (last_block+1);
219 #endif
220                                         } else {
221                                                 distance += (last_block+1)-block_range_start;
222 #ifdef SUB_DISTANCE
223                                                 sub_distance[sub_distance_index] += (last_block+1)-block_range_start ;
224 #endif
225                                         }
226
227                                         if (distance >= 1000000000) {
228                                                 printf ("line[%d] %s, block_range_start %d last_block %d\n", lineno, buf, block_range_start, last_block);
229                                                 RFS_ASSERT (0);
230                                         }
231                                         fprintf(fpout, "%d %d\n", last_block, block_range_start);
232                                 };
233                                 //printf ("range_start %d last_block %d distance %d\n", 
234                                                 //block_range_start, last_block, distance);
235 #ifdef SUB_DISTANCE
236                                 sub_frag_num[sub_distance_index] ++;
237 #endif
238                         }
239                         
240                         last_block = block_range_stop;
241                         if (last_block > max_block)
242                                 max_block = last_block;
243                         if (p1)
244                                 p = strchr (p3, '(');
245                         else {
246                                 p = strchr (p3, ' ');
247                                 p++;
248                         }
249                 }
250                 //printf ("FRAG_NUM %d DISTANCE %d\n", frag_num, distance);
251                 tfrag_num += frag_num;
252                 distancell += distance;
253 ENDLOOP:
254                 file_num ++;
255                 size = -1;
256                 block_num = -1;
257                 max_block_num = -1;
258 /*
259                 td += distance;
260                 if (td > 1000000) {
261                         td_MB += td/1000000;
262                         td = td%1000000;
263                         RFS_ASSERT (td_MB < 1000000000);
264                 }
265 */
266         }
267         fclose (fpout);
268         fclose (fp);
269                                                                               
270         if (tfrag_num != file_num) {
271                 RFS_ASSERT ((distancell /(tfrag_num-file_num)) < 1000000000);
272                 RFS_ASSERT ((distancell /(tblock_num-file_num)) < 1000000000);
273                 avg_frag_distance = distancell/(tfrag_num-file_num);
274                 avg_block_distance = distancell/(tblock_num-file_num);
275         } else {
276                 avg_frag_distance =0;
277                 avg_block_distance =0;
278         }
279         RFS_ASSERT ((distancell /1000000) < 1000000000);
280         td_MB = distancell/1000000;
281         td = distancell%1000000;
282         
283 #ifdef SUB_DISTANCE
284         for (i=0; i<SUB_DISTANCE_NUM; i++) {
285                 printf("sub[%d] block_num %d frag_num %d distance %d\n", i, sub_block_num[i], sub_frag_num[i], sub_distance[i]/1000000);
286         }
287 #endif
288 /*
289     distancell = td_MB;
290     distancell *=1000000;
291     distancell +=td;
292     distancell /= (tfrag_num-file_num);
293     if (distancell > 1000000000) {
294         printf ("error 4\n");
295         exit(-1);
296     }
297     avg_frag_distance = distancell;
298
299     distancell = td_MB;
300     distancell *=1000000;
301     distancell +=td;
302     distancell /= (tblock_num-file_num);
303     if (distancell > 1000000000) {
304         printf ("error 4\n");
305         exit(-1);
306     }
307     avg_block_distance = distancell;
308 */
309
310         printf("****total FRAG_NUM %d td_MB %d td %d tblock_num %d max_blockno %d file_num %d avg_frag_distance %d avg_block_distance %d\n", tfrag_num, td_MB, td, tblock_num, max_block, file_num, avg_frag_distance, avg_block_distance);
311 }