Example #1
0
LIBCOUCHSTORE_API
couchstore_error_t couchstore_close_db(Db *db)
{
    tree_file_close(&db->file);

    free(db->header.by_id_root);
    free(db->header.by_seq_root);
    free(db->header.local_docs_root);

    memset(db, 0xa5, sizeof(*db));
    free(db);

    return COUCHSTORE_SUCCESS;
}
Example #2
0
LIBCOUCHSTORE_API
couchstore_error_t couchstore_cleanup_view_group(view_group_info_t *info,
                                                 uint64_t *header_pos,
                                                 uint64_t *purge_count,
                                                 view_error_t *error_info)
{
    couchstore_error_t ret;
    tree_file index_file;
    index_header_t *header = NULL;
    node_pointer *id_root = NULL;
    node_pointer **view_roots = NULL;
    view_purger_ctx_t purge_ctx;
    bitmap_t bm_cleanup;
    int i;

    memset(&bm_cleanup, 0, sizeof(bm_cleanup));
    error_info->view_name = NULL;
    error_info->error_msg = NULL;
    index_file.handle = NULL;
    index_file.ops = NULL;
    index_file.path = NULL;

    view_roots = (node_pointer **) calloc(
        info->num_btrees, sizeof(node_pointer *));
    if (view_roots == NULL) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    /* Read info from current index viewgroup file */
    ret = open_view_group_file(info->filepath,
                               COUCHSTORE_OPEN_FLAG_RDONLY,
                               &info->file);
    if (ret != COUCHSTORE_SUCCESS) {
        goto cleanup;
    }

    ret = read_view_group_header(info, &header);
    if (ret != COUCHSTORE_SUCCESS) {
        goto cleanup;
    }
    assert(info->num_btrees == header->num_views);

    /* Setup purger context */
    purge_ctx.count = 0;
    purge_ctx.cbitmask = header->cleanup_bitmask;

    ret = open_view_group_file(info->filepath,
                               0,
                               &index_file);
    if (ret != COUCHSTORE_SUCCESS) {
        goto cleanup;
    }

    index_file.pos = index_file.ops->goto_eof(&index_file.lastError,
                                                         index_file.handle);

    /* Cleanup id_bree */
    ret = cleanup_id_btree(&index_file, header->id_btree_state, &id_root,
                                                                &purge_ctx,
                                                                error_info);
    if (ret != COUCHSTORE_SUCCESS) {
        goto cleanup;
    }

    free(header->id_btree_state);
    header->id_btree_state = id_root;
    view_id_bitmask(id_root, &bm_cleanup);
    id_root = NULL;

    /* Cleanup all view btrees */
    for (i = 0; i < info->num_btrees; ++i) {
        ret = cleanup_view_btree(&index_file,
                                 (node_pointer *) header->view_btree_states[i],
                                 &info->btree_infos[i],
                                 &view_roots[i],
                                 &purge_ctx,
                                 error_info);

        if (ret != COUCHSTORE_SUCCESS) {
            goto cleanup;
        }

        free(header->view_btree_states[i]);
        header->view_btree_states[i] = view_roots[i];
        view_bitmask(view_roots[i], &bm_cleanup);
        view_roots[i] = NULL;
    }

    /* Set resulting cleanup bitmask */
    /* TODO: This code can be removed, if we do not plan for cleanup STOP command */
    intersect_bitmaps(&bm_cleanup, &purge_ctx.cbitmask);
    header->cleanup_bitmask = bm_cleanup;

    /* Update header with new btree infos */
    ret = write_view_group_header(&index_file, header_pos, header);
    if (ret != COUCHSTORE_SUCCESS) {
        goto cleanup;
    }

    *purge_count = purge_ctx.count;
    ret = COUCHSTORE_SUCCESS;

cleanup:
    free_index_header(header);
    close_view_group_file(info);
    tree_file_close(&index_file);
    free(id_root);
    if (view_roots != NULL) {
        for (i = 0; i < info->num_btrees; ++i) {
            free(view_roots[i]);
        }
        free(view_roots);
    }

    return ret;
}
Example #3
0
LIBCOUCHSTORE_API
couchstore_error_t couchstore_build_view_group(view_group_info_t *info,
                                               const char *id_records_file,
                                               const char *kv_records_files[],
                                               const char *dst_file,
                                               uint64_t *header_pos,
                                               view_error_t *error_info)
{
    couchstore_error_t ret;
    tree_file index_file;
    index_header_t *header = NULL;
    node_pointer *id_root = NULL;
    node_pointer **view_roots = NULL;
    int i;

    error_info->view_name = NULL;
    error_info->error_msg = NULL;
    index_file.handle = NULL;
    index_file.ops = NULL;
    index_file.path = NULL;

    view_roots = (node_pointer **) calloc(
        info->num_btrees, sizeof(node_pointer *));
    if (view_roots == NULL) {
        return COUCHSTORE_ERROR_ALLOC_FAIL;
    }

    ret = open_view_group_file(info->filepath,
                               COUCHSTORE_OPEN_FLAG_RDONLY,
                               &info->file);
    if (ret != COUCHSTORE_SUCCESS) {
        goto out;
    }

    ret = read_view_group_header(info, &header);
    if (ret != COUCHSTORE_SUCCESS) {
        goto out;
    }
    assert(info->num_btrees == header->num_views);

    ret = open_view_group_file(dst_file,
                               COUCHSTORE_OPEN_FLAG_CREATE,
                               &index_file);
    if (ret != COUCHSTORE_SUCCESS) {
        goto out;
    }

    ret = build_id_btree(id_records_file, &index_file, &id_root);
    if (ret != COUCHSTORE_SUCCESS) {
        goto out;
    }

    free(header->id_btree_state);
    header->id_btree_state = id_root;
    id_root = NULL;

    for (i = 0; i < info->num_btrees; ++i) {
        ret = build_view_btree(kv_records_files[i],
                               &info->btree_infos[i],
                               &index_file,
                               &view_roots[i],
                               error_info);
        if (ret != COUCHSTORE_SUCCESS) {
            goto out;
        }

        free(header->view_btree_states[i]);
        header->view_btree_states[i] = view_roots[i];
        view_roots[i] = NULL;
    }

    ret = write_view_group_header(&index_file, header_pos, header);
    if (ret != COUCHSTORE_SUCCESS) {
        goto out;
    }

    ret = COUCHSTORE_SUCCESS;

out:
    free_index_header(header);
    close_view_group_file(info);
    tree_file_close(&index_file);
    free(id_root);
    if (view_roots != NULL) {
        for (i = 0; i < info->num_btrees; ++i) {
            free(view_roots[i]);
        }
        free(view_roots);
    }

    return ret;
}