ARB
admap.cxx
Go to the documentation of this file.
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 
28 struct gbdata_offset {
30  long index; // new index
31  long offset; // offset in mapfile (initialized with -1)
32 };
33 
34 struct gbdByKey { // one for each diff. keyQuark
35  int cnt;
37 };
38 
39 static gbdByKey *gb_gbk = NULp;
40 
41 
42 inline 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 
59 static 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 
87 static 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 
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 
146 static 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 
190 static bool writeError;
191 
192 static 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 
199 static char alignment_bytes[ALIGN(1)] = { 0 }; // zero-filled buffer with maximum alignment size
200 
201 static 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 
218 static 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) {
224  size_t copy_size;
225 
226  if (out) {
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 
243 static 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  {
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 
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 }
317 static 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 
492 static 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 
507 static 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 
526 static 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 
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 
576 static 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 
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 
616 
617  IF_ASSERTION_USED(long writeOffset =)
618  writeGbdByKey(Main, gb_gbk, out, main_idx_4_save);
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 
645 #if (MEMORY_TEST == 1)
646  return false;
647 #else
648  return true;
649 #endif
650 }
651 
652 int 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  */
704 static int mappedFiles = 0;
705 
706 GBDATA *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 
725 int 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 
long memsize
Definition: gb_data.h:29
void GB_dump_db_path(GBDATA *gbd)
Definition: adTest.cxx:27
const char * GB_ERROR
Definition: arb_core.h:25
static void freeGbdByKey(GB_MAIN_TYPE *Main, gbdByKey *gbk)
Definition: admap.cxx:576
unsigned int saved_flags
Definition: gb_data.h:74
static void ftwrite_aligned(const void *ptr, size_t ali_siz, FILE *fil)
Definition: admap.cxx:192
static char * fileMappedTo[GB_MAX_MAPPED_FILES]
Definition: admap.cxx:702
#define ADMAP_VERSION
Definition: gb_map.h:20
gb_flag_types2 flags2
Definition: gb_data.h:135
gb_data_base_type_union info
Definition: gb_data.h:204
long GB_REL_PIFES
Definition: gb_memory.h:61
void GB_unlink_or_warn(const char *path, GB_ERROR *error)
Definition: arb_file.cxx:206
long nref
Definition: gb_key.h:31
unsigned int folded_container
Definition: gb_data.h:82
long server_id
Definition: gb_data.h:130
long GB_REL_CONTAINER
Definition: gb_memory.h:57
long
Definition: AW_awar.cxx:154
static void convertFlags4Save(gb_flag_types *flags, gb_flag_types2 *flags2, gb_flag_types3 *)
Definition: admap.cxx:305
bool GB_supports_mapfile()
Definition: admap.cxx:644
static long calcGbdOffsets(GB_MAIN_TYPE *Main, gbdByKey *gbk)
Definition: admap.cxx:507
GB_MAIN_IDX main_idx
Definition: gb_map.h:26
GB_ERROR GB_IO_error(const char *action, const char *filename)
Definition: arb_msg.cxx:293
long GB_REL_HLS
Definition: gb_memory.h:58
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
unsigned int unused
Definition: gb_data.h:71
GBDATA * GB_HEADER_LIST_GBD(gb_header_list &hl)
Definition: gb_header.h:42
GB_REL_CONTAINER rel_father
Definition: gb_data.h:131
CONSTEXPR_INLINE gb_header_list * GB_DATA_LIST_HEADER(gb_data_list &dl)
Definition: gb_data.h:105
char * get_data()
Definition: gb_data.h:32
gb_index_files * GB_INDEX_FILES_NEXT(gb_index_files *ixf)
Definition: gb_index.h:87
GB_MAIN_IDX gb_make_main_idx(GB_MAIN_TYPE *Main)
Definition: ad_load.cxx:922
GBCONTAINER * root_container
Definition: gb_main.h:120
long GB_size_of_file(const char *path)
Definition: arb_file.cxx:28
GBDATA * GB_IF_ENTRIES_GBD(gb_if_entries *ie)
Definition: gb_index.h:36
long GB_REL_GBDATA
Definition: gb_memory.h:56
Definition: gb_key.h:28
static char alignment_bytes[ALIGN(1)]
Definition: admap.cxx:199
static void downheap(gbdata_offset *heap, int idx, int num)
Definition: admap.cxx:59
unsigned int last_updated
Definition: gb_data.h:79
static int mappedFiles
Definition: admap.cxx:704
static long write_IFS(gb_index_files *ifs, FILE *out, long *offset)
Definition: admap.cxx:243
GB_ERROR GB_export_error(const char *error)
Definition: arb_msg.cxx:259
uchar flags
Definition: probe_tree.h:38
boolean verbose
Definition: readseq.c:457
gb_flag_types flags
Definition: gb_data.h:134
int cnt
Definition: admap.cxx:35
long GB_REL_IFS
Definition: gb_memory.h:60
GB_REL_GBDATA rel_ie_gbd
Definition: gb_index.h:26
long header_update_date
Definition: gb_data.h:253
long GB_REL_STRING
Definition: gb_memory.h:55
unsigned int user_flags
Definition: gb_data.h:72
#define PTR_DIFF(p1, p2)
Definition: admap.cxx:26
static void scanGbdByKey(GB_MAIN_TYPE *Main, GBDATA *gbd, gbdByKey *gbk)
Definition: admap.cxx:526
unsigned int user_bits
Definition: gb_data.h:80
bool is_container() const
Definition: gb_data.h:147
GB_REL_PIFES rel_entries
Definition: gb_index.h:53
char * GB_map_file(const char *path, int writeable)
Definition: adsocket.cxx:344
long offset
Definition: admap.cxx:31
static void error(const char *msg)
Definition: mkptypes.cxx:96
gb_flag_types3 flags3
Definition: gb_data.h:245
long byte_order
Definition: gb_map.h:25
GB_REL_IFES rel_ie_next
Definition: gb_index.h:25
int gb_is_valid_mapfile(const char *path, gb_map_header *mheader, int verbose)
Definition: admap.cxx:652
static gbdByKey * createGbdByKey(GB_MAIN_TYPE *Main)
Definition: admap.cxx:552
gb_db_extended * ext
Definition: gb_data.h:132
unsigned int update_in_server
Definition: gb_data.h:83
GBCONTAINER * as_container() const
Definition: gb_data.h:155
GB_REL_STRING rel_data
Definition: gb_data.h:28
static gbdata_offset * find_gbdata_offset(GBQUARK quark, GBDATA *gbd)
Definition: admap.cxx:116
#define cmp(h1, h2)
Definition: admap.cxx:50
static long write_GBDATA(GB_MAIN_TYPE *, GBDATA *gbd, GBQUARK quark, FILE *out, long *offset, GB_MAIN_IDX main_idx)
Definition: admap.cxx:317
long index_of_touched_one_son
Definition: gb_data.h:248
CONSTEXPR_INLINE GBCONTAINER * GB_FATHER(GBDATA *gbd)
Definition: gb_data.h:271
GBDATA * gbd
Definition: admap.cxx:29
static long getrel_GBDATA(long rel_to, GBDATA *gbd)
Definition: admap.cxx:146
GB_REL_HLS rel_header
Definition: gb_data.h:99
CONSTEXPR_INLINE bool valid(SpeciesCreationMode m)
Definition: ed4_class.hxx:2249
int cache_index
Definition: gb_data.h:206
char * key
Definition: gb_key.h:29
GBDATA * gb_main() const
Definition: gb_main.h:179
gb_index_files * GBCONTAINER_IFS(GBCONTAINER *gbc)
Definition: gb_index.h:94
#define ALIGN(size)
Definition: admap.cxx:25
unsigned int temporary
Definition: gb_data.h:73
GB_REL_GBDATA rel_hl_gbd
Definition: gb_header.h:36
gb_extern_data ex
Definition: gb_data.h:51
gb_if_entries * GB_IF_ENTRIES_NEXT(gb_if_entries *ie)
Definition: gb_index.h:29
GB_ERROR GB_print_error()
Definition: arb_msg.cxx:335
#define GB_MAX_MAPPED_FILES
Definition: admap.cxx:17
int gb_isMappedMemory(void *mem)
Definition: admap.cxx:725
long main_data_offset
Definition: gb_map.h:27
static bool writeError
Definition: admap.cxx:190
static void copy(double **i, double **j)
Definition: trnsprob.cxx:32
static long writeGbdByKey(GB_MAIN_TYPE *Main, gbdByKey *gbk, FILE *out, GB_MAIN_IDX main_idx)
Definition: admap.cxx:492
CONSTEXPR_INLINE_Cxx14 void SET_GB_FATHER(GBDATA *gbd, GBCONTAINER *father)
Definition: gb_data.h:274
GBQUARK GB_KEY_QUARK(GBDATA *gbd)
Definition: gb_key.h:48
static void sort_gbdata_offsets(gbdata_offset *gbdo, int num)
Definition: admap.cxx:87
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
#define IF_ASSERTION_USED(x)
Definition: arb_assert.h:308
#define GBTUM_MAGIC_NUMBER
Definition: gb_local.h:25
#define gb_assert(cond)
Definition: arbdbt.h:11
unsigned int ever_changed
Definition: gb_header.h:23
long MAKEREL(long rel_to, long offset)
Definition: admap.cxx:42
bool stored_external() const
Definition: gb_data.h:211
long GB_REL_IFES
Definition: gb_memory.h:59
char mapfileID[ADMAP_ID_LEN+1]
Definition: gb_map.h:23
#define ADMAP_ID
Definition: gb_map.h:18
#define swap(h1, h2)
Definition: admap.cxx:52
static gbdByKey * gb_gbk
Definition: admap.cxx:39
#define ADMAP_ID_LEN
Definition: gb_map.h:19
long index
Definition: gb_data.h:133
short GB_MAIN_IDX
Definition: gb_local.h:32
GB_REL_IFS rel_if_next
Definition: gb_index.h:48
#define ADMAP_BYTE_ORDER
Definition: admap.cxx:16
long index
Definition: admap.cxx:30
unsigned int changed
Definition: gb_header.h:22
gb_Key * keys
Definition: gb_main.h:134
static long fileLen[GB_MAX_MAPPED_FILES]
Definition: admap.cxx:703
GBENTRY * as_entry() const
Definition: gb_data.h:150
GBDATA * GBCONTAINER_ELEM(GBCONTAINER *gbc, int idx)
Definition: gb_header.h:57
#define NULp
Definition: cxxforward.h:97
gb_data_list d
Definition: gb_data.h:246
int keycnt
Definition: gb_main.h:131
gb_header_flags flags
Definition: gb_header.h:35
static long write_IE(gb_if_entries *ie, FILE *out, long *offset)
Definition: admap.cxx:218
static size_t ftwrite_unaligned(const void *ptr, size_t unali_siz, FILE *fil)
Definition: admap.cxx:201
#define offset(field)
Definition: GLwDrawA.c:73
void release_main_idx()
Definition: ad_load.cxx:947
GB_REL_IFES * GB_INDEX_FILES_ENTRIES(gb_index_files *ifs)
Definition: gb_index.h:80
long hash_table_size
Definition: gb_index.h:50
int nheader
Definition: gb_data.h:102
long version
Definition: gb_map.h:24
#define GB_ENTRIES_ENTRY(entries, idx)
Definition: gb_index.h:64
GB_ERROR gb_save_mapfile(GB_MAIN_TYPE *Main, GB_CSTR path)
Definition: admap.cxx:587
GB_MAIN_IDX main_idx
Definition: gb_data.h:255
#define STATIC_ASSERT(const_expression)
Definition: static_assert.h:36
unsigned int header_changed
Definition: gb_data.h:85
const char * GB_CSTR
Definition: arbdb_base.h:25
GBDATA * gb_map_mapfile(const char *path)
Definition: admap.cxx:706
int GBQUARK
Definition: arbdb_base.h:30
GB_REL_IFS rel_ifs
Definition: gb_data.h:256
gbdata_offset * gbdoff
Definition: admap.cxx:36
GBCONTAINER * dummy_father
Definition: gb_main.h:119
int headermemsize
Definition: gb_data.h:100
unsigned int flags
Definition: gb_header.h:20