/* Get the current 'next-key' value and bump the record. */ static svn_error_t * get_key_and_bump(svn_fs_t *fs, const char **key, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBC *cursor; char next_key[MAX_KEY_SIZE]; apr_size_t key_len; int db_err; DBT query; DBT result; /* ### todo: see issue #409 for why bumping the key as part of this trail is problematic. */ /* Open a cursor and move it to the 'next-key' value. We can then fetch the contents and use the cursor to overwrite those contents. Since this database allows duplicates, we can't do an arbitrary 'put' to write the new value -- that would append, not overwrite. */ svn_fs_base__trail_debug(trail, "strings", "cursor"); SVN_ERR(BDB_WRAP(fs, N_("creating cursor for reading a string"), bfd->strings->cursor(bfd->strings, trail->db_txn, &cursor, 0))); /* Advance the cursor to 'next-key' and read it. */ db_err = svn_bdb_dbc_get(cursor, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__result_dbt(&result), DB_SET); if (db_err) { svn_bdb_dbc_close(cursor); return BDB_WRAP(fs, N_("getting next-key value"), db_err); } svn_fs_base__track_dbt(&result, pool); *key = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ key_len = result.size; svn_fs_base__next_key(result.data, &key_len, next_key); /* Shove the new key back into the database, at the cursor position. */ db_err = svn_bdb_dbc_put(cursor, &query, svn_fs_base__str_to_dbt(&result, next_key), DB_CURRENT); if (db_err) { svn_bdb_dbc_close(cursor); /* ignore the error, the original is more important. */ return BDB_WRAP(fs, N_("bumping next string key"), db_err); } return BDB_WRAP(fs, N_("closing string-reading cursor"), svn_bdb_dbc_close(cursor)); }
svn_error_t * svn_fs_bdb__write_new_rep(const char **key, svn_fs_t *fs, const representation_t *rep, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; int db_err; apr_size_t len; char next_key[MAX_KEY_SIZE]; /* ### todo: see issue #409 for why bumping the key as part of this trail is problematic. */ /* Get the current value associated with `next-key'. */ svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__trail_debug(trail, "representations", "get"); SVN_ERR(BDB_WRAP(fs, _("allocating new representation (getting next-key)"), bfd->representations->get (bfd->representations, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Store the new rep. */ *key = apr_pstrmemdup(pool, result.data, result.size); SVN_ERR(svn_fs_bdb__write_rep(fs, *key, rep, trail, pool)); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "representations", "put"); db_err = bfd->representations->put (bfd->representations, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); SVN_ERR(BDB_WRAP(fs, _("bumping next representation key"), db_err)); return SVN_NO_ERROR; }
svn_error_t * svn_fs_bdb__new_node_id(svn_fs_id_t **id_p, svn_fs_t *fs, const char *copy_id, const char *txn_id, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; const char *next_node_id; SVN_ERR_ASSERT(txn_id); /* Get the current value associated with the `next-key' key in the table. */ svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__trail_debug(trail, "nodes", "get"); SVN_ERR(BDB_WRAP(fs, N_("allocating new node ID (getting 'next-key')"), bfd->nodes->get(bfd->nodes, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Squirrel away our next node id value. */ next_node_id = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "nodes", "put"); db_err = bfd->nodes->put(bfd->nodes, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); SVN_ERR(BDB_WRAP(fs, N_("bumping next node ID key"), db_err)); /* Create and return the new node id. */ *id_p = svn_fs_base__id_create(next_node_id, copy_id, txn_id, pool); return SVN_NO_ERROR; }
svn_error_t *svn_fs_bdb__reserve_rep_reuse_id(const char **id_p, svn_fs_t *fs, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); /* Get the current value associated with the `next-key' key in the `checksum-reps' table. */ svn_fs_base__trail_debug(trail, "checksum-reps", "get"); SVN_ERR(BDB_WRAP(fs, _("allocating new representation reuse ID " "(getting 'next-key')"), bfd->checksum_reps->get(bfd->checksum_reps, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Set our return value. */ *id_p = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__trail_debug(trail, "checksum_reps", "put"); db_err = bfd->checksum_reps->put(bfd->checksum_reps, trail->db_txn, svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY), svn_fs_base__str_to_dbt(&result, next_key), 0); return BDB_WRAP(fs, _("bumping next copy key"), db_err); }
/* Allocate a Subversion transaction ID in FS, as part of TRAIL. Set *ID_P to the new transaction ID, allocated in POOL. */ static svn_error_t * allocate_txn_id(const char **id_p, svn_fs_t *fs, trail_t *trail, apr_pool_t *pool) { base_fs_data_t *bfd = fs->fsap_data; DBT query, result; apr_size_t len; char next_key[MAX_KEY_SIZE]; int db_err; svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); /* Get the current value associated with the `next-key' key in the table. */ svn_fs_base__trail_debug(trail, "transactions", "get"); SVN_ERR(BDB_WRAP(fs, "allocating new transaction ID (getting 'next-key')", bfd->transactions->get(bfd->transactions, trail->db_txn, &query, svn_fs_base__result_dbt(&result), 0))); svn_fs_base__track_dbt(&result, pool); /* Set our return value. */ *id_p = apr_pstrmemdup(pool, result.data, result.size); /* Bump to future key. */ len = result.size; svn_fs_base__next_key(result.data, &len, next_key); svn_fs_base__str_to_dbt(&query, NEXT_KEY_KEY); svn_fs_base__str_to_dbt(&result, next_key); svn_fs_base__trail_debug(trail, "transactions", "put"); db_err = bfd->transactions->put(bfd->transactions, trail->db_txn, &query, &result, 0); return BDB_WRAP(fs, "bumping next transaction key", db_err); }