Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
/*
 * 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;
}