source: tags/ms_r16q3/ARBDB/admap.cxx

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