示例#1
0
LIBCOUCHSTORE_API
view_group_info_t *couchstore_read_view_group_info(FILE *in_stream,
                                                   FILE *error_stream)
{
    view_group_info_t *info;
    char buf[4096];
    char *dup;
    int i, j;
    int reduce_len;

    info = (view_group_info_t *) calloc(1, sizeof(*info));
    if (info == NULL) {
        fprintf(error_stream, "Memory allocation failure\n");
        goto out_error;
    }

    if (couchstore_read_line(in_stream, buf, sizeof(buf)) != buf) {
        fprintf(stderr, "Error reading source index file path\n");
        goto out_error;
    }
    dup = strdup(buf);
    if (dup == NULL) {
        fprintf(error_stream, "Memory allocation failure\n");
        goto out_error;
    }
    info->filepath = (const char *) dup;

    if (fscanf(in_stream, "%" SCNu64 "\n", &info->header_pos) != 1) {
        fprintf(error_stream, "Error reading header position\n");
        goto out_error;
    }

    if (fscanf(in_stream, "%d\n", &info->num_btrees) != 1) {
        fprintf(error_stream, "Error reading number of btrees\n");
        goto out_error;
    }

    info->btree_infos = (view_btree_info_t *)
        calloc(info->num_btrees, sizeof(view_btree_info_t));
    if (info->btree_infos == NULL) {
        fprintf(error_stream, "Memory allocation failure\n");
        info->num_btrees = 0;
        goto out_error;
    }

    for (i = 0; i < info->num_btrees; ++i) {
        view_btree_info_t *bti = &info->btree_infos[i];

        if (fscanf(in_stream, "%d\n", &bti->num_reducers) != 1) {
            fprintf(error_stream,
                    "Error reading number of reducers for btree %d\n", i);
            goto out_error;
        }

        bti->names = (const char **) calloc(bti->num_reducers, sizeof(char *));
        if (bti->names == NULL) {
            fprintf(error_stream, "Memory allocation failure\n");
            bti->num_reducers = 0;
            goto out_error;
        }

        bti->reducers = (const char **) calloc(bti->num_reducers, sizeof(char *));
        if (bti->reducers == NULL) {
            fprintf(error_stream, "Memory allocation failure\n");
            bti->num_reducers = 0;
            free(bti->names);
            goto out_error;
        }

        for (j = 0; j < bti->num_reducers; ++j) {
            if (couchstore_read_line(in_stream, buf, sizeof(buf)) != buf) {
                fprintf(error_stream,
                        "Error reading btree %d view %d name\n", i, j);
                goto out_error;
            }
            dup = strdup(buf);
            if (dup == NULL) {
                fprintf(error_stream, "Memory allocation failure\n");
                goto out_error;
            }
            bti->names[j] = (const char *) dup;

            if (fscanf(in_stream, "%d\n", &reduce_len) != 1) {
                fprintf(error_stream,
                        "Error reading btree %d view %d "
                        "reduce function size\n", i, j);
                goto out_error;
            }

            dup = (char *) malloc(reduce_len + 1);
            if (dup == NULL) {
                fprintf(error_stream, "Memory allocation failure\n");
                goto out_error;
            }

            if (fread(dup, reduce_len, 1, in_stream) != 1) {
                fprintf(error_stream,
                        "Error reading btree %d view %d reducer\n", i, j);
                free(dup);
                goto out_error;
            }
            dup[reduce_len] = '\0';
            bti->reducers[j] = (const char *) dup;
        }
    }

    return info;

out_error:
    couchstore_free_view_group_info(info);

    return NULL;
}
int main(int argc, char *argv[])
{
    view_group_info_t *group_info = NULL;
    char buf[BUF_SIZE];
    char **source_files = NULL;
    char *dest_file = NULL;
    int i;
    size_t len;
    int ret = 2;
    uint64_t header_pos;
    view_error_t error_info;

    (void) argc;
    (void) argv;

    group_info = couchstore_read_view_group_info(stdin, stderr);
    if (group_info == NULL) {
        ret = COUCHSTORE_ERROR_ALLOC_FAIL;
        goto out;
    }

    source_files = (char **) calloc(group_info->num_btrees + 1, sizeof(char *));
    if (source_files == NULL) {
        fprintf(stderr, "Memory allocation failure\n");
        ret = COUCHSTORE_ERROR_ALLOC_FAIL;
        goto out;
    }

    if (couchstore_read_line(stdin, buf, BUF_SIZE) != buf) {
        fprintf(stderr, "Error reading destination file\n");
        ret = COUCHSTORE_ERROR_INVALID_ARGUMENTS;
        goto out;
    }
    len = strlen(buf);
    dest_file = (char *) malloc(len + 1);
    if (dest_file == NULL) {
        fprintf(stderr, "Memory allocation failure\n");
        ret = COUCHSTORE_ERROR_ALLOC_FAIL;
        goto out;
    }
    memcpy(dest_file, buf, len);
    dest_file[len] = '\0';

    for (i = 0; i <= group_info->num_btrees; ++i) {
        if (couchstore_read_line(stdin, buf, BUF_SIZE) != buf) {
            if (i == 0) {
                fprintf(stderr, "Error reading source file for id btree\n");
            } else {
                fprintf(stderr,
                        "Error reading source file for btree %d\n", i - 1);
            }
            ret = COUCHSTORE_ERROR_INVALID_ARGUMENTS;
            goto out;
        }

        len = strlen(buf);
        source_files[i] = (char *) malloc(len + 1);
        if (source_files[i] == NULL) {
            fprintf(stderr, "Memory allocation failure\n");
            ret = COUCHSTORE_ERROR_ALLOC_FAIL;
            goto out;
        }
        memcpy(source_files[i], buf, len);
        source_files[i][len] = '\0';
    }

    ret = couchstore_build_view_group(group_info,
                                      source_files[0],
                                      (const char **) &source_files[1],
                                      dest_file,
                                      &header_pos,
                                      &error_info);

    if (ret != COUCHSTORE_SUCCESS) {
        if (error_info.error_msg != NULL && error_info.view_name != NULL) {
            fprintf(stderr,
                    "Error building index for view `%s`, reason: %s\n",
                    error_info.view_name,
                    error_info.error_msg);
        }
        goto out;
    }

out:
    if (source_files != NULL) {
        for (i = 0; i <= group_info->num_btrees; ++i) {
            free(source_files[i]);
        }
        free(source_files);
    }
    free(dest_file);
    couchstore_free_view_group_info(group_info);
    free((void *) error_info.error_msg);
    free((void *) error_info.view_name);

    return (ret < 0) ? (100 + ret) : ret;
}