You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/07/24 15:24:44 UTC
svn commit: r1506545 [2/2] - in
/subversion/branches/fsfs-improvements/subversion: include/ libsvn_fs_fs/
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.c?rev=1506545&r1=1506544&r2=1506545&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.c Wed Jul 24 13:24:44 2013
@@ -36,7 +36,6 @@
#include "util.h"
#include "id.h"
#include "low_level.h"
-#include "key-gen.h"
#include "temp_serializer.h"
#include "cached_data.h"
#include "lock.h"
@@ -54,7 +53,7 @@
*/
static APR_INLINE const char *
path_txn_sha1(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
svn_checksum_t *sha1,
apr_pool_t *pool)
{
@@ -65,7 +64,7 @@ path_txn_sha1(svn_fs_t *fs,
static APR_INLINE const char *
path_txn_changes(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
@@ -74,7 +73,7 @@ path_txn_changes(svn_fs_t *fs,
static APR_INLINE const char *
path_txn_props(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
@@ -83,7 +82,7 @@ path_txn_props(svn_fs_t *fs,
static APR_INLINE const char *
path_txn_next_ids(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
@@ -127,14 +126,14 @@ static txn_vtable_t txn_vtable = {
typedef struct fs_txn_data_t
{
/* Strongly typed representation of the TXN's ID member. */
- const char *txn_id;
+ svn_fs_fs__id_part_t txn_id;
} fs_txn_data_t;
-const char *
+const svn_fs_fs__id_part_t *
svn_fs_fs__txn_get_id(svn_fs_txn_t *txn)
{
fs_txn_data_t *ftd = txn->fsap_data;
- return ftd->txn_id;
+ return &ftd->txn_id;
}
/* Functions for working with shared transaction data. */
@@ -146,7 +145,7 @@ svn_fs_fs__txn_get_id(svn_fs_txn_t *txn)
true) or return NULL (otherwise). */
static fs_fs_shared_txn_data_t *
get_shared_txn(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
svn_boolean_t create_new)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -154,7 +153,7 @@ get_shared_txn(svn_fs_t *fs,
fs_fs_shared_txn_data_t *txn;
for (txn = ffsd->txns; txn; txn = txn->next)
- if (svn_fs_fs__id_part_eq(txn->txn_id, txn_id))
+ if (svn_fs_fs__id_part_eq(&txn->txn_id, txn_id))
break;
if (txn || !create_new)
@@ -174,8 +173,7 @@ get_shared_txn(svn_fs_t *fs,
txn->pool = subpool;
}
- assert(strlen(txn_id) < sizeof(txn->txn_id));
- apr_cpystrn(txn->txn_id, txn_id, sizeof(txn->txn_id));
+ txn->txn_id = *txn_id;
txn->being_written = FALSE;
/* Link this transaction into the head of the list. We will typically
@@ -193,14 +191,14 @@ get_shared_txn(svn_fs_t *fs,
locked via the txn_list_lock mutex). Do nothing if the transaction
does not exist. */
static void
-free_shared_txn(svn_fs_t *fs, const char *txn_id)
+free_shared_txn(svn_fs_t *fs, const svn_fs_fs__id_part_t *txn_id)
{
fs_fs_data_t *ffd = fs->fsap_data;
fs_fs_shared_data_t *ffsd = ffd->shared;
fs_fs_shared_txn_data_t *txn, *prev = NULL;
for (txn = ffsd->txns; txn; prev = txn, txn = txn->next)
- if (svn_fs_fs__id_part_eq(txn->txn_id, txn_id))
+ if (svn_fs_fs__id_part_eq(&txn->txn_id, txn_id))
break;
if (!txn)
@@ -246,7 +244,7 @@ with_txnlist_lock(svn_fs_t *fs,
which see. */
struct unlock_proto_rev_baton
{
- const char *txn_id;
+ svn_fs_fs__id_part_t txn_id;
void *lockcookie;
};
@@ -256,7 +254,7 @@ unlock_proto_rev_body(svn_fs_t *fs, cons
{
const struct unlock_proto_rev_baton *b = baton;
apr_file_t *lockfile = b->lockcookie;
- fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, FALSE);
+ fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, FALSE);
apr_status_t apr_err;
if (!txn)
@@ -293,13 +291,13 @@ unlock_proto_rev_body(svn_fs_t *fs, cons
Perform temporary allocations in POOL. */
static svn_error_t *
unlock_proto_rev(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
void *lockcookie,
apr_pool_t *pool)
{
struct unlock_proto_rev_baton b;
- b.txn_id = txn_id;
+ b.txn_id = *txn_id;
b.lockcookie = lockcookie;
return with_txnlist_lock(fs, unlock_proto_rev_body, &b, pool);
}
@@ -308,13 +306,13 @@ unlock_proto_rev(svn_fs_t *fs,
lock is already held. */
static svn_error_t *
unlock_proto_rev_list_locked(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
void *lockcookie,
apr_pool_t *pool)
{
struct unlock_proto_rev_baton b;
- b.txn_id = txn_id;
+ b.txn_id = *txn_id;
b.lockcookie = lockcookie;
return unlock_proto_rev_body(fs, &b, pool);
}
@@ -325,7 +323,7 @@ struct get_writable_proto_rev_baton
{
apr_file_t **file;
void **lockcookie;
- const char *txn_id;
+ svn_fs_fs__id_part_t txn_id;
};
/* Callback used in the implementation of get_writable_proto_rev(). */
@@ -336,7 +334,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
apr_file_t **file = b->file;
void **lockcookie = b->lockcookie;
svn_error_t *err;
- fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, TRUE);
+ fs_fs_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, TRUE);
/* First, ensure that no thread in this process (including this one)
is currently writing to this transaction's proto-rev file. */
@@ -359,7 +357,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
apr_file_t *lockfile;
apr_status_t apr_err;
const char *lockfile_path
- = svn_fs_fs__path_txn_proto_rev_lock(fs, b->txn_id, pool);
+ = svn_fs_fs__path_txn_proto_rev_lock(fs, &b->txn_id, pool);
/* Open the proto-rev lockfile, creating it if necessary, as it may
not exist if the transaction dates from before the lockfiles were
@@ -400,7 +398,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
/* Now open the prototype revision file and seek to the end. */
err = svn_io_file_open(file,
- svn_fs_fs__path_txn_proto_rev(fs, b->txn_id, pool),
+ svn_fs_fs__path_txn_proto_rev(fs, &b->txn_id, pool),
APR_WRITE | APR_BUFFERED, APR_OS_DEFAULT, pool);
/* You might expect that we could dispense with the following seek
@@ -420,7 +418,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
{
err = svn_error_compose_create(
err,
- unlock_proto_rev_list_locked(fs, b->txn_id, *lockcookie, pool));
+ unlock_proto_rev_list_locked(fs, &b->txn_id, *lockcookie, pool));
*lockcookie = NULL;
}
@@ -442,14 +440,14 @@ static svn_error_t *
get_writable_proto_rev(apr_file_t **file,
void **lockcookie,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
struct get_writable_proto_rev_baton b;
b.file = file;
b.lockcookie = lockcookie;
- b.txn_id = txn_id;
+ b.txn_id = *txn_id;
return with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool);
}
@@ -458,7 +456,7 @@ get_writable_proto_rev(apr_file_t **file
static svn_error_t *
purge_shared_txn_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
{
- const char *txn_id = baton;
+ const svn_fs_fs__id_part_t *txn_id = baton;
free_shared_txn(fs, txn_id);
svn_fs_fs__reset_txn_caches(fs);
@@ -470,7 +468,7 @@ purge_shared_txn_body(svn_fs_t *fs, cons
Perform all allocations in POOL. */
static svn_error_t *
purge_shared_txn(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
return with_txnlist_lock(fs, purge_shared_txn_body, txn_id, pool);
@@ -819,7 +817,7 @@ process_changes(apr_hash_t *changed_path
svn_error_t *
svn_fs_fs__txn_changes_fetch(apr_hash_t **changed_paths_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
apr_file_t *file;
@@ -875,12 +873,12 @@ svn_fs_fs__paths_changed(apr_hash_t **ch
Allocations are from POOL. */
static svn_error_t *
create_new_txn_noderev_from_rev(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
svn_fs_id_t *src,
apr_pool_t *pool)
{
node_revision_t *noderev;
- const char *node_id, *copy_id;
+ const svn_fs_fs__id_part_t *node_id, *copy_id;
SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, src, pool));
@@ -905,7 +903,7 @@ create_new_txn_noderev_from_rev(svn_fs_t
/* A structure used by get_and_increment_txn_key_body(). */
struct get_and_increment_txn_key_baton {
svn_fs_t *fs;
- char *txn_id;
+ apr_uint64_t txn_number;
apr_pool_t *pool;
};
@@ -918,36 +916,29 @@ get_and_increment_txn_key_body(void *bat
struct get_and_increment_txn_key_baton *cb = baton;
const char *txn_current_filename
= svn_fs_fs__path_txn_current(cb->fs, pool);
- char next_txn_id[MAX_KEY_SIZE+3];
- apr_size_t len;
+ char new_id_str[SVN_INT64_BUFFER_SIZE];
svn_stringbuf_t *buf;
SVN_ERR(svn_fs_fs__read_content(&buf, txn_current_filename, cb->pool));
/* remove trailing newlines */
- svn_stringbuf_strip_whitespace(buf);
- cb->txn_id = buf->data;
- len = buf->len;
+ cb->txn_number = svn__base36toui64(NULL, buf->data);
/* Increment the key and add a trailing \n to the string so the
txn-current file has a newline in it. */
- svn_fs_fs__next_key(cb->txn_id, &len, next_txn_id);
- next_txn_id[len] = '\n';
- ++len;
- next_txn_id[len] = '\0';
-
- SVN_ERR(svn_io_write_atomic(txn_current_filename, next_txn_id, len,
+ SVN_ERR(svn_io_write_atomic(txn_current_filename, new_id_str,
+ svn__ui64tobase36(new_id_str, cb->txn_number+1),
txn_current_filename /* copy_perms path */, pool));
return SVN_NO_ERROR;
}
-/* Create a unique directory for a transaction in FS based on revision
- REV. Return the ID for this transaction in *ID_P. Use a sequence
+/* Create a unique directory for a transaction in FS based on revision REV.
+ Return the ID for this transaction in *ID_P and *TXN_ID. Use a sequence
value in the transaction ID to prevent reuse of transaction IDs. */
static svn_error_t *
create_txn_dir(const char **id_p,
- const char **txn_id,
+ svn_fs_fs__id_part_t *txn_id,
svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *pool)
@@ -965,9 +956,10 @@ create_txn_dir(const char **id_p,
get_and_increment_txn_key_body,
&cb,
pool));
- *id_p = apr_psprintf(pool, "%ld-%s", rev, cb.txn_id);
+ txn_id->revision = rev;
+ txn_id->number = cb.txn_number;
- *txn_id = *id_p;
+ *id_p = svn_fs_fs__id_txn_unparse(txn_id, pool);
txn_dir = svn_dirent_join_many(pool,
fs->path,
PATH_TXNS_DIR,
@@ -986,7 +978,7 @@ create_txn_dir(const char **id_p,
transaction IDs are possible with this implementation. */
static svn_error_t *
create_txn_dir_pre_1_5(const char **id_p,
- const char **txn_id,
+ svn_fs_fs__id_part_t *txn_id,
svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *pool)
@@ -1013,7 +1005,7 @@ create_txn_dir_pre_1_5(const char **id_p
const char *name = svn_dirent_basename(unique_path, subpool);
*id_p = apr_pstrndup(pool, name,
strlen(name) - strlen(PATH_EXT_TXN));
- *txn_id = *id_p;
+ SVN_ERR(svn_fs_fs__id_txn_parse(txn_id, *id_p));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
@@ -1059,24 +1051,24 @@ svn_fs_fs__create_txn(svn_fs_txn_t **txn
/* Create a new root node for this transaction. */
SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, rev, pool));
- SVN_ERR(create_new_txn_noderev_from_rev(fs, ftd->txn_id, root_id, pool));
+ SVN_ERR(create_new_txn_noderev_from_rev(fs, &ftd->txn_id, root_id, pool));
/* Create an empty rev file. */
SVN_ERR(svn_io_file_create_empty(
- svn_fs_fs__path_txn_proto_rev(fs, ftd->txn_id, pool),
+ svn_fs_fs__path_txn_proto_rev(fs, &ftd->txn_id, pool),
pool));
/* Create an empty rev-lock file. */
SVN_ERR(svn_io_file_create_empty(
- svn_fs_fs__path_txn_proto_rev_lock(fs, ftd->txn_id, pool),
+ svn_fs_fs__path_txn_proto_rev_lock(fs, &ftd->txn_id, pool),
pool));
/* Create an empty changes file. */
- SVN_ERR(svn_io_file_create_empty(path_txn_changes(fs, ftd->txn_id, pool),
+ SVN_ERR(svn_io_file_create_empty(path_txn_changes(fs, &ftd->txn_id, pool),
pool));
/* Create the next-ids file. */
- return svn_io_file_create(path_txn_next_ids(fs, ftd->txn_id, pool),
+ return svn_io_file_create(path_txn_next_ids(fs, &ftd->txn_id, pool),
"0 0\n", pool);
}
@@ -1085,14 +1077,14 @@ svn_fs_fs__create_txn(svn_fs_txn_t **txn
static svn_error_t *
get_txn_proplist(apr_hash_t *proplist,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
svn_stream_t *stream;
/* Check for issue #3696. (When we find and fix the cause, we can change
* this to an assertion.) */
- if (!txn_id || !svn_fs_fs__id_txn_used(&txn_id))
+ if (!txn_id || !svn_fs_fs__id_txn_used(txn_id))
return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("Internal error: a null transaction id was "
"passed to get_txn_proplist()"));
@@ -1135,7 +1127,7 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
int i;
svn_error_t *err;
- err = get_txn_proplist(txn_prop, txn->fs, ftd->txn_id, pool);
+ err = get_txn_proplist(txn_prop, txn->fs, &ftd->txn_id, pool);
/* Here - and here only - we need to deal with the possibility that the
transaction property file doesn't yet exist. The rest of the
implementation assumes that the file exists, but we're called to set the
@@ -1158,7 +1150,7 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
stream = svn_stream_from_stringbuf(buf, pool);
SVN_ERR(svn_hash_write2(txn_prop, stream, SVN_HASH_TERMINATOR, pool));
SVN_ERR(svn_stream_close(stream));
- SVN_ERR(svn_io_write_atomic(path_txn_props(txn->fs, ftd->txn_id, pool),
+ SVN_ERR(svn_io_write_atomic(path_txn_props(txn->fs, &ftd->txn_id, pool),
buf->data, buf->len,
NULL /* copy_perms_path */, pool));
return SVN_NO_ERROR;
@@ -1167,7 +1159,7 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
svn_error_t *
svn_fs_fs__get_txn(transaction_t **txn_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
transaction_t *txn;
@@ -1198,23 +1190,26 @@ svn_fs_fs__get_txn(transaction_t **txn_p
POOL. */
static svn_error_t *
write_next_ids(svn_fs_t *fs,
- const char *txn_id,
- const char *node_id,
- const char *copy_id,
+ const svn_fs_fs__id_part_t *txn_id,
+ apr_uint64_t node_id,
+ apr_uint64_t copy_id,
apr_pool_t *pool)
{
apr_file_t *file;
- svn_stream_t *out_stream;
+ char buffer[2 * SVN_INT64_BUFFER_SIZE + 2];
+ char *p = buffer;
+
+ p += svn__ui64tobase36(p, node_id);
+ *(p++) = ' ';
+ p += svn__ui64tobase36(p, copy_id);
+ *(p++) = '\n';
+ *(p++) = '\0';
- SVN_ERR(svn_io_file_open(&file, path_txn_next_ids(fs, txn_id, pool),
+ SVN_ERR(svn_io_file_open(&file,
+ path_txn_next_ids(fs, txn_id, pool),
APR_WRITE | APR_TRUNCATE,
APR_OS_DEFAULT, pool));
-
- out_stream = svn_stream_from_aprfile2(file, TRUE, pool);
-
- SVN_ERR(svn_stream_printf(out_stream, pool, "%s %s\n", node_id, copy_id));
-
- SVN_ERR(svn_stream_close(out_stream));
+ SVN_ERR(svn_io_file_write_full(file, buffer, p - buffer, NULL, pool));
return svn_io_file_close(file, pool);
}
@@ -1224,36 +1219,31 @@ write_next_ids(svn_fs_t *fs,
nodes for the given transaction, as well as uniquifying representations.
Perform all allocations in POOL. */
static svn_error_t *
-read_next_ids(const char **node_id,
- const char **copy_id,
+read_next_ids(apr_uint64_t *node_id,
+ apr_uint64_t *copy_id,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
svn_stringbuf_t *buf;
const char *str;
- char *last_str;
SVN_ERR(svn_fs_fs__read_content(&buf,
path_txn_next_ids(fs, txn_id, pool),
pool));
/* Parse this into two separate strings. */
- last_str = buf->data;
- str = svn_cstring_tokenize(" ", &last_str);
- if (! str)
+ str = buf->data;
+ *node_id = svn__base36toui64(&str, str);
+ if (*str != ' ')
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("next-id file corrupt"));
- *node_id = apr_pstrdup(pool, str);
-
- str = svn_cstring_tokenize(" \n", &last_str);
- if (! str)
+ *copy_id = svn__base36toui64(&str, ++str);
+ if (*str != '\n')
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("next-id file corrupt"));
- *copy_id = apr_pstrdup(pool, str);
-
return SVN_NO_ERROR;
}
@@ -1262,51 +1252,41 @@ read_next_ids(const char **node_id,
Node-ids are guaranteed to be unique to this transction, but may
not necessarily be sequential. Perform all allocations in POOL. */
static svn_error_t *
-get_new_txn_node_id(const char **node_id_p,
+get_new_txn_node_id(svn_fs_fs__id_part_t *node_id_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
- const char *cur_node_id, *cur_copy_id;
- char *node_id;
- apr_size_t len;
+ apr_uint64_t node_id, copy_id;
/* First read in the current next-ids file. */
- SVN_ERR(read_next_ids(&cur_node_id, &cur_copy_id, fs, txn_id, pool));
+ SVN_ERR(read_next_ids(&node_id, ©_id, fs, txn_id, pool));
- node_id = apr_pcalloc(pool, strlen(cur_node_id) + 2);
+ node_id_p->revision = SVN_INVALID_REVNUM;
+ node_id_p->number = node_id;
- len = strlen(cur_node_id);
- svn_fs_fs__next_key(cur_node_id, &len, node_id);
-
- SVN_ERR(write_next_ids(fs, txn_id, node_id, cur_copy_id, pool));
-
- *node_id_p = apr_pstrcat(pool, "_", cur_node_id, (char *)NULL);
+ SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
return SVN_NO_ERROR;
}
svn_error_t *
-svn_fs_fs__reserve_copy_id(const char **copy_id_p,
+svn_fs_fs__reserve_copy_id(svn_fs_fs__id_part_t *copy_id_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
- const char *cur_node_id, *cur_copy_id;
- char *copy_id;
- apr_size_t len;
+ apr_uint64_t node_id, copy_id;
/* First read in the current next-ids file. */
- SVN_ERR(read_next_ids(&cur_node_id, &cur_copy_id, fs, txn_id, pool));
-
- copy_id = apr_pcalloc(pool, strlen(cur_copy_id) + 2);
+ SVN_ERR(read_next_ids(&node_id, ©_id, fs, txn_id, pool));
- len = strlen(cur_copy_id);
- svn_fs_fs__next_key(cur_copy_id, &len, copy_id);
+ /* this is an in-txn ID now */
+ copy_id_p->revision = SVN_INVALID_REVNUM;
+ copy_id_p->number = copy_id;
- SVN_ERR(write_next_ids(fs, txn_id, cur_node_id, copy_id, pool));
-
- *copy_id_p = apr_pstrcat(pool, "_", cur_copy_id, (char *)NULL);
+ /* Update the ID counter file */
+ SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
return SVN_NO_ERROR;
}
@@ -1315,17 +1295,17 @@ svn_error_t *
svn_fs_fs__create_node(const svn_fs_id_t **id_p,
svn_fs_t *fs,
node_revision_t *noderev,
- const char *copy_id,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *copy_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
- const char *node_id;
+ svn_fs_fs__id_part_t node_id;
const svn_fs_id_t *id;
/* Get a new node-id for this node. */
SVN_ERR(get_new_txn_node_id(&node_id, fs, txn_id, pool));
- id = svn_fs_fs__id_txn_create(node_id, copy_id, txn_id, pool);
+ id = svn_fs_fs__id_txn_create(&node_id, copy_id, txn_id, pool);
noderev->id = id;
@@ -1338,15 +1318,17 @@ svn_fs_fs__create_node(const svn_fs_id_t
svn_error_t *
svn_fs_fs__purge_txn(svn_fs_t *fs,
- const char *txn_id,
+ const char *txn_id_str,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
+ svn_fs_fs__id_part_t txn_id;
+ SVN_ERR(svn_fs_fs__id_txn_parse(&txn_id, txn_id_str));
/* Remove the shared transaction object associated with this transaction. */
- SVN_ERR(purge_shared_txn(fs, txn_id, pool));
+ SVN_ERR(purge_shared_txn(fs, &txn_id, pool));
/* Remove the directory associated with this transaction. */
- SVN_ERR(svn_io_remove_dir2(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
+ SVN_ERR(svn_io_remove_dir2(svn_fs_fs__path_txn_dir(fs, &txn_id, pool),
FALSE, NULL, NULL, pool));
if (ffd->format >= SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
{
@@ -1355,10 +1337,10 @@ svn_fs_fs__purge_txn(svn_fs_t *fs,
is post-commit and the proto-rev has been moved into
place). */
SVN_ERR(svn_io_remove_file2(
- svn_fs_fs__path_txn_proto_rev(fs, txn_id, pool),
+ svn_fs_fs__path_txn_proto_rev(fs, &txn_id, pool),
TRUE, pool));
SVN_ERR(svn_io_remove_file2(
- svn_fs_fs__path_txn_proto_rev_lock(fs, txn_id, pool),
+ svn_fs_fs__path_txn_proto_rev_lock(fs, &txn_id, pool),
TRUE, pool));
}
return SVN_NO_ERROR;
@@ -1387,11 +1369,14 @@ set_uniquifier(svn_fs_t *fs,
representation_t *rep,
apr_pool_t *pool)
{
- const char *buffer;
+ svn_fs_fs__id_part_t temp;
+ char buffer[SVN_INT64_BUFFER_SIZE];
+
+ SVN_ERR(get_new_txn_node_id(&temp, fs, &rep->txn_id, pool));
+ svn__ui64tobase36(buffer, temp.number);
- SVN_ERR(get_new_txn_node_id(&buffer, fs, rep->txn_id, pool));
rep->uniquifier
- = apr_psprintf(pool, "%s/%s",
+ = apr_psprintf(pool, "%s/_%s",
svn_fs_fs__id_txn_unparse(&rep->txn_id, pool),
buffer);
@@ -1416,7 +1401,7 @@ reset_txn_in_rep(representation_t *rep)
svn_error_t *
svn_fs_fs__set_entry(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
node_revision_t *parent_noderev,
const char *name,
const svn_fs_id_t *id,
@@ -1451,7 +1436,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
/* Mark the node-rev's data rep as mutable. */
rep = apr_pcalloc(pool, sizeof(*rep));
rep->revision = SVN_INVALID_REVNUM;
- rep->txn_id = txn_id;
+ rep->txn_id = *txn_id;
SVN_ERR(set_uniquifier(fs, rep, pool));
parent_noderev->data_rep = rep;
SVN_ERR(svn_fs_fs__put_node_revision(fs, parent_noderev->id,
@@ -1514,7 +1499,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
svn_error_t *
svn_fs_fs__add_change(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
const char *path,
const svn_fs_id_t *id,
svn_fs_path_change_kind_t change_kind,
@@ -1907,7 +1892,7 @@ get_shared_rep(representation_t **old_re
{
svn_node_kind_t kind;
const char *file_name
- = path_txn_sha1(fs, rep->txn_id, rep->sha1_checksum, pool);
+ = path_txn_sha1(fs, &rep->txn_id, rep->sha1_checksum, pool);
/* in our txn, is there a rep file named with the wanted SHA1?
If so, read it and use that rep.
@@ -1957,7 +1942,7 @@ rep_write_contents_close(void *baton)
/* Fill in the rest of the representation field. */
rep->expanded_size = b->rep_size;
- rep->txn_id = svn_fs_fs__id_txn_id(b->noderev->id);
+ rep->txn_id = *svn_fs_fs__id_txn_id(b->noderev->id);
SVN_ERR(set_uniquifier(b->fs, rep, b->pool));
rep->revision = SVN_INVALID_REVNUM;
@@ -1997,7 +1982,7 @@ rep_write_contents_close(void *baton)
SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->pool));
SVN_ERR(svn_io_file_close(b->file, b->pool));
- SVN_ERR(unlock_proto_rev(b->fs, rep->txn_id, b->lockcookie, b->pool));
+ SVN_ERR(unlock_proto_rev(b->fs, &rep->txn_id, b->lockcookie, b->pool));
svn_pool_destroy(b->pool);
return SVN_NO_ERROR;
@@ -2048,8 +2033,8 @@ svn_fs_fs__create_successor(const svn_fs
svn_fs_t *fs,
const svn_fs_id_t *old_idp,
node_revision_t *new_noderev,
- const char *copy_id,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *copy_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
const svn_fs_id_t *id;
@@ -2099,7 +2084,7 @@ svn_fs_fs__set_proplist(svn_fs_t *fs,
if (!noderev->prop_rep || !is_txn_rep(noderev->prop_rep))
{
noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
- noderev->prop_rep->txn_id = svn_fs_fs__id_txn_id(noderev->id);
+ noderev->prop_rep->txn_id = *svn_fs_fs__id_txn_id(noderev->id);
SVN_ERR(svn_fs_fs__put_node_revision(fs, noderev->id, noderev, FALSE,
pool));
}
@@ -2111,8 +2096,8 @@ svn_fs_fs__set_proplist(svn_fs_t *fs,
available node id in *NODE_ID, and the next available copy id in
*COPY_ID. Allocations are performed from POOL. */
static svn_error_t *
-get_next_revision_ids(const char **node_id,
- const char **copy_id,
+get_next_revision_ids(apr_uint64_t *node_id,
+ apr_uint64_t *copy_id,
svn_fs_t *fs,
apr_pool_t *pool)
{
@@ -2135,14 +2120,14 @@ get_next_revision_ids(const char **node_
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Corrupt 'current' file"));
- *node_id = apr_pstrdup(pool, str);
+ *node_id = svn__base36toui64(NULL, str);
str = svn_cstring_tokenize(" \n", &buf);
if (! str)
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Corrupt 'current' file"));
- *copy_id = apr_pstrdup(pool, str);
+ *copy_id = svn__base36toui64(NULL, str);
return SVN_NO_ERROR;
}
@@ -2416,21 +2401,21 @@ validate_root_noderev(svn_fs_t *fs,
* revision. Use the repo FORMAT to decide which implementation to use.
*/
static void
-get_final_id(const char **part,
+get_final_id(svn_fs_fs__id_part_t *part,
svn_revnum_t revision,
- const char *start_id,
- int format,
- apr_pool_t *pool)
+ apr_uint64_t start_id,
+ int format)
{
- if (**part == '_')
+ if (part->revision == SVN_INVALID_REVNUM)
{
if (format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
- *part = apr_psprintf(pool, "%s-%ld", *part + 1, revision);
+ {
+ part->revision = revision;
+ }
else
{
- char buf[MAX_KEY_SIZE + 2];
- svn_fs_fs__add_keys(start_id, *part + 1, buf);
- *part = apr_pstrdup(pool, buf);
+ part->revision = 0;
+ part->number += start_id;
}
}
}
@@ -2467,8 +2452,8 @@ write_final_rev(const svn_fs_id_t **new_
svn_revnum_t rev,
svn_fs_t *fs,
const svn_fs_id_t *id,
- const char *start_node_id,
- const char *start_copy_id,
+ apr_uint64_t start_node_id,
+ apr_uint64_t start_copy_id,
apr_off_t initial_offset,
apr_array_header_t *reps_to_cache,
apr_hash_t *reps_hash,
@@ -2479,7 +2464,7 @@ write_final_rev(const svn_fs_id_t **new_
node_revision_t *noderev;
apr_off_t my_offset;
const svn_fs_id_t *new_id;
- const char *node_id, *copy_id;
+ svn_fs_fs__id_part_t node_id, copy_id, rev_offset;
fs_fs_data_t *ffd = fs->fsap_data;
*new_id_p = NULL;
@@ -2578,17 +2563,19 @@ write_final_rev(const svn_fs_id_t **new_
}
/* Convert our temporary ID into a permanent revision one. */
- SVN_ERR(svn_fs_fs__get_file_offset(&my_offset, file, pool));
-
- node_id = svn_fs_fs__id_node_id(noderev->id);
- get_final_id(&node_id, rev, start_node_id, ffd->format, pool);
- copy_id = svn_fs_fs__id_copy_id(noderev->id);
- get_final_id(©_id, rev, start_copy_id, ffd->format, pool);
+ node_id = *svn_fs_fs__id_node_id(noderev->id);
+ get_final_id(&node_id, rev, start_node_id, ffd->format);
+ copy_id = *svn_fs_fs__id_copy_id(noderev->id);
+ get_final_id(©_id, rev, start_copy_id, ffd->format);
if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
noderev->copyroot_rev = rev;
- new_id = svn_fs_fs__id_rev_create(node_id, copy_id, rev, my_offset, pool);
+ SVN_ERR(svn_fs_fs__get_file_offset(&my_offset, file, pool));
+ rev_offset.number = my_offset;
+
+ rev_offset.revision = rev;
+ new_id = svn_fs_fs__id_rev_create(&node_id, ©_id, &rev_offset, pool);
noderev->id = new_id;
@@ -2653,7 +2640,7 @@ static svn_error_t *
write_final_changed_path_info(apr_off_t *offset_p,
apr_file_t *file,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
apr_hash_t *changed_paths;
@@ -2721,28 +2708,28 @@ verify_as_revision_before_current_plus_p
set to REV. Perform temporary allocations in POOL. */
static svn_error_t *
write_final_current(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
svn_revnum_t rev,
- const char *start_node_id,
- const char *start_copy_id,
+ apr_uint64_t start_node_id,
+ apr_uint64_t start_copy_id,
apr_pool_t *pool)
{
- const char *txn_node_id, *txn_copy_id;
- char new_node_id[MAX_KEY_SIZE + 2];
- char new_copy_id[MAX_KEY_SIZE + 2];
+ apr_uint64_t txn_node_id;
+ apr_uint64_t txn_copy_id;
fs_fs_data_t *ffd = fs->fsap_data;
if (ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
- return svn_fs_fs__write_current(fs, rev, NULL, NULL, pool);
+ return svn_fs_fs__write_current(fs, rev, 0, 0, pool);
/* To find the next available ids, we add the id that used to be in
the 'current' file, to the next ids from the transaction file. */
SVN_ERR(read_next_ids(&txn_node_id, &txn_copy_id, fs, txn_id, pool));
- svn_fs_fs__add_keys(start_node_id, txn_node_id, new_node_id);
- svn_fs_fs__add_keys(start_copy_id, txn_copy_id, new_copy_id);
+ start_node_id += txn_node_id;
+ start_copy_id += txn_copy_id;
- return svn_fs_fs__write_current(fs, rev, new_node_id, new_copy_id, pool);
+ return svn_fs_fs__write_current(fs, rev, start_node_id, start_copy_id,
+ pool);
}
/* Verify that the user registed with FS has all the locks necessary to
@@ -2750,7 +2737,7 @@ write_final_current(svn_fs_t *fs,
The FS write lock is assumed to be held by the caller. */
static svn_error_t *
verify_locks(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
@@ -2842,7 +2829,8 @@ commit_body(void *baton, apr_pool_t *poo
const char *old_rev_filename, *rev_filename, *proto_filename;
const char *revprop_filename, *final_revprop;
const svn_fs_id_t *root_id, *new_root_id;
- const char *start_node_id = NULL, *start_copy_id = NULL;
+ apr_uint64_t start_node_id = 0;
+ apr_uint64_t start_copy_id = 0;
svn_revnum_t old_rev, new_rev;
apr_file_t *proto_file;
void *proto_file_lockcookie;
@@ -2850,7 +2838,7 @@ commit_body(void *baton, apr_pool_t *poo
apr_hash_t *txnprops;
apr_array_header_t *txnprop_list;
svn_prop_t prop;
- const char *txn_id = svn_fs_fs__txn_get_id(cb->txn);
+ const svn_fs_fs__id_part_t *txn_id = svn_fs_fs__txn_get_id(cb->txn);
svn_stringbuf_t *trailer;
/* Get the current youngest revision. */
@@ -3143,12 +3131,12 @@ svn_fs_fs__open_txn(svn_fs_txn_t **txn_p
fs_txn_data_t *ftd;
svn_node_kind_t kind;
transaction_t *local_txn;
- const char *txn_id;
+ svn_fs_fs__id_part_t txn_id;
- txn_id = name;
+ SVN_ERR(svn_fs_fs__id_txn_parse(&txn_id, name));
/* First check to see if the directory exists. */
- SVN_ERR(svn_io_check_path(svn_fs_fs__path_txn_dir(fs, txn_id, pool),
+ SVN_ERR(svn_io_check_path(svn_fs_fs__path_txn_dir(fs, &txn_id, pool),
&kind, pool));
/* Did we find it? */
@@ -3165,7 +3153,7 @@ svn_fs_fs__open_txn(svn_fs_txn_t **txn_p
txn->id = apr_pstrdup(pool, name);
txn->fs = fs;
- SVN_ERR(svn_fs_fs__get_txn(&local_txn, fs, txn_id, pool));
+ SVN_ERR(svn_fs_fs__get_txn(&local_txn, fs, &txn_id, pool));
txn->base_rev = svn_fs_fs__id_rev(local_txn->base_id);
@@ -3233,7 +3221,7 @@ svn_error_t *
svn_fs_fs__get_txn_ids(const svn_fs_id_t **root_id_p,
const svn_fs_id_t **base_root_id_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
transaction_t *txn;
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.h?rev=1506545&r1=1506544&r2=1506545&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.h (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/transaction.h Wed Jul 24 13:24:44 2013
@@ -27,7 +27,7 @@
/* Return the transaction ID of TXN.
*/
-const char *
+const svn_fs_fs__id_part_t *
svn_fs_fs__txn_get_id(svn_fs_txn_t *txn);
/* Store NODEREV as the node-revision for the node whose id is ID in
@@ -46,7 +46,7 @@ svn_fs_fs__put_node_revision(svn_fs_t *f
svn_error_t *
svn_fs_fs__txn_changes_fetch(apr_hash_t **changed_paths_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Find the paths which were changed in revision REV of filesystem FS
@@ -88,15 +88,15 @@ svn_fs_fs__change_txn_props(svn_fs_txn_t
svn_error_t *
svn_fs_fs__get_txn(transaction_t **txn_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Return the next available copy_id in *COPY_ID for the transaction
TXN_ID in filesystem FS. Allocate space in POOL. */
svn_error_t *
-svn_fs_fs__reserve_copy_id(const char **copy_id,
+svn_fs_fs__reserve_copy_id(svn_fs_fs__id_part_t *copy_id_p,
svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Create an entirely new mutable node in the filesystem FS, whose
@@ -108,8 +108,8 @@ svn_error_t *
svn_fs_fs__create_node(const svn_fs_id_t **id_p,
svn_fs_t *fs,
node_revision_t *noderev,
- const char *copy_id,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *copy_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Remove all references to the transaction TXN_ID from filesystem FS.
@@ -130,7 +130,7 @@ svn_fs_fs__abort_txn(svn_fs_txn_t *txn,
KIND. Allocations are done in POOL. */
svn_error_t *
svn_fs_fs__set_entry(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
node_revision_t *parent_noderev,
const char *name,
const svn_fs_id_t *id,
@@ -147,7 +147,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
from POOL. */
svn_error_t *
svn_fs_fs__add_change(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
const char *path,
const svn_fs_id_t *id,
svn_fs_path_change_kind_t change_kind,
@@ -186,8 +186,8 @@ svn_fs_fs__create_successor(const svn_fs
svn_fs_t *fs,
const svn_fs_id_t *old_idp,
node_revision_t *new_noderev,
- const char *copy_id,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *copy_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Write a new property list PROPLIST for node-revision NODEREV in
@@ -259,7 +259,7 @@ svn_error_t *
svn_fs_fs__get_txn_ids(const svn_fs_id_t **root_id_p,
const svn_fs_id_t **base_root_id_p,
svn_fs_t *fs,
- const char *txn_name,
+ const svn_fs_fs__id_part_t *txn_name,
apr_pool_t *pool);
/* Find the value of the property named PROPNAME in transaction TXN.
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/tree.c?rev=1506545&r1=1506544&r2=1506545&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/tree.c Wed Jul 24 13:24:44 2013
@@ -51,7 +51,6 @@
#include "svn_props.h"
#include "fs.h"
-#include "key-gen.h"
#include "cached_data.h"
#include "dag.h"
#include "lock.h"
@@ -106,8 +105,9 @@ typedef dag_node_t fs_rev_root_data_t;
typedef struct fs_txn_root_data_t
{
- const char *txn_id;
-
+ /* TXN_ID value from the main struct but as a struct instead of a string */
+ svn_fs_fs__id_part_t txn_id;
+
/* Cache of txn DAG nodes (without their nested noderevs, because
* it's mutable). Same keys/values as ffd->rev_node_cache. */
svn_cache__t *txn_node_cache;
@@ -126,7 +126,7 @@ static svn_fs_root_t *make_revision_root
static svn_error_t *make_txn_root(svn_fs_root_t **root_p,
svn_fs_t *fs,
- const char *txn,
+ const svn_fs_fs__id_part_t *txn,
svn_revnum_t base_rev,
apr_uint32_t flags,
apr_pool_t *pool);
@@ -654,13 +654,13 @@ svn_fs_fs__revision_root(svn_fs_root_t *
/* Getting dag nodes for roots. */
/* Return the transaction ID to a given transaction ROOT. */
-static const char *
+static const svn_fs_fs__id_part_t *
root_txn_id(svn_fs_root_t *root)
{
fs_txn_root_data_t *frd = root->fsap_data;
assert(root->is_txn_root);
- return frd->txn_id;
+ return &frd->txn_id;
}
/* Set *NODE_P to a freshly opened dag node referring to the root
@@ -798,7 +798,7 @@ get_copy_inheritance(copy_id_inherit_t *
apr_pool_t *pool)
{
const svn_fs_id_t *child_id, *parent_id, *copyroot_id;
- const char *child_copy_id, *parent_copy_id;
+ const svn_fs_fs__id_part_t *child_copy_id, *parent_copy_id;
const char *id_path = NULL;
svn_fs_root_t *copyroot_root;
dag_node_t *copyroot_node;
@@ -1122,7 +1122,7 @@ make_path_mutable(svn_fs_root_t *root,
apr_pool_t *pool)
{
dag_node_t *clone;
- const char *txn_id = root_txn_id(root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
/* Is the node mutable already? */
if (svn_fs_fs__dag_check_mutable(parent_path->node))
@@ -1132,7 +1132,8 @@ make_path_mutable(svn_fs_root_t *root,
if (parent_path->parent)
{
const svn_fs_id_t *parent_id, *child_id, *copyroot_id;
- const char *copy_id = NULL;
+ svn_fs_fs__id_part_t copy_id = { SVN_INVALID_REVNUM, 0 };
+ svn_fs_fs__id_part_t *copy_id_ptr = ©_id;
copy_id_inherit_t inherit = parent_path->copy_inherit;
const char *clone_path, *copyroot_path;
svn_revnum_t copyroot_rev;
@@ -1149,7 +1150,7 @@ make_path_mutable(svn_fs_root_t *root,
{
case copy_id_inherit_parent:
parent_id = svn_fs_fs__dag_get_id(parent_path->parent->node);
- copy_id = svn_fs_fs__id_copy_id(parent_id);
+ copy_id = *svn_fs_fs__id_copy_id(parent_id);
break;
case copy_id_inherit_new:
@@ -1158,7 +1159,7 @@ make_path_mutable(svn_fs_root_t *root,
break;
case copy_id_inherit_self:
- copy_id = NULL;
+ copy_id_ptr = NULL;
break;
case copy_id_inherit_unknown:
@@ -1187,7 +1188,7 @@ make_path_mutable(svn_fs_root_t *root,
parent_path->parent->node,
clone_path,
parent_path->entry,
- copy_id, txn_id,
+ copy_id_ptr, txn_id,
is_parent_copyroot,
pool));
@@ -1273,7 +1274,7 @@ get_dag(dag_node_t **dag_node_p,
be SVN_INVALID_REVNUM. Do all this as part of POOL. */
static svn_error_t *
add_change(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
const char *path,
const svn_fs_id_t *noderev_id,
svn_fs_path_change_kind_t change_kind,
@@ -1469,7 +1470,7 @@ fs_change_node_prop(svn_fs_root_t *root,
{
parent_path_t *parent_path;
apr_hash_t *proplist;
- const char *txn_id;
+ const svn_fs_fs__id_part_t *txn_id;
if (! root->is_txn_root)
return SVN_FS__NOT_TXN(root);
@@ -1611,7 +1612,7 @@ merge(svn_stringbuf_t *conflict_p,
dag_node_t *target,
dag_node_t *source,
dag_node_t *ancestor,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_int64_t *mergeinfo_increment_out,
apr_pool_t *pool)
{
@@ -1975,7 +1976,7 @@ merge_changes(dag_node_t *ancestor_node,
{
dag_node_t *txn_root_node;
svn_fs_t *fs = txn->fs;
- const char *txn_id = svn_fs_fs__txn_get_id(txn);
+ const svn_fs_fs__id_part_t *txn_id = svn_fs_fs__txn_get_id(txn);
SVN_ERR(svn_fs_fs__dag_txn_root(&txn_root_node, fs, txn_id, pool));
@@ -2260,7 +2261,7 @@ fs_make_dir(svn_fs_root_t *root,
{
parent_path_t *parent_path;
dag_node_t *sub_dir;
- const char *txn_id = root_txn_id(root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
SVN_ERR(check_newline(path, pool));
@@ -2309,7 +2310,7 @@ fs_delete_node(svn_fs_root_t *root,
apr_pool_t *pool)
{
parent_path_t *parent_path;
- const char *txn_id;
+ const svn_fs_fs__id_part_t *txn_id;
apr_int64_t mergeinfo_count = 0;
svn_node_kind_t kind;
@@ -2385,7 +2386,7 @@ copy_helper(svn_fs_root_t *from_root,
{
dag_node_t *from_node;
parent_path_t *to_parent_path;
- const char *txn_id = root_txn_id(to_root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(to_root);
svn_boolean_t same_p;
/* Use an error check, not an assert, because even the caller cannot
@@ -2581,7 +2582,7 @@ fs_make_file(svn_fs_root_t *root,
{
parent_path_t *parent_path;
dag_node_t *child;
- const char *txn_id = root_txn_id(root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(root);
SVN_ERR(check_newline(path, pool));
@@ -2817,7 +2818,7 @@ apply_textdelta(void *baton, apr_pool_t
{
txdelta_baton_t *tb = (txdelta_baton_t *) baton;
parent_path_t *parent_path;
- const char *txn_id = root_txn_id(tb->root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(tb->root);
/* Call open_path with no flags, as we want this to return an error
if the node for which we are searching doesn't exist. */
@@ -2982,7 +2983,7 @@ apply_text(void *baton, apr_pool_t *pool
{
struct text_baton_t *tb = baton;
parent_path_t *parent_path;
- const char *txn_id = root_txn_id(tb->root);
+ const svn_fs_fs__id_part_t *txn_id = root_txn_id(tb->root);
/* Call open_path with no flags, as we want this to return an error
if the node for which we are searching doesn't exist. */
@@ -3360,7 +3361,7 @@ fs_node_origin_rev(svn_revnum_t *revisio
{
svn_fs_t *fs = root->fs;
const svn_fs_id_t *given_noderev_id, *cached_origin_id;
- const char *node_id, *dash;
+ const svn_fs_fs__id_part_t *node_id;
path = svn_fs__canonicalize_abspath(path, pool);
@@ -3368,27 +3369,13 @@ fs_node_origin_rev(svn_revnum_t *revisio
SVN_ERR(svn_fs_fs__node_id(&given_noderev_id, root, path, pool));
node_id = svn_fs_fs__id_node_id(given_noderev_id);
- /* Is it a brand new uncommitted node? */
- if (node_id[0] == '_')
- {
- *revision = SVN_INVALID_REVNUM;
- return SVN_NO_ERROR;
- }
-
- /* Maybe this is a new-style node ID that just has the revision
- sitting right in it. */
- dash = strchr(node_id, '-');
- if (dash && *(dash+1))
- {
- *revision = SVN_STR_TO_REV(dash + 1);
- return SVN_NO_ERROR;
- }
-
- /* The root node always has ID 0, created in revision 0 and will never
- use the new-style ID format. */
- if (strcmp(node_id, "0") == 0)
+ /* Is it a brand new uncommitted node or a new-style node ID?
+ * (committed old-style nodes will have a 0 revision value;
+ * rev 0, number 0 is rev 0 root node). Note that != 0 includes
+ * SVN_INVALID_REVNUM for uncommitted nodes. */
+ if (node_id->revision != 0 || node_id->number == 0)
{
- *revision = 0;
+ *revision = node_id->revision;
return SVN_NO_ERROR;
}
@@ -3468,7 +3455,7 @@ fs_node_origin_rev(svn_revnum_t *revisio
/* Wow, I don't want to have to do all that again. Let's cache
the result. */
- if (node_id[0] != '_')
+ if (node_id->revision != SVN_INVALID_REVNUM)
SVN_ERR(svn_fs_fs__set_node_origin(fs, node_id,
svn_fs_fs__dag_get_id(node), pool));
@@ -4194,17 +4181,17 @@ make_revision_root(svn_fs_t *fs,
static svn_error_t *
make_txn_root(svn_fs_root_t **root_p,
svn_fs_t *fs,
- const char *txn,
+ const svn_fs_fs__id_part_t *txn,
svn_revnum_t base_rev,
apr_uint32_t flags,
apr_pool_t *pool)
{
svn_fs_root_t *root = make_root(fs, pool);
fs_txn_root_data_t *frd = apr_pcalloc(root->pool, sizeof(*frd));
- frd->txn_id = apr_pstrdup(root->pool, txn);
+ frd->txn_id = *txn;
root->is_txn_root = TRUE;
- root->txn = apr_pstrdup(root->pool, txn);
+ root->txn = svn_fs_fs__id_txn_unparse(txn, root->pool);
root->txn_flags = flags;
root->rev = base_rev;
@@ -4375,7 +4362,7 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
if (root->is_txn_root)
{
fs_txn_root_data_t *frd = root->fsap_data;
- SVN_ERR(svn_fs_fs__dag_txn_root(&root_dir, fs, frd->txn_id, pool));
+ SVN_ERR(svn_fs_fs__dag_txn_root(&root_dir, fs, &frd->txn_id, pool));
}
else
{
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.c?rev=1506545&r1=1506544&r2=1506545&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.c Wed Jul 24 13:24:44 2013
@@ -193,17 +193,17 @@ svn_fs_fs__path_revprops(svn_fs_t *fs,
* Allocate the result in POOL.
*/
static const char *
-combine_txn_id_string(const char *txn_id,
+combine_txn_id_string(const svn_fs_fs__id_part_t *txn_id,
const char *to_add,
apr_pool_t *pool)
{
- return apr_pstrcat(pool, txn_id,
+ return apr_pstrcat(pool, svn_fs_fs__id_txn_unparse(txn_id, pool),
to_add, (char *)NULL);
}
const char *
svn_fs_fs__path_txn_dir(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
SVN_ERR_ASSERT_NO_RETURN(txn_id != NULL);
@@ -215,7 +215,7 @@ svn_fs_fs__path_txn_dir(svn_fs_t *fs,
const char *
svn_fs_fs__path_txn_proto_rev(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -231,7 +231,7 @@ svn_fs_fs__path_txn_proto_rev(svn_fs_t *
const char *
svn_fs_fs__path_txn_proto_rev_lock(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -251,13 +251,13 @@ svn_fs_fs__path_txn_node_rev(svn_fs_t *f
const svn_fs_id_t *id,
apr_pool_t *pool)
{
- const char *txn_id = svn_fs_fs__id_txn_id(id);
- const char *node_id = svn_fs_fs__id_node_id(id);
- const char *copy_id = svn_fs_fs__id_copy_id(id);
- const char *name = apr_psprintf(pool, PATH_PREFIX_NODE "%s.%s",
- node_id, copy_id);
+ char *filename = (char *)svn_fs_fs__id_unparse(id, pool)->data;
+ *strrchr(filename, '.') = '\0';
- return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, txn_id, pool), name,
+ return svn_dirent_join(svn_fs_fs__path_txn_dir(fs, svn_fs_fs__id_txn_id(id),
+ pool),
+ apr_psprintf(pool, PATH_PREFIX_NODE "%s",
+ filename),
pool);
}
@@ -281,11 +281,17 @@ svn_fs_fs__path_txn_node_children(svn_fs
const char *
svn_fs_fs__path_node_origin(svn_fs_t *fs,
- const char *node_id,
+ const svn_fs_fs__id_part_t *node_id,
apr_pool_t *pool)
{
+ char buffer[SVN_INT64_BUFFER_SIZE];
+ apr_size_t len = svn__ui64tobase36(buffer, node_id->number);
+
+ if (len > 1)
+ buffer[len - 1] = '\0';
+
return svn_dirent_join_many(pool, fs->path, PATH_NODE_ORIGINS_DIR,
- node_id, NULL);
+ buffer, NULL);
}
const char *
@@ -367,19 +373,28 @@ svn_fs_fs__write_revnum_file(svn_fs_t *f
svn_error_t *
svn_fs_fs__write_current(svn_fs_t *fs,
svn_revnum_t rev,
- const char *next_node_id,
- const char *next_copy_id,
+ apr_uint64_t next_node_id,
+ apr_uint64_t next_copy_id,
apr_pool_t *pool)
{
char *buf;
- const char *name;
+ const char *tmp_name, *name;
fs_fs_data_t *ffd = fs->fsap_data;
/* Now we can just write out this line. */
if (ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT)
- buf = apr_psprintf(pool, "%ld\n", rev);
+ {
+ buf = apr_psprintf(pool, "%ld\n", rev);
+ }
else
- buf = apr_psprintf(pool, "%ld %s %s\n", rev, next_node_id, next_copy_id);
+ {
+ char node_id_str[SVN_INT64_BUFFER_SIZE];
+ char copy_id_str[SVN_INT64_BUFFER_SIZE];
+ svn__ui64tobase36(node_id_str, next_node_id);
+ svn__ui64tobase36(copy_id_str, next_copy_id);
+
+ buf = apr_psprintf(pool, "%ld %s %s\n", rev, node_id_str, copy_id_str);
+ }
name = svn_fs_fs__path_current(fs, pool);
SVN_ERR(svn_io_write_atomic(name, buf, strlen(buf),
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.h?rev=1506545&r1=1506544&r2=1506545&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/util.h Wed Jul 24 13:24:44 2013
@@ -181,7 +181,7 @@ svn_fs_fs__path_min_unpacked_rev(svn_fs_
*/
const char *
svn_fs_fs__path_txn_dir(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Return the path of the proto-revision file for transaction TXN_ID in FS.
@@ -189,7 +189,7 @@ svn_fs_fs__path_txn_dir(svn_fs_t *fs,
*/
const char *
svn_fs_fs__path_txn_proto_rev(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Return the path of the proto-revision lock file for transaction TXN_ID
@@ -197,7 +197,7 @@ svn_fs_fs__path_txn_proto_rev(svn_fs_t *
*/
const char *
svn_fs_fs__path_txn_proto_rev_lock(svn_fs_t *fs,
- const char *txn_id,
+ const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
/* Return the path of the file containing the in-transaction node revision
@@ -230,7 +230,7 @@ svn_fs_fs__path_txn_node_children(svn_fs
*/
const char *
svn_fs_fs__path_node_origin(svn_fs_t *fs,
- const char *node_id,
+ const svn_fs_fs__id_part_t *node_id,
apr_pool_t *pool);
/* Set *MIN_UNPACKED_REV to the integer value read from the file returned
@@ -279,8 +279,8 @@ svn_fs_fs__write_revnum_file(svn_fs_t *f
svn_error_t *
svn_fs_fs__write_current(svn_fs_t *fs,
svn_revnum_t rev,
- const char *next_node_id,
- const char *next_copy_id,
+ apr_uint64_t next_node_id,
+ apr_uint64_t next_copy_id,
apr_pool_t *pool);
/* Read the file at PATH and return its content in *CONTENT. *CONTENT will