source: tags/svn.1.5.4/ARBDB/admap.cxx

Last change on this file was 8309, checked in by westram, 14 years ago
  • moved much code into static scope

(partly reverted by [8310])

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