]> mj.ucw.cz Git - libucw.git/blob - ucw/sorter/debug/radix-file-test.c
Sorter tests: get rid of sherlock.h
[libucw.git] / ucw / sorter / debug / radix-file-test.c
1 /*
2  *  An experiment with parallel reading and writing of files.
3  *
4  *  (c) 2007 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <ucw/lib.h>
8 #include <ucw/conf.h>
9 #include <ucw/io.h>
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15
16 #define COPY
17 #define DIRECT 0                // or O_DIRECT
18
19 static timestamp_t timer;
20
21 #define P_INIT do { cnt = 0; cnt_rep = 0; cnt_ms = 1; } while(0)
22 #define P_UPDATE(cc) do { \
23   cnt += cc; \
24   if (cnt >= cnt_rep) { cnt_ms += get_timer(&timer); \
25     printf("%d of %d MB (%.2f MB/sec)\r", (int)(cnt >> 20), (int)(total_size >> 20), (double)cnt / 1048576 * 1000 / cnt_ms); \
26     fflush(stdout); cnt_rep += 1<<26; } } while(0)
27 #define P_FINAL do { \
28   cnt_ms += get_timer(&timer); \
29   msg(L_INFO, "Spent %.3f sec (%.2f MB/sec)", (double)cnt_ms/1000, (double)cnt / 1048576 * 1000 / cnt_ms); \
30 } while(0)
31
32 int main(int argc, char **argv)
33 {
34   uns files, bufsize;
35   u64 total_size;
36   if (argc != 4 ||
37       cf_parse_int(argv[1], (int*) &files) ||
38       cf_parse_int(argv[2], (int*) &bufsize) ||
39       cf_parse_u64(argv[3], &total_size))
40     {
41       fprintf(stderr, "Usage: file-test <nr-files> <bufsize> <totalsize>\n");
42       return 1;
43     }
44   u64 cnt, cnt_rep;
45   uns cnt_ms;
46   int fd[files];
47   byte *buf[files], name[files][16];
48   uns xbufsize = bufsize;                                       // Used for single-file I/O
49   byte *xbuf = big_alloc(xbufsize);
50
51   init_timer(&timer);
52
53 #ifdef COPY
54   msg(L_INFO, "Creating input file");
55   int in_fd = ucw_open("tmp/ft-in", O_RDWR | O_CREAT | O_TRUNC | DIRECT, 0666);
56   ASSERT(in_fd >= 0);
57   ASSERT(!(total_size % xbufsize));
58   P_INIT;
59   for (uns i=0; i<total_size/xbufsize; i++)
60     {
61       for (uns j=0; j<xbufsize; j++)
62         xbuf[j] = i+j;
63       uns c = write(in_fd, xbuf, xbufsize);
64       ASSERT(c == xbufsize);
65       P_UPDATE(c);
66     }
67   lseek(in_fd, 0, SEEK_SET);
68   sync();
69   P_FINAL;
70 #endif
71
72   msg(L_INFO, "Initializing output files");
73   for (uns i=0; i<files; i++)
74     {
75       sprintf(name[i], "tmp/ft-%d", i);
76       fd[i] = ucw_open(name[i], O_RDWR | O_CREAT | O_TRUNC | DIRECT, 0666);
77       if (fd[i] < 0)
78         die("Cannot create %s: %m", name[i]);
79       buf[i] = big_alloc(bufsize);
80     }
81   sync();
82   get_timer(&timer);
83
84   msg(L_INFO, "Writing %d MB to %d files in parallel with %d byte buffers", (int)(total_size >> 20), files, bufsize);
85   P_INIT;
86   for (uns r=0; r<total_size/bufsize/files; r++)
87     {
88       for (uns i=0; i<files; i++)
89         {
90 #ifdef COPY
91           uns ci = read(in_fd, buf[i], bufsize);
92           ASSERT(ci == bufsize);
93 #else
94           for (uns j=0; j<bufsize; j++)
95             buf[i][j] = r+i+j;
96 #endif
97           uns c = write(fd[i], buf[i], bufsize);
98           ASSERT(c == bufsize);
99           P_UPDATE(c);
100         }
101     }
102 #ifdef COPY
103   close(in_fd);
104 #endif
105   msg(L_INFO, "Syncing");
106   sync();
107   P_FINAL;
108
109   msg(L_INFO, "Reading the files sequentially");
110   P_INIT;
111   for (uns i=0; i<files; i++)
112     {
113       lseek(fd[i], 0, SEEK_SET);
114       for (uns r=0; r<total_size/xbufsize/files; r++)
115         {
116           uns c = read(fd[i], xbuf, xbufsize);
117           ASSERT(c == xbufsize);
118           P_UPDATE(c);
119         }
120       close(fd[i]);
121     }
122   P_FINAL;
123
124   for (uns i=0; i<files; i++)
125     unlink(name[i]);
126 #ifdef COPY
127   unlink("tmp/ft-in");
128 #endif
129   msg(L_INFO, "Done");
130   return 0;
131 }