source: branches/port5/ARBDB/admap.c

Last change on this file was 6107, checked in by westram, 16 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.6 KB
Line 
1
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "adlocal.h"
7/*#include "arbdb.h"*/
8#include "admap.h"
9
10#define ADMAP_BYTE_ORDER        0x01020304
11
12#ifdef DIGITAL
13#   define ALIGN_BITS       3
14#else
15#   define ALIGN_BITS       2           /* if ALIGN_BITS==3 we get problems
16                                           when writing pointer-arrays */
17#endif
18
19#define ALIGN(size)     (((((size)-1)>>ALIGN_BITS)+1)<<ALIGN_BITS)
20#define PTR_DIFF(p1,p2)     ((char*)(p1)-(char*)(p2))
21struct gbdata_offset
22{
23    GBDATA *gbd;
24    long    index;      /* new index */
25    long    offset;     /* offset in mapfile (initialized with -1) */
26};
27
28typedef struct S_gbdByKey   /* one for each diff. keyQuark */
29{
30    int             cnt;
31    struct gbdata_offset    *gbdoff;    /* gbdoff */
32
33} *gbdByKey;
34
35static gbdByKey gb_gbk = NULL;
36
37
38#ifdef NDEBUG
39#define MAKEREL(rel_to,offset)  ((offset)?((offset)-(rel_to)):0)
40#else
41long MAKEREL(long rel_to, long offset)
42{
43    ad_assert(rel_to);
44    return offset ? offset-rel_to : 0;
45}
46#endif
47
48/* ********************************************************
49   sort and binsearch
50   ******************************************************** */
51
52
53#define cmp(h1,h2)  ((long)(h1).gbd - (long)(h2).gbd)
54
55#define swap(h1,h2)             \
56do {                        \
57    struct gbdata_offset xxx = (h1);        \
58    (h1) = (h2);                \
59    (h2) = xxx;                 \
60} while(0)
61
62static void downheap(struct gbdata_offset *heap, int idx, int num)
63{
64    int idx2  = idx<<1;
65    int idx21 = idx2+1;
66    ad_assert(idx>=1);
67
68    if (idx2>num)
69        return;                     /* no lson -> done */
70
71    if (cmp(heap[idx2],heap[idx])>0)            /* lson is bigger than actual */
72    {
73        if (idx21 <= num &&             /* rson exists */
74            cmp(heap[idx2],heap[idx21])<0)  /* lson is smaller than rson */
75        {
76            swap(heap[idx],heap[idx21]);
77            downheap(heap,idx21,num);
78        }
79        else
80        {
81            swap(heap[idx],heap[idx2]);
82            downheap(heap,idx2,num);
83        }
84    }else if (idx21 <= num &&               /* rson exists */
85              cmp(heap[idx],heap[idx21])<0)         /* rson is bigger than actual */
86    {
87        swap(heap[idx],heap[idx21]);
88        downheap(heap,idx21,num);
89    }
90}
91
92static void sort_gbdata_offsets(struct gbdata_offset *gbdo, int num)
93{
94    int i;
95    struct gbdata_offset *heap = gbdo-1;
96#if defined(DEBUG)
97    int onum = num;
98#endif // DEBUG
99
100    ad_assert(gbdo!=NULL);
101    ad_assert(num>=1);
102
103    for (i=num/2; i>=1; i--)
104        downheap(heap,i,num); /* make heap */
105
106    while(num>1)    /* sort heap */
107    {
108        struct gbdata_offset big = heap[1];
109
110        heap[1] = heap[num];
111        downheap(heap,1,num-1);
112        heap[num] = big;
113        num--;
114    }
115
116#ifdef DEBUG
117    for (i=1; i<onum; i++) { /* test if sorted */
118        ad_assert(cmp(heap[i],heap[i+1])<0);
119    }
120#endif
121}
122
123static struct gbdata_offset *find_gbdata_offset(int quark, GBDATA *gbd){
124    struct gbdata_offset *gbdo = gb_gbk[quark].gbdoff;
125    long l=0,
126        h=gb_gbk[quark].cnt-1,
127        m;
128
129    ad_assert(h>=l);
130    ad_assert(gbdo!=NULL);
131
132    while (1){
133        long cmpres;
134
135        m = (l+h)>>1;
136        cmpres = (long)gbd - (long)gbdo[m].gbd;
137
138        if (cmpres == 0){   /* equal m */
139            return &gbdo[m];
140        }else{
141            if (l==h) break;
142            if (cmpres < 0) h = m;
143            else        l = m+1;
144        }
145    }
146
147    printf("not found(1): gbd=%lx\n",(long)gbd);
148    ad_assert(0);   /* should never occur */
149    return 0;
150}
151
152static long getrel_GBDATA(long rel_to, GBDATA *gbd)
153     /*
154      * calcs offset of 'gbd' in mapfile _relative_ to offset 'rel_to'
155      */
156{
157    /* printf("search %x\n", (long)gbd); */
158
159    if (gbd)
160    {
161        unsigned int quark = gbd->rel_father ? GB_KEY_QUARK(gbd) : 0; /* cause Main->data->father==NULL !! */
162        struct gbdata_offset *gbdo = gb_gbk[quark].gbdoff;
163        int l=0,
164            h=gb_gbk[quark].cnt-1,
165            m;
166
167        ad_assert(h>=l);
168        ad_assert(gbdo!=NULL);
169
170        while (1)
171        {
172            long cmpres;
173
174            m = (l+h)>>1;
175            cmpres = (long)gbd - (long)gbdo[m].gbd;
176
177            if (cmpres == 0){   /* equal m */
178                return MAKEREL(rel_to,gbdo[m].offset);
179            }else{
180                if (l==h) break;
181
182                if (cmpres < 0) h = m;
183                else        l = m+1;
184            }
185        }
186
187        printf("not found(2): gbd=%lx\n",(long)gbd);
188        ad_assert(0);   /* should never occur */
189    }
190
191    return 0;
192}
193
194#undef cmp
195#undef swap
196
197/* ********************************************************
198   write - routines
199   ******************************************************** */
200
201static int writeError;
202
203void ftwrite_aligned(const void *ptr, size_t ali_siz, FILE *fil) {
204    ad_assert(ali_siz == ALIGN(ali_siz));
205    if (!writeError && fwrite((const char *)ptr, 1, ali_siz, fil) != ali_siz) {
206        writeError = 1;
207    }
208}
209
210static char alignment_bytes[ALIGN(1)] = { 0 }; // zero-filled buffer with maximum alignment size
211
212/* ftwrite_unaligned does the same as ftwrite_aligned, but does not access uninitialized memory (that's better for valgrind) */
213
214size_t ftwrite_unaligned(const void *ptr, size_t unali_siz, FILE *fil) {
215    if (!writeError) {
216        size_t ali_siz   = ALIGN(unali_siz);
217        size_t pad_bytes = ali_siz-unali_siz;
218
219        if (fwrite((const char*)(ptr), 1, unali_siz, fil) == unali_siz) {
220            if (pad_bytes == 0 || fwrite(alignment_bytes, 1, pad_bytes, fil) == pad_bytes) {
221                return ali_siz; // success -> return size written
222            }
223        }
224    }
225    return 0; // failure
226}
227
228static long write_IE(struct gb_if_entries *ie, FILE *out, long *offset)
229     /* parameters mean the same as in write_GBDATA */
230{
231    long ieoffset = ie ? *offset : 0;
232
233    while (ie)
234    {
235        struct gb_if_entries copy;
236        size_t               copy_size;
237
238        if (out) {
239            copy.rel_ie_gbd = (GB_REL_GBDATA) getrel_GBDATA(*offset,GB_IF_ENTRIES_GBD(ie));
240            copy.rel_ie_next = (GB_REL_IFES)( ie->rel_ie_next ? ALIGN(sizeof(copy)) : 0);
241
242            /* ftwrite(&copy,ALIGN(sizeof(copy)),out); */
243            copy_size = ftwrite_unaligned(&copy,sizeof(copy),out);
244        }
245        else {
246            copy_size = ALIGN(sizeof(copy));
247        }
248
249        *offset += copy_size;
250        ie = GB_IF_ENTRIES_NEXT(ie);
251    }
252
253    return ieoffset;
254}
255
256static long write_IFS(struct gb_index_files_struct *ifs, FILE *out, long *offset)
257     /* parameters mean the same as in write_GBDATA */
258{
259    long    ifsoffset,
260        nextoffset,
261        entriesoffset;
262
263    if (!ifs) return 0;
264
265    nextoffset = write_IFS(GB_INDEX_FILES_NEXT(ifs), out, offset);
266
267    /* entries */
268
269    {
270        GB_REL_IFES *ie     = GB_INDEX_FILES_ENTRIES(ifs);
271        GB_REL_IFES *iecopy;
272        size_t       iesize = ALIGN((size_t)(ifs->hash_table_size)*sizeof(*ie));
273        int          idx;
274
275        ad_assert(ALIGN(sizeof(*ie))==sizeof(*ie));
276
277        iecopy = (GB_REL_IFES *)malloc(iesize);
278        memcpy(iecopy,ie,iesize);
279
280        /* write index entries an calc absolute offsets */
281
282        for (idx=0; idx<ifs->hash_table_size; idx++) {
283            iecopy[idx] = (GB_REL_IFES) write_IE(GB_ENTRIES_ENTRY(ie,idx),out,offset);
284        }
285
286        /* convert to relative offsets and write them */
287
288        entriesoffset = *offset;
289        for (idx=0; idx<ifs->hash_table_size; idx++) {
290            iecopy[idx] = (GB_REL_IFES)MAKEREL(entriesoffset,(long)iecopy[idx]);
291        }
292
293        if (out) ftwrite_aligned(iecopy,iesize,out);
294        *offset += iesize;
295
296        free(iecopy);
297    }
298
299    /* ifs */
300
301    {
302        struct gb_index_files_struct ifscopy = *ifs;
303        size_t ifscopy_size;
304
305        ifsoffset = *offset;
306
307        ifscopy.rel_if_next = (GB_REL_IFS)MAKEREL(ifsoffset,nextoffset);
308        ifscopy.rel_entries = (GB_REL_PIFES)MAKEREL(ifsoffset,entriesoffset);
309
310        if (out) ifscopy_size = ftwrite_unaligned(&ifscopy, sizeof(ifscopy), out);
311        else   ifscopy_size   = ALIGN(sizeof(ifscopy));
312
313        *offset += ifscopy_size;
314    }
315
316    return ifsoffset;
317}
318
319static void convertFlags4Save(struct gb_flag_types *flags, struct gb_flag_types2 * flags2, struct gb_flag_types3 *flags3)
320{
321    GBUSE(flags3);
322    flags->unused = 0;
323    flags->user_flags = 0;
324    ad_assert(flags->temporary==0);
325    flags->saved_flags = 0;
326
327    flags2->last_updated = 0;
328    flags2->usr_ref = 0;
329    flags2->folded_container = 0;
330    flags2->update_in_server = 0;
331    flags2->header_changed = 0;
332
333    /*  if (flags3)
334        {
335
336        }
337    */
338}
339
340static long write_GBDATA(GB_MAIN_TYPE *Main,GBDATA *gbd, int quark, FILE *out, long *offset,GB_MAIN_IDX main_idx)
341     /*
342       if out==NULL -> only calculate size
343
344       changes     'offset' according to size of written data
345       returns     offset of GBDATA in mapfile
346     */
347{
348    int  type = GB_TYPE(gbd);
349    long gbdoffset;
350
351    GBUSE(Main);
352    ad_assert(gbd->flags.temporary==0);
353
354    if (type==GB_DB)    /* CONTAINER */
355    {
356        GBCONTAINER *gbc = (GBCONTAINER*)gbd, gbccopy = *gbc;
357        long headeroffset, ifsoffset;
358
359        /* header */
360
361        {
362            struct gb_header_list_struct *header, *headercopy;
363            long headermemsize = ALIGN(gbc->d.headermemsize*sizeof(*header));
364            int item, nitems = gbc->d.nheader;
365
366            headeroffset = *offset;
367            header = GB_DATA_LIST_HEADER(gbc->d);
368            ad_assert(PTR_DIFF(&(header[1]),&(header[0]))==sizeof(*header));    /* @@@@ */
369
370            if (headermemsize){      /* if container is non-empty */
371
372                if (out){
373                    int valid=0;    /* no of non-temporary items */
374                    headercopy = (struct gb_header_list_struct*) malloc(headermemsize);
375                    ad_assert(sizeof(*headercopy)==ALIGN(sizeof(*headercopy)));
376                    memset(headercopy,0x0,headermemsize);
377
378                    for (item=0; item<nitems; item++)
379                    {
380                        GBDATA *gbd2 = GB_HEADER_LIST_GBD(header[item]);
381                        long hs_offset;
382
383                        if (!gbd2 || gbd2->flags.temporary) continue;
384
385                        hs_offset = headeroffset + PTR_DIFF(&(headercopy[valid]), &(headercopy[0]));
386
387                        headercopy[valid].flags = header[item].flags;
388                        headercopy[valid].flags.flags &= 1;
389                        headercopy[valid].flags.changed = 0;
390                        headercopy[valid].flags.ever_changed = 0;
391                        headercopy[valid].rel_hl_gbd = (GB_REL_GBDATA)getrel_GBDATA(hs_offset, gbd2);
392
393                        /* printf("header[%i->%i].rel_hl_gbd = %li\n", item,valid,
394                           headercopy[valid].rel_hl_gbd); */
395
396                        ad_assert(headercopy[valid].rel_hl_gbd != 0);
397                        valid++;
398                    }
399
400
401                    gbccopy.d.size          = gbccopy.d.nheader = valid;
402                    gbccopy.d.headermemsize = valid;
403
404                    headermemsize = ALIGN(valid * sizeof(*header));
405                    ftwrite_aligned(headercopy, headermemsize, out);
406                    free(headercopy);
407
408                }else{      /* Calc new indizes and size of header */
409                    int valid=0;    /* no of non-temporary items */
410                    for (item=0; item<nitems; item++)
411                    {
412                        GBDATA *gbd2 = GB_HEADER_LIST_GBD(header[item]);
413                        struct gbdata_offset *dof;
414                        if (!gbd2 || gbd2->flags.temporary) continue;
415                        dof = find_gbdata_offset(header[item].flags.key_quark, gbd2);
416                        dof->index = valid;
417                        valid++;
418                    }
419                    ad_assert((size_t)headermemsize >= valid * sizeof(*header));
420                    headermemsize = ALIGN(valid * sizeof(*header));
421                }
422            }else{
423                ad_assert(header==0);
424                headeroffset=0;
425            }
426
427            *offset += headermemsize;
428        }
429
430        /* ifs */
431
432        ifsoffset = write_IFS(GBCONTAINER_IFS(gbc),out,offset);
433
434        /* gbc */
435
436        gbdoffset = *offset;
437        {
438            size_t gbccopy_size;
439            if (out) {
440                struct gbdata_offset *dof = find_gbdata_offset(quark, (GBDATA *)gbc);
441                gbccopy.index = dof->index;
442                ad_assert(dof->index <= gbc->index); /* very simple check */
443
444                gbccopy.rel_father = (GB_REL_CONTAINER)getrel_GBDATA(gbdoffset,(GBDATA*)GB_FATHER(gbc));
445
446                gbccopy.ext = NULL;
447                convertFlags4Save(&(gbccopy.flags),&(gbccopy.flags2),&(gbccopy.flags3));
448                gbccopy.d.rel_header = (GB_REL_HLS)MAKEREL( gbdoffset+PTR_DIFF(&(gbc->d), gbc),headeroffset);
449                /* rel_header is relative to gbc->d !!! */
450                gbccopy.main_idx = main_idx;
451                gbccopy.index_of_touched_one_son = 0;
452                gbccopy.header_update_date = 0;
453                gbccopy.rel_ifs = (GB_REL_IFS)MAKEREL(gbdoffset,ifsoffset);
454
455                gbccopy_size = ftwrite_unaligned(&gbccopy, sizeof(gbccopy), out);
456            }
457            else {
458                gbccopy_size = ALIGN(sizeof(gbccopy));
459            }
460            *offset += gbccopy_size;
461        }
462    }
463    else        /* GBDATA */
464    {
465        int     ex = gbd->flags2.extern_data;
466        GBDATA  gbdcopy = *gbd; /* make copy to avoid change of mem */
467
468        if (ex) {
469            long   exoffset = *offset;
470            size_t ex_size;
471
472            if (out) ex_size = ftwrite_unaligned(GB_EXTERN_DATA_DATA(gbd->info.ex), gbdcopy.info.ex.memsize, out);
473            else ex_size     = ALIGN(gbdcopy.info.ex.memsize);;
474
475            *offset                  += ex_size;
476            gbdcopy.info.ex.rel_data  = (GB_REL_STRING)MAKEREL(*offset+PTR_DIFF(&(gbd->info),gbd), exoffset);
477        }
478
479        gbdoffset = *offset;
480
481        {
482            size_t gbdcopy_size;
483            if (out) {
484                struct gbdata_offset *dof = find_gbdata_offset(quark, gbd);
485                gbdcopy.index = dof->index;
486                ad_assert(dof->index <= gbd->index); /* very simple check */
487
488                gbdcopy.rel_father  = (GB_REL_CONTAINER)getrel_GBDATA(gbdoffset,(GBDATA*)GB_FATHER(gbd));
489                gbdcopy.ext         = NULL;
490                gbdcopy.server_id   = GBTUM_MAGIC_NUMBER;
491                convertFlags4Save(&(gbdcopy.flags),&(gbdcopy.flags2),NULL);
492                gbdcopy.cache_index = 0;
493                gbdcopy_size        = ftwrite_unaligned(&gbdcopy, sizeof(gbdcopy), out);
494            }
495            else {
496                gbdcopy_size = ALIGN(sizeof(gbdcopy));
497            }
498            *offset += gbdcopy_size;
499        }
500    }
501
502    return gbdoffset;
503}
504
505static long writeGbdByKey(GB_MAIN_TYPE *Main, gbdByKey gbk, FILE *out, GB_MAIN_IDX main_idx)
506{
507    int idx;
508    int idx2;
509    long offset = ALIGN(sizeof(struct gb_map_header));
510
511    for (idx=0; idx<Main->keycnt; idx++)
512    {
513        for (idx2=0; idx2<gbk[idx].cnt; idx2++)
514        {
515#if defined(ASSERTION_USED)
516            long gboffset =
517#endif // ASSERTION_USED
518                write_GBDATA(Main,gbk[idx].gbdoff[idx2].gbd,idx,out, &offset,main_idx);
519            ad_assert(gboffset == gbk[idx].gbdoff[idx2].offset);
520        }
521    }
522
523    return offset;
524}
525
526static long calcGbdOffsets(GB_MAIN_TYPE *Main, gbdByKey gbk)
527{
528    int idx;
529    int idx2;
530    long offset = ALIGN(sizeof(struct gb_map_header));
531
532    for (idx=0; idx<Main->keycnt; idx++)
533    {
534        for (idx2=0; idx2<gbk[idx].cnt; idx2++)
535        {
536            gbk[idx].gbdoff[idx2].offset =
537                write_GBDATA(Main,gbk[idx].gbdoff[idx2].gbd,idx, NULL, &offset,0);
538        }
539    }
540
541    return offset;
542}
543
544/* ********************************************************
545   handle gbdByKey
546   ******************************************************** */
547
548static void scanGbdByKey(GB_MAIN_TYPE *Main, GBDATA *gbd, gbdByKey gbk)
549{
550    unsigned int quark;
551
552    if (gbd->flags.temporary) return;
553
554    if (GB_TYPE(gbd) == GB_DB)  /* CONTAINER */
555    {
556        int         idx;
557        GBCONTAINER     *gbc = (GBCONTAINER *)gbd;
558        GBDATA      *gbd2;
559
560        for (idx=0; idx < gbc->d.nheader; idx++)
561            if ((gbd2=GBCONTAINER_ELEM(gbc,idx))!=NULL)
562                scanGbdByKey(Main,gbd2,gbk);
563    }
564
565    quark = GB_KEY_QUARK(gbd);
566
567#if defined(DEBUG)
568    if (quark == 0) {
569        printf("KeyQuark==0 found:\n");
570        GB_dump_db_path(gbd);
571    }
572/*     ad_assert(quark != 0);      // @@@ just a test */
573#endif /* DEBUG */
574    ad_assert(gbk[quark].gbdoff!=0);
575
576    gbk[quark].gbdoff[ gbk[quark].cnt ].gbd = gbd;
577    gbk[quark].gbdoff[ gbk[quark].cnt ].offset = -1; /* -1 is impossible as offset in file */
578    gbk[quark].cnt++;
579}
580
581static gbdByKey createGbdByKey(GB_MAIN_TYPE *Main)
582{
583    int idx;
584    gbdByKey gbk = (gbdByKey)GB_calloc(Main->keycnt, sizeof(*gbk));
585
586    if (!gbk) goto err1;
587
588    for (idx=0; idx<Main->keycnt; idx++) {
589        gbk[idx].cnt = 0;
590
591        if (Main->keys[idx].key && Main->keys[idx].nref>0) {
592            gbk[idx].gbdoff  = (struct gbdata_offset *) GB_calloc((size_t)Main->keys[idx].nref, sizeof(*(gbk[idx].gbdoff)));
593            if (!gbk[idx].gbdoff) goto err2;
594        }
595    }
596
597    gbk[0].gbdoff = (struct gbdata_offset *)GB_calloc(1,sizeof(*(gbk[0].gbdoff))); // @@@ FIXME : this is maybe allocated twice (5 lines above and here), maybe idx == 0 is special ?
598
599    scanGbdByKey(Main,(GBDATA*)Main->data,gbk);
600
601    for (idx=0; idx<Main->keycnt; idx++)
602        if (gbk[idx].cnt)
603            sort_gbdata_offsets(gbk[idx].gbdoff,gbk[idx].cnt);
604
605    return gbk;
606
607    /* error handling: */
608
609 err2:  while (idx>=0)
610 {
611     free(gbk[idx].gbdoff);
612     idx--;
613 }
614    free(gbk);
615 err1:  GB_memerr();
616    return NULL;
617}
618
619static void freeGbdByKey(GB_MAIN_TYPE *Main, gbdByKey gbk)
620{
621    int idx;
622
623    for (idx=0; idx<Main->keycnt; idx++) free(gbk[idx].gbdoff);
624    free(gbk);
625}
626
627/* ********************************************************
628   save
629   ******************************************************** */
630
631int gb_save_mapfile(GB_MAIN_TYPE *Main, GB_CSTR path)
632{
633    struct gb_map_header mheader;
634    FILE *out;
635    long calcOffset,
636        writeOffset;
637    GB_MAIN_IDX main_idx;
638    GB_CSTR opath = gb_overwriteName(path);
639
640    gb_gbk = createGbdByKey(Main);
641    if (!gb_gbk) goto error;
642
643    calcOffset = calcGbdOffsets(Main,gb_gbk);
644
645    /* write file */
646
647    out = fopen(opath, "w");
648    writeError = out==NULL;     /* global flag */
649
650    ad_assert(ADMAP_ID_LEN <= strlen(ADMAP_ID));
651    memset(&mheader,0,sizeof(mheader));
652    strcpy(mheader.mapfileID,ADMAP_ID); /* header */
653
654    mheader.version = ADMAP_VERSION;
655    mheader.byte_order = ADMAP_BYTE_ORDER;
656    main_idx  = gb_make_main_idx(Main); /* Generate a new main idx */
657    mheader.main_idx = main_idx;
658
659    /* mheader.main_data_offset = getrel_GBDATA(0,(GBDATA*)Main->data); */
660    mheader.main_data_offset = getrel_GBDATA(1,(GBDATA*)Main->data)+1;
661
662    ftwrite_unaligned(&mheader, sizeof(mheader), out);
663
664    ad_assert(GB_FATHER(Main->data)==Main->dummy_father);
665    SET_GB_FATHER(Main->data,NULL);
666    writeOffset = writeGbdByKey(Main,gb_gbk,out,main_idx);
667    SET_GB_FATHER(Main->data,Main->dummy_father);
668
669    ad_assert(calcOffset==writeOffset);
670
671    freeGbdByKey(Main,gb_gbk);
672    gb_gbk = NULL;
673
674    fclose(out);
675    if (!writeError) return 0;  /* no error */
676
677 error:
678
679    GB_export_errorf("Error while saving FastLoad-File '%s'", opath);
680    GB_unlink_or_warn(opath, NULL);
681
682    return -1;
683}
684
685/*
686  void renameOverwrittenMapfile(const char *path)
687  {
688  char *overwritten = overwriteName(path);
689  FILE *in = fopen(overwritten,"r");
690
691  if (in)
692  {
693  fclose(in);
694  remove(path);
695  rename(overwritten,path);
696  }
697  }
698*/
699
700/** Test whether mapfile is valid
701 *  returns -1 no map file found
702 *      0   mapfile error
703 *      1   mapfile ok
704 *     -1   MEMORY_TEST (don't use mapfile)
705 */
706
707int gb_is_valid_mapfile(const char *path, struct gb_map_header *mheader, int verbose)
708
709{
710    /* Dont map anything in memory debug mode */
711#if  ( MEMORY_TEST == 1)
712    GBUSE(path);
713    GBUSE(mheader);
714    GBUSE(verbose);
715    return -1;
716#else
717    FILE *in = fopen(path,"r");
718    if (in) {
719        const char *error_form = 0;
720
721        if (verbose) printf("ARB: Opening FastLoad File '%s' ...\n",path);
722        fread((char *)mheader, sizeof(*mheader),1,in);
723        fclose(in);
724
725        if (strcmp(mheader->mapfileID,ADMAP_ID)!=0)     error_form = "'%s' is not a ARB-FastLoad-File";
726        else if (mheader->version!=ADMAP_VERSION)       error_form = "FastLoad-File '%s' has wrong version";
727        else if (mheader->byte_order!=ADMAP_BYTE_ORDER) error_form = "FastLoad-File '%s' has wrong byte order";
728
729        if (error_form) {
730            GB_export_errorf(error_form, path);
731            GB_print_error();
732            return 0;
733        }
734
735        return 1;
736    }
737    return -1;
738#endif
739}
740
741/*
742  The module admalloc.c must be able to determine whether a memory block
743  is inside the mapped file. So we store the location of the mapped file in
744  the following both static variables.
745*/
746
747
748static char *fileMappedTo[GB_MAX_MAPPED_FILES];
749static long fileLen[GB_MAX_MAPPED_FILES];
750static int mappedFiles = 0;
751
752GBDATA *gb_map_mapfile(const char *path)
753{
754    struct gb_map_header mheader;
755
756    if (gb_is_valid_mapfile(path, &mheader, 1)>0)
757    {
758        char *mapped;
759        mapped = GB_map_file(path, 1);
760
761        if (mapped)
762        {
763            fileMappedTo[mappedFiles] = mapped;
764            fileLen[mappedFiles++] = GB_size_of_file(path);
765            ad_assert(mappedFiles<=GB_MAX_MAPPED_FILES);
766
767            return (GBDATA*)(mapped+mheader.main_data_offset);
768        }
769    }
770
771    return NULL;
772}
773
774int gb_isMappedMemory(char *mem)
775{
776    int file = 0;
777
778    while (file<mappedFiles)
779    {
780        if (mem>=fileMappedTo[file] &&
781            mem<(fileMappedTo[file]+fileLen[file])) return 1;
782        file++;
783    }
784
785    return 0;
786}
787
788
Note: See TracBrowser for help on using the repository browser.