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; }
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; }
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; }