source: trunk/ARBDB/admap.cxx

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