]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/justdisk.c
226d270e50ccd193ec919094258a1cc6c1c8caf0
[bacula/bacula] / bacula / patches / testing / justdisk.c
1 /*
2  * This file is used to test simple I/O operation for accurate mode
3  *
4  *
5  * 1) Loading
6  *    fseek()   ?
7  *    fwrite()
8  *
9  * 2) Fetch + Update
10  *    fseek(pos1)
11  *    fread()
12  *    fseek(pos1)
13  *    fwrite()
14  *
15  * 3) Read all
16  *    fseek()
17  *    fread()
18  *    
19  */
20
21 /*
22  cd regress/build
23  make
24  cd patches/testing
25  g++ -g -Wall -I../../src -I../../src/lib -L../../src/lib justdisk.c -lbac -lpthread -lssl -D_TEST_BUF
26  ./a.out
27  */
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include "bacula.h"
35 #include "dird/dird.h"
36 typedef struct {
37    char *path;
38    char *fname;
39    int32_t seen;
40    int32_t pad;
41    int64_t mtime;
42    int64_t ctime;
43 } AccurateElt;
44
45 #define NB_ELT 500
46
47 typedef struct {
48    char *buf;
49    rblink link;
50 } MY;
51
52 typedef struct {
53    char *path;
54    char *fname;
55    int64_t index;
56    rblink link;
57 } MY_INDEX;
58
59 static int my_index_cmp(void *item1, void *item2)
60 {
61    MY_INDEX *elt1, *elt2;
62    elt1 = (MY_INDEX *) item1;
63    elt2 = (MY_INDEX *) item2;
64    int r = strcmp(elt1->fname, elt2->fname);
65    if (r) {
66       return r;
67    }
68    r = strcmp(elt1->path, elt2->path);
69    return r;
70 }
71
72 static int my_cmp(void *item1, void *item2)
73 {
74    MY *elt1, *elt2;
75    elt1 = (MY *) item1;
76    elt2 = (MY *) item2;
77    return strcmp(elt1->buf, elt2->buf);
78 }
79
80 rblist *load_rb(const char *file)
81 {
82    FILE *fp;
83    char buffer[1024];
84    MY *res;
85    rblist *lst;
86    lst = New(rblist(res, &res->link));
87
88    fp = fopen(file, "r");
89    if (!fp) {
90       return NULL;
91    }
92    while (fgets(buffer, sizeof(buffer), fp)) {
93       if (*buffer) {
94          int len = strlen(buffer);
95          if (len > 0) {
96             buffer[len-1]=0;       /* zap \n */
97          }
98          MY *buf = (MY *)malloc(sizeof(MY));
99          memset(buf, 0, sizeof(MY));
100          buf->buf = bstrdup(buffer);
101          res = (MY *)lst->insert(buf, my_cmp);
102          if (res != buf) {
103             free(buf->buf);
104             free(buf);
105          }
106       }
107    }
108    fclose(fp);
109
110    return lst;
111 }
112
113 /* buffer used for 4k io operations */
114 class AccurateBuffer
115 {
116 public:
117    AccurateBuffer() { 
118       _fp=NULL; 
119       _nb=-1;
120       _max_nb=-1;
121       _dirty=0; 
122       memset(_buf, 0, sizeof(_buf));
123    };
124    void *get_elt(int nb);
125    void init();
126    void destroy();
127    void update_elt(int nb);
128    ~AccurateBuffer() {
129       destroy();
130    }
131 private:
132    char _buf[4096];
133    int _nb;
134    int _max_nb;
135    char _dirty;
136    FILE *_fp;
137 };
138
139 void AccurateBuffer::init()
140 {
141    _fp = fopen("testfile", "w+");
142    if (!_fp) {
143       exit(1);
144    }
145    _nb=-1;
146    _max_nb=-1;
147 }
148
149 void AccurateBuffer::destroy()
150 {
151    if (_fp) {
152       fclose(_fp);
153       _fp = NULL;
154    }
155 }
156
157 void *AccurateBuffer::get_elt(int nb)
158 {
159    int page=nb*sizeof(AccurateElt)/sizeof(_buf);
160
161    if (!_fp) {
162       init();
163    }
164
165    if (page != _nb) {           /* not the same page */
166       if (_dirty) {             /* have to sync on disk */
167 //       printf("put dirty page on disk %i\n", _nb);
168          if (fseek(_fp, _nb*sizeof(_buf), SEEK_SET) == -1) {
169             perror("bad fseek");
170             exit(3);
171          }
172          if (fwrite(_buf, sizeof(_buf), 1, _fp) != 1) {
173             perror("writing...");
174             exit(2);
175          }
176          _dirty=0;
177       }
178       if (page <= _max_nb) {    /* we read it only if the page exists */
179 //       printf("read page from disk %i <= %i\n", page, _max_nb);
180          fseek(_fp, page*sizeof(_buf), SEEK_SET);
181          if (fread(_buf, sizeof(_buf), 1, _fp) != 1) {
182 //          printf("memset to zero\n");
183             memset(_buf, 0, sizeof(_buf));
184          }
185       } else {
186          memset(_buf, 0, sizeof(_buf));
187       }
188       _nb = page;
189       _max_nb = MAX(_max_nb, page);
190    }
191
192    /* compute addr of the element in _buf */
193    int addr=(nb%(sizeof(_buf)/sizeof(AccurateElt)))*sizeof(AccurateElt);
194 // printf("addr=%i\n", addr);
195    return (void *) (_buf + addr);
196 }
197
198 void AccurateBuffer::update_elt(int nb)
199 {
200    _dirty = 1;
201 }
202
203 typedef struct B_DBx
204 {
205    POOLMEM *fname;
206    int fnl;
207    POOLMEM *path;
208    int pnl;
209 } B_DBx;
210
211 /*
212  * Given a full filename, split it into its path
213  *  and filename parts. They are returned in pool memory
214  *  in the mdb structure.
215  */
216 void split_path_and_file(B_DBx *mdb, const char *fname)
217 {
218    const char *p, *f;
219
220    /* Find path without the filename.
221     * I.e. everything after the last / is a "filename".
222     * OK, maybe it is a directory name, but we treat it like
223     * a filename. If we don't find a / then the whole name
224     * must be a path name (e.g. c:).
225     */
226    for (p=f=fname; *p; p++) {
227       if (IsPathSeparator(*p)) {
228          f = p;                       /* set pos of last slash */
229       }
230    }
231    if (IsPathSeparator(*f)) {                   /* did we find a slash? */
232       f++;                            /* yes, point to filename */
233    } else {                           /* no, whole thing must be path name */
234       f = p;
235    }
236
237    /* If filename doesn't exist (i.e. root directory), we
238     * simply create a blank name consisting of a single
239     * space. This makes handling zero length filenames
240     * easier.
241     */
242    mdb->fnl = p - f;
243    if (mdb->fnl > 0) {
244       mdb->fname = check_pool_memory_size(mdb->fname, mdb->fnl+1);
245       memcpy(mdb->fname, f, mdb->fnl);    /* copy filename */
246       mdb->fname[mdb->fnl] = 0;
247    } else {
248       mdb->fname[0] = 0;
249       mdb->fnl = 0;
250    }
251
252    mdb->pnl = f - fname;
253    if (mdb->pnl > 0) {
254       mdb->path = check_pool_memory_size(mdb->path, mdb->pnl+1);
255       memcpy(mdb->path, fname, mdb->pnl);
256       mdb->path[mdb->pnl] = 0;
257    } else {
258       mdb->path[0] = 0;
259       mdb->pnl = 0;
260    }
261
262    Dmsg2(500, "split path=%s file=%s\n", mdb->path, mdb->fname);
263 }
264
265 #ifdef _TEST_TREE
266 int main()
267 {
268    AccurateElt *elt;
269    char *start_heap = (char *)sbrk(0);
270    MY *myp, *res;
271    MY_INDEX *idx;
272
273    FILE *fp;
274    fp = fopen("lst", "r");
275    if (!fp) {
276       exit (5);
277    }
278    rblist *index, *rb_file, *rb_path;
279    index   = New(rblist(idx, &idx->link)); /* (pathid, filenameid) => index */
280    rb_path = New(rblist(myp, &myp->link)); /* pathid => path */
281    rb_file = New(rblist(myp, &myp->link)); /* filenameid => filename */
282
283    B_DBx mdb;
284    mdb.fname = get_pool_memory(PM_FNAME);
285    mdb.path = get_pool_memory(PM_FNAME);
286
287    AccurateBuffer *accbuf = new AccurateBuffer;
288    char buf[4096];
289    int64_t count=0;
290    printf("loading...\n");
291    while (fgets(buf, sizeof(buf), fp)) {
292       int len = strlen(buf);
293       if (len > 0) {
294          buf[len-1]=0;       /* zap \n */
295       }
296       split_path_and_file(&mdb, buf);
297
298       MY_INDEX *idx = (MY_INDEX *)malloc(sizeof(MY_INDEX));
299       memset(idx, 0, sizeof(MY_INDEX));
300
301       myp = (MY *)malloc(sizeof(MY));
302       memset(myp, 0, sizeof(MY));
303       myp->buf = bstrdup(mdb.path);
304       res = (MY *)rb_path->insert(myp, my_cmp);
305       if (res != myp) {
306          free(myp->buf);
307          free(myp);
308       }
309
310       idx->path = res->buf;
311
312       myp = (MY *)malloc(sizeof(MY));
313       memset(myp, 0, sizeof(MY));
314       myp->buf = bstrdup(mdb.fname);
315       res = (MY *)rb_file->insert(myp, my_cmp);
316       if (res != myp) {
317          free(myp->buf);
318          free(myp);
319       }
320
321       idx->fname = res->buf;
322
323       idx->index = count;
324       index->insert(idx, my_index_cmp);
325
326       elt = (AccurateElt *)accbuf->get_elt(count);
327       elt->mtime = count;
328       elt->path = idx->path;
329       elt->fname = idx->fname;
330       accbuf->update_elt(count);
331
332       count++;
333    }
334
335    printf("fetch and update...\n");
336    fprintf(stderr, "count;%lli\n", count);
337    fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
338       
339    fseek(fp, 0, SEEK_SET);
340    int toggle=0;
341    while (fgets(buf, sizeof(buf), fp)) {
342       int len = strlen(buf);
343       if (len > 0) {
344          buf[len-1]=0;       /* zap \n */
345       }
346       split_path_and_file(&mdb, buf);
347       
348       MY search;
349       search.buf = mdb.fname;
350       MY *f = (MY *)rb_file->search(&search, my_cmp);
351
352       if (!f) {
353          continue;                      /* not found, skip */
354       }
355
356       search.buf = mdb.path;
357       MY *p = (MY *)rb_path->search(&search, my_cmp);
358       if (!p) {
359          continue;                      /* not found, skip */
360       }
361
362       MY_INDEX idx;
363       idx.path = p->buf;
364       idx.fname = f->buf;
365       MY_INDEX *res = (MY_INDEX *)index->search(&idx, my_index_cmp);
366       
367       if (!res) {
368          continue;                      /* not found skip */
369       }
370
371       AccurateElt *elt = (AccurateElt *)accbuf->get_elt(res->index);
372       elt->seen=toggle;
373       accbuf->update_elt(res->index);
374       toggle = (toggle+1)%100000;
375    }
376
377    for(int j=0;j<=count; j++) {
378       AccurateElt *elt = (AccurateElt *)accbuf->get_elt(j);
379       if (elt->path && elt->fname) {
380          if (!elt->seen) {
381             printf("%s%s\n", elt->path, elt->fname);
382          }
383       }
384    }
385 }
386 #else
387 #ifdef _TEST_OPEN
388 int main()
389 {
390    int fd;
391    int i;
392    AccurateElt elt;
393    char *start_heap = (char *)sbrk(0);
394
395    fd = open("testfile", O_CREAT | O_RDWR, 0600);
396    if (fd<0) {
397       perror("E: Can't open testfile ");
398       return(1);
399    }
400
401    memset(&elt, 0, sizeof(elt));
402
403    /* 1) Loading */
404    for (i=0; i<NB_ELT; i++) {
405       write(fd, &elt, sizeof(elt));
406    }
407
408    lseek(fd, 0, SEEK_SET);      /* rewind */
409
410    /* 2) load and update */
411    for (i=0; i<NB_ELT; i++) {
412       lseek(fd, i*sizeof(AccurateElt), SEEK_SET);
413       read(fd, &elt, sizeof(elt));
414       lseek(fd, i*sizeof(AccurateElt), SEEK_SET);
415       write(fd, &elt, sizeof(elt));
416    }
417
418    lseek(fd, 0, SEEK_SET);      /* rewind */
419
420    /* 3) Fetch all of them */
421    for (i=0; i<NB_ELT; i++) {
422       read(fd, &elt, sizeof(elt));
423    }
424
425    close(fd);
426
427    fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
428    sleep(50);
429    return (0);
430 }
431 #else  /* _TEST_OPEN */
432 #ifdef _TEST_BUF
433 int main()
434 {
435    char *start_heap = (char *)sbrk(0);
436
437    int i;
438    AccurateElt *elt;
439    AccurateBuffer *buf = new AccurateBuffer;
440
441    /* 1) Loading */
442    printf("Loading...\n");
443    for (i=0; i<NB_ELT; i++) {
444       elt = (AccurateElt *) buf->get_elt(i);
445       elt->mtime = i;
446       buf->update_elt(i);
447    }
448
449    /* 2) load and update */
450    printf("Load and update...\n");
451    for (i=0; i<NB_ELT; i++) {
452       elt = (AccurateElt *) buf->get_elt(i);
453       if (elt->mtime != i) {
454          printf("Something is wrong with elt %i mtime=%lli\n", i, elt->mtime);   
455          exit (0);
456       }
457       elt->seen = i;
458       buf->update_elt(i);
459    }
460
461    /* 3) Fetch all of them */
462    printf("Fetch them...\n");
463    for (i=0; i<NB_ELT; i++) {
464       elt = (AccurateElt *) buf->get_elt(i);
465       if (elt->seen != i || elt->mtime != i) {
466          printf("Something is wrong with elt %i mtime=%lli seen=%i\n", i, elt->mtime, elt->seen);
467          exit (0);
468       }
469    }
470    fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
471    delete buf;
472
473    return(0);
474 }
475
476 #else
477 int main()
478 {
479    FILE *fd;
480    int i;
481    AccurateElt elt;
482    fd = fopen("testfile", "w+");
483    if (!fd) {
484       perror("E: Can't open testfile ");
485       return(1);
486    }
487
488    memset(&elt, 0, sizeof(elt));
489
490    /* 1) Loading */
491    printf("Loading...\n");
492    for (i=0; i<NB_ELT; i++) {
493       fwrite(&elt, sizeof(elt), 1, fd);
494    }
495
496    fseek(fd, 0, SEEK_SET);      /* rewind */
497
498    /* 2) load and update */
499    printf("Load and update...\n");
500    for (i=0; i<NB_ELT; i++) {
501       fseek(fd, i*sizeof(AccurateElt), SEEK_SET);
502       fread(&elt, sizeof(elt), 1, fd);
503       fseek(fd, i*sizeof(AccurateElt), SEEK_SET);
504       fwrite(&elt, sizeof(elt), 1, fd);
505    }
506
507    fseek(fd, 0, SEEK_SET);      /* rewind */
508
509    /* 3) Fetch all of them */
510    printf("Fetch them...\n");
511    for (i=0; i<NB_ELT; i++) {
512       fread(&elt, sizeof(elt), 1, fd);
513    }
514
515    fclose(fd);
516    return(0);
517 }
518 #endif  /* _TEST_BUF */
519 #endif  /* _TEST_OPEN */
520 #endif  /* _TEST_TREE */