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