/* * Simulate reading and writing to the old in-memory copy of the Index * array. * * We use a hash table instead and cache (or not, for now) records for * as long as needed. */ #define AUX_BLOCK_SZ 256 /* must be a power of two */ Index *g_read_index(GFile *gfile, GCardinal rec) { Index *idx, *idxr = NULL; HacheItem *hi; HacheData hd; AuxIndex aidx[AUX_BLOCK_SZ]; int toggle, nrecs, i; GCardinal r2; hi = HacheTableSearch(gfile->idx_hash, (char *)&rec, sizeof(rec)); if (hi) { return (Index *)hi->data.p; } r2 = rec & ~(AUX_BLOCK_SZ-1); /* LOW LEVEL IO HERE */ if (-1==gfile->low_level_vector[GOP_SEEK_AUX_INDEX](gfile->fdaux,NULL,r2)) return gerr_set(GERR_SEEK_ERROR), NULL; nrecs = g_read_aux_index(gfile, &aidx[0], AUX_BLOCK_SZ); if (nrecs <= 0) return gerr_set(GERR_READ_ERROR), NULL; for (i = 0; i < AUX_BLOCK_SZ; i++, r2++) { toggle = i < nrecs ? g_toggle_state(gfile->header.last_time, &aidx[i]) : G_NO_TOGGLE; hi = HacheTableSearch(gfile->idx_hash, (char *)&r2, sizeof(r2)); idx = hi ? (Index *)hi->data.p : (Index *)xcalloc(1, sizeof(*idx)); if (toggle != G_NO_TOGGLE) { idx->aux_allocated = aidx[i].used[toggle]; idx->aux_image = aidx[i].image[toggle]; idx->aux_time = aidx[i].time[toggle]; idx->aux_used = aidx[i].used[toggle]; if (idx->aux_image != G_NO_IMAGE) { idx->flags = G_INDEX_NONE; } } else { /* To be allocated later */ idx->aux_allocated = 0; idx->aux_image = 0; idx->aux_time = 0; idx->aux_used = 0; idx->flags = 0; } hd.p = idx; HacheTableAdd(gfile->idx_hash, (char *)&r2, sizeof(r2), hd, NULL); if (r2 == rec) idxr = idx; } assert(idxr); return idxr; }
/* * Dumps a G database in an ASCII readable form. Modelled around the start * of the g_open_file() routine. */ void g_dump_file(char *fn) { GFile *gfile = NULL; char fnaux[1024]; AuxIndex aux_ind; int i; #define ABORT(E)\ {\ g_free_gfile(gfile); \ gfile = NULL; \ (void)gerr_set(E); \ perror("ABORT"); \ return; \ } /* check file name isn't too long */ if (strlen(fn) + strlen(G_AUX_SUFFIX) >= sizeof(fnaux)) ABORT(GERR_NAME_TOO_LONG); strcpy(fnaux, fn); strcat(fnaux, G_AUX_SUFFIX); /* allocate new data structure - GFile */ gfile = g_new_gfile(); if (gfile == NULL) ABORT(GERR_OUT_OF_MEMORY); /* set file name */ if ((gfile->fname = (char *)xmalloc(strlen(fn)+1)) != NULL) strcpy(gfile->fname, fn); /* open file and its aux */ /* LOW LEVEL IO HERE */ if ((gfile->fd = open(fn, O_RDONLY)) == -1) ABORT(GERR_OPENING_FILE); /* LOW LEVEL IO HERE */ if ((gfile->fdaux = open(fnaux, O_RDONLY)) == -1) ABORT(GERR_OPENING_FILE); /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fdaux, 0, 0)) ABORT(GERR_SEEK_ERROR); if (g_read_aux_header(gfile->fdaux, &gfile->header)) ABORT(GERR_READ_ERROR); printf("** \n"); printf("** Opening file %s\n",fn); printf("** file_size = %"PRIGImage"\n", gfile->header.file_size); printf("** block_size = %"PRIGCardinal"\n", gfile->header.block_size); printf("** num_records = %"PRIGCardinal"\n", gfile->header.num_records); printf("** max_records = %"PRIGCardinal"\n", gfile->header.max_records); printf("** last_time = %"PRIGCardinal"\n", gfile->header.last_time); printf("** flags = %"PRIGHFlags"\n", gfile->header.flags); printf("** \n"); /* allocate index */ gfile->Nidx = gfile->header.num_records; if ((gfile->idx = ArrayCreate(sizeof(Index), gfile->Nidx)) == NULL ) ABORT(GERR_OUT_OF_MEMORY); (void) ArrayRef(gfile->idx, gfile->Nidx-1); for(i = 0; i < gfile->Nidx; i++) arr(Index, gfile->idx, i).flags = G_INDEX_NEW; /* read aux index and initialise */ /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fdaux, sizeof(AuxHeader), 0)) ABORT(GERR_SEEK_ERROR); /* force Array.max field to be updated */ (void)ArrayRef(gfile->idx, gfile->header.num_records-1); printf("global_time %08x\n", gfile->header.last_time); for (i = 0; i < gfile->header.num_records; i++) { char buf[MAX_BUF]; int toggle, len, len_r; /* Load index for this record */ if (g_read_aux_index(gfile->fdaux, &aux_ind)) ABORT(GERR_READ_ERROR); /* Compute toggle */ toggle = g_toggle_state(gfile->header.last_time, &aux_ind); /* LOW LEVEL IO HERE */ if (-1 == lseek(gfile->fd, aux_ind.image[toggle], 0)) ABORT(GERR_SEEK_ERROR); len = MIN(aux_ind.used[toggle], MAX_BUF); /* LOW LEVEL IO HERE */ if (-1 == (len_r = read(gfile->fd, buf, len))) ABORT(GERR_READ_ERROR); if (len_r != len) { fprintf(stderr, "WARNING: Read too short. Requested %d, got %d\n", len, len_r); } printf("record %05d pos %020"PRIGImage" len %08d : %08x", i, aux_ind.image[toggle], aux_ind.used[toggle], (((((buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3]); if (len > 4) printf(" %c%c%c%c%c%c%c%c\n", isprint(buf[4])?buf[4]:'.', isprint(buf[5])?buf[5]:'.', isprint(buf[6])?buf[6]:'.', isprint(buf[7])?buf[7]:'.', isprint(buf[8])?buf[8]:'.', isprint(buf[9])?buf[9]:'.', isprint(buf[10])?buf[10]:'.', isprint(buf[11])?buf[11]:'.'); else putchar('\n'); } #undef ABORT g_free_gfile(gfile); return; }