You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/02/17 06:53:26 UTC
svn commit: r1568883 [4/6] - in /subversion/branches/fsfs-ucsnorm: ./
build/generator/ contrib/client-side/ contrib/client-side/emacs/
contrib/hook-scripts/ contrib/server-side/ notes/ notes/meetings/
notes/wc-ng/ subversion/bindings/ctypes-python/csvn...
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.c Mon Feb 17 05:53:23 2014
@@ -66,14 +66,14 @@ static txn_vtable_t txn_vtable = {
typedef struct fs_txn_data_t
{
/* Strongly typed representation of the TXN's ID member. */
- svn_fs_x__id_part_t txn_id;
+ svn_fs_x__txn_id_t txn_id;
} fs_txn_data_t;
-const svn_fs_x__id_part_t *
+svn_fs_x__txn_id_t
svn_fs_x__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. */
@@ -85,7 +85,7 @@ svn_fs_x__txn_get_id(svn_fs_txn_t *txn)
true) or return NULL (otherwise). */
static fs_x_shared_txn_data_t *
get_shared_txn(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
svn_boolean_t create_new)
{
fs_x_data_t *ffd = fs->fsap_data;
@@ -93,7 +93,7 @@ get_shared_txn(svn_fs_t *fs,
fs_x_shared_txn_data_t *txn;
for (txn = ffsd->txns; txn; txn = txn->next)
- if (svn_fs_x__id_part_eq(&txn->txn_id, txn_id))
+ if (txn->txn_id == txn_id)
break;
if (txn || !create_new)
@@ -113,7 +113,7 @@ get_shared_txn(svn_fs_t *fs,
txn->pool = subpool;
}
- txn->txn_id = *txn_id;
+ txn->txn_id = txn_id;
txn->being_written = FALSE;
/* Link this transaction into the head of the list. We will typically
@@ -131,14 +131,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 svn_fs_x__id_part_t *txn_id)
+free_shared_txn(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id)
{
fs_x_data_t *ffd = fs->fsap_data;
fs_x_shared_data_t *ffsd = ffd->shared;
fs_x_shared_txn_data_t *txn, *prev = NULL;
for (txn = ffsd->txns; txn; prev = txn, txn = txn->next)
- if (svn_fs_x__id_part_eq(&txn->txn_id, txn_id))
+ if (txn->txn_id == txn_id)
break;
if (!txn)
@@ -299,7 +299,7 @@ with_txn_current_lock(svn_fs_t *fs,
which see. */
struct unlock_proto_rev_baton
{
- svn_fs_x__id_part_t txn_id;
+ svn_fs_x__txn_id_t txn_id;
void *lockcookie;
};
@@ -309,30 +309,30 @@ unlock_proto_rev_body(svn_fs_t *fs, cons
{
const struct unlock_proto_rev_baton *b = baton;
apr_file_t *lockfile = b->lockcookie;
- fs_x_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, FALSE);
+ fs_x_shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, FALSE);
apr_status_t apr_err;
if (!txn)
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
_("Can't unlock unknown transaction '%s'"),
- svn_fs_x__id_txn_unparse(&b->txn_id, pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
if (!txn->being_written)
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
_("Can't unlock nonlocked transaction '%s'"),
- svn_fs_x__id_txn_unparse(&b->txn_id, pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
apr_err = apr_file_unlock(lockfile);
if (apr_err)
return svn_error_wrap_apr
(apr_err,
_("Can't unlock prototype revision lockfile for transaction '%s'"),
- svn_fs_x__id_txn_unparse(&b->txn_id, pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
apr_err = apr_file_close(lockfile);
if (apr_err)
return svn_error_wrap_apr
(apr_err,
_("Can't close prototype revision lockfile for transaction '%s'"),
- svn_fs_x__id_txn_unparse(&b->txn_id, pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
txn->being_written = FALSE;
@@ -346,13 +346,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 svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_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);
}
@@ -361,13 +361,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 svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_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);
}
@@ -378,7 +378,7 @@ struct get_writable_proto_rev_baton
{
apr_file_t **file;
void **lockcookie;
- svn_fs_x__id_part_t txn_id;
+ svn_fs_x__txn_id_t txn_id;
};
/* Callback used in the implementation of get_writable_proto_rev(). */
@@ -389,7 +389,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_x_shared_txn_data_t *txn = get_shared_txn(fs, &b->txn_id, TRUE);
+ fs_x_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. */
@@ -399,7 +399,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
"of transaction '%s' because a previous "
"representation is currently being written by "
"this process"),
- svn_fs_x__id_txn_unparse(&b->txn_id, pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
/* We know that no thread in this process is writing to the proto-rev
@@ -412,7 +412,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_x__path_txn_proto_rev_lock(fs, &b->txn_id, pool);
+ = svn_fs_x__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
@@ -436,8 +436,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
"file of transaction '%s' because a "
"previous representation is currently "
"being written by another process"),
- svn_fs_x__id_txn_unparse(&b->txn_id,
- pool));
+ svn_fs_x__txn_name(b->txn_id, pool));
return svn_error_wrap_apr(apr_err,
_("Can't get exclusive lock on file '%s'"),
@@ -453,7 +452,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_x__path_txn_proto_rev(fs, &b->txn_id, pool),
+ svn_fs_x__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
@@ -473,7 +472,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;
}
@@ -495,14 +494,14 @@ static svn_error_t *
get_writable_proto_rev(apr_file_t **file,
void **lockcookie,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_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);
}
@@ -511,7 +510,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 svn_fs_x__id_part_t *txn_id = baton;
+ svn_fs_x__txn_id_t txn_id = *(const svn_fs_x__txn_id_t *)baton;
free_shared_txn(fs, txn_id);
svn_fs_x__reset_txn_caches(fs);
@@ -523,10 +522,10 @@ 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 svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
- return with_txnlist_lock(fs, purge_shared_txn_body, txn_id, pool);
+ return with_txnlist_lock(fs, purge_shared_txn_body, &txn_id, pool);
}
@@ -579,8 +578,10 @@ store_sha1_rep_mapping(svn_fs_t *fs,
&& noderev->data_rep->has_sha1)
{
apr_file_t *rep_file;
+ apr_int64_t txn_id
+ = svn_fs_x__get_txn_id(noderev->data_rep->id.change_set);
const char *file_name
- = svn_fs_x__path_txn_sha1(fs, &noderev->data_rep->txn_id,
+ = svn_fs_x__path_txn_sha1(fs, txn_id,
noderev->data_rep->sha1_digest, pool);
svn_stringbuf_t *rep_string
= svn_fs_x__unparse_representation(noderev->data_rep,
@@ -893,7 +894,7 @@ process_changes(apr_hash_t *changed_path
svn_error_t *
svn_fs_x__txn_changes_fetch(apr_hash_t **changed_paths_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
apr_file_t *file;
@@ -949,15 +950,17 @@ svn_fs_x__paths_changed(apr_hash_t **cha
Allocations are from POOL. */
static svn_error_t *
create_new_txn_noderev_from_rev(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
svn_fs_id_t *src,
apr_pool_t *pool)
{
node_revision_t *noderev;
- const svn_fs_x__id_part_t *node_id, *copy_id;
SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, pool));
+ /* This must be a root node. */
+ SVN_ERR_ASSERT(svn_fs_x__id_node_id(noderev->id)->number == 0);
+
if (svn_fs_x__id_is_txn(noderev->id))
return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
_("Copying from transactions not allowed"));
@@ -969,9 +972,7 @@ create_new_txn_noderev_from_rev(svn_fs_t
/* For the transaction root, the copyroot never changes. */
- node_id = svn_fs_x__id_node_id(noderev->id);
- copy_id = svn_fs_x__id_copy_id(noderev->id);
- noderev->id = svn_fs_x__id_txn_create(node_id, copy_id, txn_id, pool);
+ noderev->id = svn_fs_x__id_txn_create_root(txn_id, pool);
return svn_fs_x__put_node_revision(fs, noderev->id, noderev, TRUE, pool);
}
@@ -1018,9 +1019,8 @@ get_and_increment_txn_key_body(void *bat
value in the transaction ID to prevent reuse of transaction IDs. */
static svn_error_t *
create_txn_dir(const char **id_p,
- svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t *txn_id,
svn_fs_t *fs,
- svn_revnum_t rev,
apr_pool_t *pool)
{
struct get_and_increment_txn_key_baton cb;
@@ -1036,10 +1036,9 @@ create_txn_dir(const char **id_p,
get_and_increment_txn_key_body,
&cb,
pool));
- txn_id->revision = rev;
- txn_id->number = cb.txn_number;
+ *txn_id = cb.txn_number;
- *id_p = svn_fs_x__id_txn_unparse(txn_id, pool);
+ *id_p = svn_fs_x__txn_name(*txn_id, pool);
txn_dir = svn_dirent_join_many(pool,
fs->path,
PATH_TXNS_DIR,
@@ -1064,7 +1063,7 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
ftd = apr_pcalloc(pool, sizeof(*ftd));
/* Get the txn_id. */
- SVN_ERR(create_txn_dir(&txn->id, &ftd->txn_id, fs, rev, pool));
+ SVN_ERR(create_txn_dir(&txn->id, &ftd->txn_id, fs, pool));
txn->fs = fs;
txn->base_rev = rev;
@@ -1075,26 +1074,26 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
/* Create a new root node for this transaction. */
SVN_ERR(svn_fs_x__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_x__path_txn_proto_rev(fs, &ftd->txn_id, pool),
+ svn_fs_x__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_x__path_txn_proto_rev_lock(fs, &ftd->txn_id, pool),
+ svn_fs_x__path_txn_proto_rev_lock(fs, ftd->txn_id, pool),
pool));
/* Create an empty changes file. */
SVN_ERR(svn_io_file_create_empty(
- svn_fs_x__path_txn_changes(fs, &ftd->txn_id, pool),
+ svn_fs_x__path_txn_changes(fs, ftd->txn_id, pool),
pool));
/* Create the next-ids file. */
return svn_io_file_create(
- svn_fs_x__path_txn_next_ids(fs, &ftd->txn_id, pool),
+ svn_fs_x__path_txn_next_ids(fs, ftd->txn_id, pool),
"0 0\n", pool);
}
@@ -1103,14 +1102,14 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
static svn_error_t *
get_txn_proplist(apr_hash_t *proplist,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_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_x__id_txn_used(txn_id))
+ if (txn_id == SVN_FS_X__INVALID_TXN_ID)
return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
_("Internal error: a null transaction id was "
"passed to get_txn_proplist()"));
@@ -1156,7 +1155,7 @@ change_txn_props(svn_fs_txn_t *txn,
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
@@ -1185,15 +1184,15 @@ change_txn_props(svn_fs_txn_t *txn,
SVN_ERR(svn_hash_write2(txn_prop, stream, SVN_HASH_TERMINATOR, pool));
SVN_ERR(svn_stream_close(stream));
SVN_ERR(svn_io_write_unique(&txn_prop_filename,
- svn_fs_x__path_txn_dir(txn->fs, &ftd->txn_id, pool),
+ svn_fs_x__path_txn_dir(txn->fs, ftd->txn_id, pool),
buf->data,
buf->len,
svn_io_file_del_none,
pool));
return svn_io_file_rename(txn_prop_filename,
(final
- ? svn_fs_x__path_txn_props_final(txn->fs, &ftd->txn_id, pool)
- : svn_fs_x__path_txn_props(txn->fs, &ftd->txn_id, pool)),
+ ? svn_fs_x__path_txn_props_final(txn->fs, ftd->txn_id, pool)
+ : svn_fs_x__path_txn_props(txn->fs, ftd->txn_id, pool)),
pool);
}
@@ -1210,7 +1209,7 @@ svn_fs_x__change_txn_props(svn_fs_txn_t
svn_error_t *
svn_fs_x__get_txn(transaction_t **txn_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
transaction_t *txn;
@@ -1234,6 +1233,92 @@ svn_fs_x__get_txn(transaction_t **txn_p,
return SVN_NO_ERROR;
}
+/* If it is supported by the format of file system FS, store the (ITEM_INDEX,
+ * OFFSET) pair in the log-to-phys proto index file of transaction TXN_ID.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+store_l2p_index_entry(svn_fs_t *fs,
+ svn_fs_x__txn_id_t txn_id,
+ apr_off_t offset,
+ apr_uint64_t item_index,
+ apr_pool_t *pool)
+{
+ const char *path = svn_fs_x__path_l2p_proto_index(fs, txn_id, pool);
+ apr_file_t *file;
+ SVN_ERR(svn_fs_x__l2p_proto_index_open(&file, path, pool));
+ SVN_ERR(svn_fs_x__l2p_proto_index_add_entry(file, offset, 0,
+ item_index, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* If it is supported by the format of file system FS, store ENTRY in the
+ * phys-to-log proto index file of transaction TXN_ID.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+store_p2l_index_entry(svn_fs_t *fs,
+ svn_fs_x__txn_id_t txn_id,
+ svn_fs_x__p2l_entry_t *entry,
+ apr_pool_t *pool)
+{
+ const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, pool);
+ apr_file_t *file;
+ SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, pool));
+ SVN_ERR(svn_fs_x__p2l_proto_index_add_entry(file, entry, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* Allocate an item index for the given MY_OFFSET in the transaction TXN_ID
+ * of file system FS and return it in *ITEM_INDEX. For old formats, it
+ * will simply return the offset as item index; in new formats, it will
+ * increment the txn's item index counter file and store the mapping in
+ * the proto index file.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+allocate_item_index(apr_uint64_t *item_index,
+ svn_fs_t *fs,
+ svn_fs_x__txn_id_t txn_id,
+ apr_off_t my_offset,
+ apr_pool_t *pool)
+{
+ apr_file_t *file;
+ char buffer[SVN_INT64_BUFFER_SIZE] = { 0 };
+ svn_boolean_t eof = FALSE;
+ apr_size_t to_write;
+ apr_size_t read;
+ apr_off_t offset = 0;
+
+ /* read number, increment it and write it back to disk */
+ SVN_ERR(svn_io_file_open(&file,
+ svn_fs_x__path_txn_item_index(fs, txn_id, pool),
+ APR_READ | APR_WRITE
+ | APR_CREATE | APR_BUFFERED,
+ APR_OS_DEFAULT, pool));
+ SVN_ERR(svn_io_file_read_full2(file, buffer, sizeof(buffer)-1,
+ &read, &eof, pool));
+ if (read)
+ SVN_ERR(svn_cstring_atoui64(item_index, buffer));
+ else
+ *item_index = SVN_FS_X__ITEM_INDEX_FIRST_USER;
+
+ to_write = svn__ui64toa(buffer, *item_index + 1);
+ SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool));
+ SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
+ /* write log-to-phys index */
+ SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, *item_index,
+ pool));
+
+ return SVN_NO_ERROR;
+}
+
/* Write out the currently available next node_id NODE_ID and copy_id
COPY_ID for transaction TXN_ID in filesystem FS. The next node-id is
used both for creating new unique nodes for the given transaction, as
@@ -1241,7 +1326,7 @@ svn_fs_x__get_txn(transaction_t **txn_p,
POOL. */
static svn_error_t *
write_next_ids(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_uint64_t node_id,
apr_uint64_t copy_id,
apr_pool_t *pool)
@@ -1273,7 +1358,7 @@ static svn_error_t *
read_next_ids(apr_uint64_t *node_id,
apr_uint64_t *copy_id,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
svn_stringbuf_t *buf;
@@ -1305,7 +1390,7 @@ read_next_ids(apr_uint64_t *node_id,
static svn_error_t *
get_new_txn_node_id(svn_fs_x__id_part_t *node_id_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
apr_uint64_t node_id, copy_id;
@@ -1313,7 +1398,7 @@ get_new_txn_node_id(svn_fs_x__id_part_t
/* First read in the current next-ids file. */
SVN_ERR(read_next_ids(&node_id, ©_id, fs, txn_id, pool));
- node_id_p->revision = SVN_INVALID_REVNUM;
+ node_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
node_id_p->number = node_id;
SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
@@ -1324,7 +1409,7 @@ get_new_txn_node_id(svn_fs_x__id_part_t
svn_error_t *
svn_fs_x__reserve_copy_id(svn_fs_x__id_part_t *copy_id_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
apr_uint64_t node_id, copy_id;
@@ -1332,7 +1417,7 @@ svn_fs_x__reserve_copy_id(svn_fs_x__id_p
/* First read in the current next-ids file. */
SVN_ERR(read_next_ids(&node_id, ©_id, fs, txn_id, pool));
- copy_id_p->revision = SVN_INVALID_REVNUM;
+ copy_id_p->change_set = SVN_FS_X__INVALID_CHANGE_SET;
copy_id_p->number = copy_id;
SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
@@ -1345,7 +1430,7 @@ svn_fs_x__create_node(const svn_fs_id_t
svn_fs_t *fs,
node_revision_t *noderev,
const svn_fs_x__id_part_t *copy_id,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
svn_fs_x__id_part_t node_id;
@@ -1370,13 +1455,13 @@ svn_fs_x__purge_txn(svn_fs_t *fs,
const char *txn_id_str,
apr_pool_t *pool)
{
- svn_fs_x__id_part_t txn_id;
- SVN_ERR(svn_fs_x__id_txn_parse(&txn_id, txn_id_str));
+ svn_fs_x__txn_id_t txn_id;
+ SVN_ERR(svn_fs_x__txn_by_name(&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_x__path_txn_dir(fs, &txn_id, pool),
+ SVN_ERR(svn_io_remove_dir2(svn_fs_x__path_txn_dir(fs, txn_id, pool),
FALSE, NULL, NULL, pool));
/* Delete protorev and its lock, which aren't in the txn
@@ -1384,10 +1469,10 @@ svn_fs_x__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_x__path_txn_proto_rev(fs, &txn_id, pool),
+ svn_fs_x__path_txn_proto_rev(fs, txn_id, pool),
TRUE, pool));
SVN_ERR(svn_io_remove_file2(
- svn_fs_x__path_txn_proto_rev_lock(fs, &txn_id, pool),
+ svn_fs_x__path_txn_proto_rev_lock(fs, txn_id, pool),
TRUE, pool));
return SVN_NO_ERROR;
@@ -1408,26 +1493,9 @@ svn_fs_x__abort_txn(svn_fs_txn_t *txn,
return SVN_NO_ERROR;
}
-/* Assign the UNIQUIFIER member of REP based on the current state of TXN_ID
- * in FS. Allocate the uniquifier in POOL.
- */
-static svn_error_t *
-set_uniquifier(svn_fs_t *fs,
- representation_t *rep,
- apr_pool_t *pool)
-{
- svn_fs_x__id_part_t temp;
-
- SVN_ERR(get_new_txn_node_id(&temp, fs, &rep->txn_id, pool));
- rep->uniquifier.txn_id = rep->txn_id;
- rep->uniquifier.number = temp.number;
-
- return SVN_NO_ERROR;
-}
-
svn_error_t *
svn_fs_x__set_entry(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
node_revision_t *parent_noderev,
const char *name,
const svn_fs_id_t *id,
@@ -1442,7 +1510,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
fs_x_data_t *ffd = fs->fsap_data;
apr_pool_t *subpool = svn_pool_create(pool);
- if (!rep || !svn_fs_x__id_txn_used(&rep->txn_id))
+ if (!rep || !svn_fs_x__is_txn(rep->id.change_set))
{
apr_hash_t *entries;
@@ -1461,9 +1529,8 @@ svn_fs_x__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;
- SVN_ERR(set_uniquifier(fs, rep, pool));
+ rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+ rep->id.number = SVN_FS_X__ITEM_INDEX_UNUSED;
parent_noderev->data_rep = rep;
SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev->id,
parent_noderev, FALSE, pool));
@@ -1525,7 +1592,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
svn_error_t *
svn_fs_x__add_change(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
const char *path,
const svn_fs_id_t *id,
svn_fs_path_change_kind_t change_kind,
@@ -1559,92 +1626,6 @@ svn_fs_x__add_change(svn_fs_t *fs,
return svn_io_file_close(file, pool);
}
-/* If it is supported by the format of file system FS, store the (ITEM_INDEX,
- * OFFSET) pair in the log-to-phys proto index file of transaction TXN_ID.
- * Use POOL for allocations.
- */
-static svn_error_t *
-store_l2p_index_entry(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
- apr_off_t offset,
- apr_uint64_t item_index,
- apr_pool_t *pool)
-{
- const char *path = svn_fs_x__path_l2p_proto_index(fs, txn_id, pool);
- apr_file_t *file;
- SVN_ERR(svn_fs_x__l2p_proto_index_open(&file, path, pool));
- SVN_ERR(svn_fs_x__l2p_proto_index_add_entry(file, offset, 0,
- item_index, pool));
- SVN_ERR(svn_io_file_close(file, pool));
-
- return SVN_NO_ERROR;
-}
-
-/* If it is supported by the format of file system FS, store ENTRY in the
- * phys-to-log proto index file of transaction TXN_ID.
- * Use POOL for allocations.
- */
-static svn_error_t *
-store_p2l_index_entry(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
- svn_fs_x__p2l_entry_t *entry,
- apr_pool_t *pool)
-{
- const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, pool);
- apr_file_t *file;
- SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, pool));
- SVN_ERR(svn_fs_x__p2l_proto_index_add_entry(file, entry, pool));
- SVN_ERR(svn_io_file_close(file, pool));
-
- return SVN_NO_ERROR;
-}
-
-/* Allocate an item index for the given MY_OFFSET in the transaction TXN_ID
- * of file system FS and return it in *ITEM_INDEX. For old formats, it
- * will simply return the offset as item index; in new formats, it will
- * increment the txn's item index counter file and store the mapping in
- * the proto index file.
- * Use POOL for allocations.
- */
-static svn_error_t *
-allocate_item_index(apr_uint64_t *item_index,
- svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
- apr_off_t my_offset,
- apr_pool_t *pool)
-{
- apr_file_t *file;
- char buffer[SVN_INT64_BUFFER_SIZE] = { 0 };
- svn_boolean_t eof = FALSE;
- apr_size_t to_write;
- apr_size_t read;
- apr_off_t offset = 0;
-
- /* read number, increment it and write it back to disk */
- SVN_ERR(svn_io_file_open(&file,
- svn_fs_x__path_txn_item_index(fs, txn_id, pool),
- APR_READ | APR_WRITE
- | APR_CREATE | APR_BUFFERED,
- APR_OS_DEFAULT, pool));
- SVN_ERR(svn_io_file_read_full2(file, buffer, sizeof(buffer)-1,
- &read, &eof, pool));
- if (read)
- SVN_ERR(svn_cstring_atoui64(item_index, buffer));
- else
- *item_index = SVN_FS_X__ITEM_INDEX_FIRST_USER;
-
- to_write = svn__ui64toa(buffer, *item_index + 1);
- SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool));
- SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool));
- SVN_ERR(svn_io_file_close(file, pool));
-
- /* write log-to-phys index */
- SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, *item_index,
- pool));
-
- return SVN_NO_ERROR;
-}
-
/* This baton is used by the representation writing streams. It keeps
track of the checksum information as well as the total size of the
representation so far. */
@@ -1785,12 +1766,14 @@ choose_delta_base(representation_t **rep
base_revision = svn_fs_x__id_rev(base->id);
if (props)
{
- if (base->prop_rep && base_revision > base->prop_rep->revision)
+ if (base->prop_rep &&
+ base_revision > svn_fs_x__get_revnum(base->prop_rep->id.change_set))
maybe_shared_rep = TRUE;
}
else
{
- if (base->data_rep && base_revision > base->data_rep->revision)
+ if (base->data_rep &&
+ base_revision > svn_fs_x__get_revnum(base->data_rep->id.change_set))
maybe_shared_rep = TRUE;
}
}
@@ -1894,8 +1877,8 @@ rep_write_get_baton(struct rep_write_bat
/* Write out the rep header. */
if (base_rep)
{
- header.base_revision = base_rep->revision;
- header.base_item_index = base_rep->item_index;
+ header.base_revision = svn_fs_x__get_revnum(base_rep->id.change_set);
+ header.base_item_index = base_rep->id.number;
header.base_length = base_rep->size;
header.type = svn_fs_x__rep_delta;
}
@@ -1999,11 +1982,13 @@ get_shared_rep(representation_t **old_re
/* look for intra-revision matches (usually data reps but not limited
to them in case props happen to look like some data rep)
*/
- if (*old_rep == NULL && svn_fs_x__id_txn_used(&rep->txn_id))
+ if (*old_rep == NULL && svn_fs_x__is_txn(rep->id.change_set))
{
svn_node_kind_t kind;
const char *file_name
- = svn_fs_x__path_txn_sha1(fs, &rep->txn_id, rep->sha1_digest, pool);
+ = svn_fs_x__path_txn_sha1(fs,
+ svn_fs_x__get_txn_id(rep->id.change_set),
+ rep->sha1_digest, pool);
/* in our txn, is there a rep file named with the wanted SHA1?
If so, read it and use that rep.
@@ -2022,7 +2007,6 @@ get_shared_rep(representation_t **old_re
{
/* Use the old rep for this content. */
memcpy((*old_rep)->md5_digest, rep->md5_digest, sizeof(rep->md5_digest));
- (*old_rep)->uniquifier = rep->uniquifier;
}
return SVN_NO_ERROR;
@@ -2059,6 +2043,7 @@ rep_write_contents_close(void *baton)
representation_t *rep;
representation_t *old_rep;
apr_off_t offset;
+ apr_int64_t txn_id;
rep = apr_pcalloc(b->parent_pool, sizeof(*rep));
@@ -2073,9 +2058,8 @@ 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_x__id_txn_id(b->noderev->id);
- SVN_ERR(set_uniquifier(b->fs, rep, b->pool));
- rep->revision = SVN_INVALID_REVNUM;
+ txn_id = svn_fs_x__id_txn_id(b->noderev->id);
+ rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
/* Finalize the checksum. */
SVN_ERR(digests_final(rep, b->md5_checksum_ctx, b->sha1_checksum_ctx,
@@ -2097,7 +2081,7 @@ rep_write_contents_close(void *baton)
{
/* Write out our cosmetic end marker. */
SVN_ERR(svn_stream_puts(b->rep_stream, "ENDREP\n"));
- SVN_ERR(allocate_item_index(&rep->item_index, b->fs, &rep->txn_id,
+ SVN_ERR(allocate_item_index(&rep->id.number, b->fs, txn_id,
b->rep_offset, b->pool));
b->noderev->data_rep = rep;
@@ -2112,23 +2096,23 @@ rep_write_contents_close(void *baton)
if (!old_rep)
{
svn_fs_x__p2l_entry_t entry;
- svn_fs_x__id_part_t rev_item;
- rev_item.revision = SVN_INVALID_REVNUM;
- rev_item.number = rep->item_index;
+ svn_fs_x__id_part_t noderev_id;
+ noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
+ noderev_id.number = rep->id.number;
entry.offset = b->rep_offset;
SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->pool));
entry.size = offset - b->rep_offset;
entry.type = SVN_FS_X__ITEM_TYPE_FILE_REP;
entry.item_count = 1;
- entry.items = &rev_item;
+ entry.items = &noderev_id;
SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->pool));
- SVN_ERR(store_p2l_index_entry(b->fs, &rep->txn_id, &entry, b->pool));
+ SVN_ERR(store_p2l_index_entry(b->fs, txn_id, &entry, 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, txn_id, b->lockcookie, b->pool));
svn_pool_destroy(b->pool);
return SVN_NO_ERROR;
@@ -2180,7 +2164,7 @@ svn_fs_x__create_successor(const svn_fs_
const svn_fs_id_t *old_idp,
node_revision_t *new_noderev,
const svn_fs_x__id_part_t *copy_id,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
const svn_fs_id_t *id;
@@ -2228,10 +2212,11 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
/* Mark the node-rev's prop rep as mutable, if not already done. */
if (!noderev->prop_rep
- || !svn_fs_x__id_txn_used(&noderev->prop_rep->txn_id))
+ || svn_fs_x__is_revision(noderev->prop_rep->id.change_set))
{
noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
- noderev->prop_rep->txn_id = *svn_fs_x__id_txn_id(noderev->id);
+ noderev->prop_rep->id.change_set
+ = svn_fs_x__change_set_by_txn(svn_fs_x__id_txn_id(noderev->id));
SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE,
pool));
}
@@ -2282,7 +2267,7 @@ write_hash_delta_rep(representation_t *r
apr_file_t *file,
apr_hash_t *hash,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
node_revision_t *noderev,
apr_hash_t *reps_hash,
int item_type,
@@ -2316,8 +2301,8 @@ write_hash_delta_rep(representation_t *r
/* Write out the rep header. */
if (base_rep)
{
- header.base_revision = base_rep->revision;
- header.base_item_index = base_rep->item_index;
+ header.base_revision = svn_fs_x__get_revnum(base_rep->id.change_set);
+ header.base_item_index = base_rep->id.number;
header.base_length = base_rep->size;
header.type = svn_fs_x__rep_delta;
}
@@ -2369,24 +2354,24 @@ write_hash_delta_rep(representation_t *r
else
{
svn_fs_x__p2l_entry_t entry;
- svn_fs_x__id_part_t rev_item;
+ svn_fs_x__id_part_t noderev_id;
/* Write out our cosmetic end marker. */
SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, pool));
SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
- SVN_ERR(allocate_item_index(&rep->item_index, fs, txn_id, offset,
+ SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id, offset,
pool));
- rev_item.revision = SVN_INVALID_REVNUM;
- rev_item.number = rep->item_index;
+ noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
+ noderev_id.number = rep->id.number;
entry.offset = offset;
SVN_ERR(svn_fs_x__get_file_offset(&offset, file, pool));
entry.size = offset - entry.offset;
entry.type = item_type;
entry.item_count = 1;
- entry.items = &rev_item;
+ entry.items = &noderev_id;
SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
@@ -2460,17 +2445,14 @@ validate_root_noderev(svn_fs_t *fs,
}
/* Given the potentially txn-local id PART, update that to a permanent ID
- * based on the REVISION currently being written and the START_ID for that
- * revision. Use the repo FORMAT to decide which implementation to use.
+ * based on the REVISION.
*/
static void
get_final_id(svn_fs_x__id_part_t *part,
- svn_revnum_t revision,
- apr_uint64_t start_id,
- int format)
+ svn_revnum_t revision)
{
- if (part->revision == SVN_INVALID_REVNUM)
- part->revision = revision;
+ if (part->change_set == SVN_FS_X__INVALID_CHANGE_SET)
+ part->change_set = svn_fs_x__change_set_by_rev(revision);
}
/* Copy a node-revision specified by id ID in fileystem FS from a
@@ -2505,8 +2487,6 @@ write_final_rev(const svn_fs_id_t **new_
svn_revnum_t rev,
svn_fs_t *fs,
const svn_fs_id_t *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,
@@ -2517,10 +2497,11 @@ 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;
- svn_fs_x__id_part_t node_id, copy_id, rev_item;
+ svn_fs_x__id_part_t node_id, copy_id, noderev_id;
fs_x_data_t *ffd = fs->fsap_data;
- const svn_fs_x__id_part_t *txn_id = svn_fs_x__id_txn_id(id);
+ svn_fs_x__txn_id_t txn_id = svn_fs_x__id_txn_id(id);
svn_fs_x__p2l_entry_t entry;
+ svn_fs_x__change_set_t change_set = svn_fs_x__change_set_by_rev(rev);
*new_id_p = NULL;
@@ -2554,7 +2535,6 @@ write_final_rev(const svn_fs_id_t **new_
svn_pool_clear(subpool);
SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
- start_node_id, start_copy_id,
initial_offset, reps_to_cache, reps_hash,
reps_pool, FALSE, subpool));
if (new_id && (svn_fs_x__id_rev(new_id) == rev))
@@ -2563,18 +2543,16 @@ write_final_rev(const svn_fs_id_t **new_
svn_pool_destroy(subpool);
if (noderev->data_rep
- && svn_fs_x__id_txn_used(&noderev->data_rep->txn_id))
+ && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
{
/* Write out the contents of this directory as a text rep. */
SVN_ERR(unparse_dir_entries(&str_entries, entries, pool));
- noderev->data_rep->revision = rev;
+ noderev->data_rep->id.change_set = change_set;
SVN_ERR(write_hash_delta_rep(noderev->data_rep, file,
str_entries, fs, txn_id, noderev,
NULL, SVN_FS_X__ITEM_TYPE_DIR_REP,
pool));
-
- svn_fs_x__id_txn_reset(&noderev->data_rep->txn_id);
}
}
else
@@ -2584,16 +2562,15 @@ write_final_rev(const svn_fs_id_t **new_
num. */
if (noderev->data_rep
- && svn_fs_x__id_txn_used(&noderev->data_rep->txn_id))
+ && svn_fs_x__is_txn(noderev->data_rep->id.change_set))
{
- svn_fs_x__id_txn_reset(&noderev->data_rep->txn_id);
- noderev->data_rep->revision = rev;
+ noderev->data_rep->id.change_set = change_set;
}
}
/* Fix up the property reps. */
if (noderev->prop_rep
- && svn_fs_x__id_txn_used(&noderev->prop_rep->txn_id))
+ && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
{
apr_hash_t *proplist;
int item_type = noderev->kind == svn_node_dir
@@ -2601,8 +2578,7 @@ write_final_rev(const svn_fs_id_t **new_
: SVN_FS_X__ITEM_TYPE_FILE_PROPS;
SVN_ERR(svn_fs_x__get_proplist(&proplist, fs, noderev, pool));
- svn_fs_x__id_txn_reset(&noderev->prop_rep->txn_id);
- noderev->prop_rep->revision = rev;
+ noderev->prop_rep->id.change_set = change_set;
SVN_ERR(write_hash_delta_rep(noderev->prop_rep, file,
proplist, fs, txn_id, noderev,
@@ -2611,9 +2587,9 @@ write_final_rev(const svn_fs_id_t **new_
/* Convert our temporary ID into a permanent revision one. */
node_id = *svn_fs_x__id_node_id(noderev->id);
- get_final_id(&node_id, rev, start_node_id, ffd->format);
+ get_final_id(&node_id, rev);
copy_id = *svn_fs_x__id_copy_id(noderev->id);
- get_final_id(©_id, rev, start_copy_id, ffd->format);
+ get_final_id(©_id, rev);
if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
noderev->copyroot_rev = rev;
@@ -2622,16 +2598,16 @@ write_final_rev(const svn_fs_id_t **new_
if (at_root)
{
/* reference the root noderev from the log-to-phys index */
- rev_item.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
- SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, rev_item.number,
+ noderev_id.number = SVN_FS_X__ITEM_INDEX_ROOT_NODE;
+ SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset, noderev_id.number,
pool));
}
else
- SVN_ERR(allocate_item_index(&rev_item.number, fs, txn_id, my_offset,
+ SVN_ERR(allocate_item_index(&noderev_id.number, fs, txn_id, my_offset,
pool));
- rev_item.revision = rev;
- new_id = svn_fs_x__id_rev_create(&node_id, ©_id, &rev_item, pool);
+ noderev_id.change_set = change_set;
+ new_id = svn_fs_x__id_create(&node_id, ©_id, &noderev_id, pool);
noderev->id = new_id;
@@ -2639,14 +2615,15 @@ write_final_rev(const svn_fs_id_t **new_
{
/* Save the data representation's hash in the rep cache. */
if ( noderev->data_rep && noderev->kind == svn_node_file
- && noderev->data_rep->revision == rev)
+ && svn_fs_x__get_revnum(noderev->data_rep->id.change_set) == rev)
{
SVN_ERR_ASSERT(reps_to_cache && reps_pool);
APR_ARRAY_PUSH(reps_to_cache, representation_t *)
= svn_fs_x__rep_copy(noderev->data_rep, reps_pool);
}
- if (noderev->prop_rep && noderev->prop_rep->revision == rev)
+ if ( noderev->prop_rep
+ && svn_fs_x__get_revnum(noderev->prop_rep->id.change_set) == rev)
{
/* Add new property reps to hash and on-disk cache. */
representation_t *copy
@@ -2681,14 +2658,14 @@ write_final_rev(const svn_fs_id_t **new_
noderev, ffd->format, pool));
/* reference the root noderev from the log-to-phys index */
- rev_item.revision = SVN_INVALID_REVNUM;
+ noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
entry.offset = my_offset;
SVN_ERR(svn_fs_x__get_file_offset(&my_offset, file, pool));
entry.size = my_offset - entry.offset;
entry.type = SVN_FS_X__ITEM_TYPE_NODEREV;
entry.item_count = 1;
- entry.items = &rev_item;
+ entry.items = &noderev_id;
SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
@@ -2706,7 +2683,7 @@ static svn_error_t *
write_final_changed_path_info(apr_off_t *offset_p,
apr_file_t *file,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_hash_t *changed_paths,
svn_revnum_t new_rev,
apr_pool_t *pool)
@@ -2799,7 +2776,7 @@ verify_as_revision_before_current_plus_p
The FS write lock is assumed to be held by the caller. */
static svn_error_t *
verify_locks(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
@@ -2903,7 +2880,7 @@ check_for_duplicate_move_source(apr_hash
txn. Use POOL for temporary allocations. */
static svn_error_t *
verify_moves(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ const svn_fs_txn_t *txn,
svn_revnum_t old_rev,
apr_hash_t *changed_paths,
apr_pool_t *pool)
@@ -2988,7 +2965,7 @@ verify_moves(svn_fs_t *fs,
APR_ARRAY_IDX(moves, i, svn_sort__item_t).value,
pool));
- for (revision = txn_id->revision + 1; revision <= old_rev; ++revision)
+ for (revision = txn->base_rev + 1; revision <= old_rev; ++revision)
{
apr_array_header_t *changes;
change_t **changes_p;
@@ -3040,7 +3017,7 @@ verify_moves(svn_fs_t *fs,
static svn_error_t *
write_final_revprop(const char **path,
svn_fs_txn_t *txn,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
apr_hash_t *txnprops;
@@ -3125,13 +3102,11 @@ 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;
- 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;
apr_off_t initial_offset, changed_path_offset;
- const svn_fs_x__id_part_t *txn_id = svn_fs_x__txn_get_id(cb->txn);
+ svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(cb->txn);
apr_hash_t *changed_paths;
/* Get the current youngest revision. */
@@ -3154,7 +3129,7 @@ commit_body(void *baton, apr_pool_t *poo
SVN_ERR(svn_fs_x__txn_changes_fetch(&changed_paths, cb->fs, txn_id,
pool));
- SVN_ERR(verify_moves(cb->fs, txn_id, old_rev, changed_paths, pool));
+ SVN_ERR(verify_moves(cb->fs, cb->txn, old_rev, changed_paths, pool));
/* We are going to be one better than this puny old revision. */
new_rev = old_rev + 1;
@@ -3167,9 +3142,8 @@ commit_body(void *baton, apr_pool_t *poo
/* Write out all the node-revisions and directory contents. */
root_id = svn_fs_x__id_txn_create_root(txn_id, pool);
SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
- start_node_id, start_copy_id, initial_offset,
- cb->reps_to_cache, cb->reps_hash, cb->reps_pool,
- TRUE, pool));
+ initial_offset, cb->reps_to_cache, cb->reps_hash,
+ cb->reps_pool, TRUE, pool));
/* Write the changed-path information. */
SVN_ERR(write_final_changed_path_info(&changed_path_offset, proto_file,
@@ -3393,12 +3367,12 @@ svn_fs_x__open_txn(svn_fs_txn_t **txn_p,
fs_txn_data_t *ftd;
svn_node_kind_t kind;
transaction_t *local_txn;
- svn_fs_x__id_part_t txn_id;
+ svn_fs_x__txn_id_t txn_id;
- SVN_ERR(svn_fs_x__id_txn_parse(&txn_id, name));
+ SVN_ERR(svn_fs_x__txn_by_name(&txn_id, name));
/* First check to see if the directory exists. */
- SVN_ERR(svn_io_check_path(svn_fs_x__path_txn_dir(fs, &txn_id, pool),
+ SVN_ERR(svn_io_check_path(svn_fs_x__path_txn_dir(fs, txn_id, pool),
&kind, pool));
/* Did we find it? */
@@ -3415,7 +3389,7 @@ svn_fs_x__open_txn(svn_fs_txn_t **txn_p,
txn->id = apr_pstrdup(pool, name);
txn->fs = fs;
- SVN_ERR(svn_fs_x__get_txn(&local_txn, fs, &txn_id, pool));
+ SVN_ERR(svn_fs_x__get_txn(&local_txn, fs, txn_id, pool));
txn->base_rev = svn_fs_x__id_rev(local_txn->base_id);
@@ -3450,13 +3424,13 @@ svn_fs_x__delete_node_revision(svn_fs_t
/* Delete any mutable property representation. */
if (noderev->prop_rep
- && svn_fs_x__id_txn_used(&noderev->prop_rep->txn_id))
+ && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
SVN_ERR(svn_io_remove_file2(svn_fs_x__path_txn_node_props(fs, id, pool),
FALSE, pool));
/* Delete any mutable data representation. */
if (noderev->data_rep
- && svn_fs_x__id_txn_used(&noderev->data_rep->txn_id)
+ && svn_fs_x__is_txn(noderev->data_rep->id.change_set)
&& noderev->kind == svn_node_dir)
{
fs_x_data_t *ffd = fs->fsap_data;
@@ -3484,7 +3458,7 @@ svn_error_t *
svn_fs_x__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 svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
transaction_t *txn;
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.h?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/transaction.h Mon Feb 17 05:53:23 2014
@@ -27,7 +27,7 @@
/* Return the transaction ID of TXN.
*/
-const svn_fs_x__id_part_t *
+svn_fs_x__txn_id_t
svn_fs_x__txn_get_id(svn_fs_txn_t *txn);
/* Obtain a write lock on the filesystem FS in a subpool of POOL, call
@@ -56,7 +56,7 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
svn_error_t *
svn_fs_x__txn_changes_fetch(apr_hash_t **changed_paths_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Find the paths which were changed in revision REV of filesystem FS
@@ -97,7 +97,7 @@ svn_fs_x__change_txn_props(svn_fs_txn_t
svn_error_t *
svn_fs_x__get_txn(transaction_t **txn_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Return the next available copy_id in *COPY_ID for the transaction
@@ -105,7 +105,7 @@ svn_fs_x__get_txn(transaction_t **txn_p,
svn_error_t *
svn_fs_x__reserve_copy_id(svn_fs_x__id_part_t *copy_id_p,
svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Create an entirely new mutable node in the filesystem FS, whose
@@ -118,7 +118,7 @@ svn_fs_x__create_node(const svn_fs_id_t
svn_fs_t *fs,
node_revision_t *noderev,
const svn_fs_x__id_part_t *copy_id,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Remove all references to the transaction TXN_ID from filesystem FS.
@@ -139,7 +139,7 @@ svn_fs_x__abort_txn(svn_fs_txn_t *txn,
KIND. Allocations are done in POOL. */
svn_error_t *
svn_fs_x__set_entry(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
node_revision_t *parent_noderev,
const char *name,
const svn_fs_id_t *id,
@@ -156,7 +156,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
from POOL. */
svn_error_t *
svn_fs_x__add_change(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
const char *path,
const svn_fs_id_t *id,
svn_fs_path_change_kind_t change_kind,
@@ -196,7 +196,7 @@ svn_fs_x__create_successor(const svn_fs_
const svn_fs_id_t *old_idp,
node_revision_t *new_noderev,
const svn_fs_x__id_part_t *copy_id,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Write a new property list PROPLIST for node-revision NODEREV in
@@ -266,7 +266,7 @@ svn_error_t *
svn_fs_x__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 svn_fs_x__id_part_t *txn_name,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Find the value of the property named PROPNAME in transaction TXN.
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/tree.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/tree.c Mon Feb 17 05:53:23 2014
@@ -60,6 +60,7 @@
#include "cached_data.h"
#include "transaction.h"
#include "pack.h"
+#include "util.h"
#include "private/svn_mergeinfo_private.h"
#include "private/svn_subr_private.h"
@@ -107,8 +108,8 @@ typedef dag_node_t fs_rev_root_data_t;
typedef struct fs_txn_root_data_t
{
/* TXN_ID value from the main struct but as a struct instead of a string */
- svn_fs_x__id_part_t txn_id;
-
+ svn_fs_x__txn_id_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;
@@ -127,7 +128,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 svn_fs_x__id_part_t *txn,
+ svn_fs_x__txn_id_t txn_id,
svn_revnum_t base_rev,
apr_uint32_t flags,
apr_pool_t *pool);
@@ -640,13 +641,13 @@ svn_fs_x__revision_root(svn_fs_root_t **
/* Getting dag nodes for roots. */
/* Return the transaction ID to a given transaction ROOT. */
-static const svn_fs_x__id_part_t *
+static svn_fs_x__txn_id_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
@@ -1108,7 +1109,7 @@ make_path_mutable(svn_fs_root_t *root,
apr_pool_t *pool)
{
dag_node_t *clone;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(root);
+ svn_fs_x__txn_id_t txn_id = root_txn_id(root);
/* Is the node mutable already? */
if (svn_fs_x__dag_check_mutable(parent_path->node))
@@ -1260,7 +1261,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 svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
const char *path,
const svn_fs_id_t *noderev_id,
svn_fs_path_change_kind_t change_kind,
@@ -1318,7 +1319,7 @@ x_node_relation(svn_fs_node_relation_t *
{
dag_node_t *node;
const svn_fs_id_t *id;
- svn_fs_x__id_part_t rev_item_a, rev_item_b, node_id_a, node_id_b;
+ svn_fs_x__id_part_t noderev_id_a, noderev_id_b, node_id_a, node_id_b;
/* Root paths are a common special case. */
svn_boolean_t a_is_root_dir
@@ -1356,15 +1357,15 @@ x_node_relation(svn_fs_node_relation_t *
* Now, we can simply test for the ID values themselves. */
SVN_ERR(get_dag(&node, root_a, path_a, FALSE, pool));
id = svn_fs_x__dag_get_id(node);
- rev_item_a = *svn_fs_x__id_rev_item(id);
+ noderev_id_a = *svn_fs_x__id_noderev_id(id);
node_id_a = *svn_fs_x__id_node_id(id);
SVN_ERR(get_dag(&node, root_b, path_b, FALSE, pool));
id = svn_fs_x__dag_get_id(node);
- rev_item_b = *svn_fs_x__id_rev_item(id);
+ noderev_id_b = *svn_fs_x__id_noderev_id(id);
node_id_b = *svn_fs_x__id_node_id(id);
- if (svn_fs_x__id_part_eq(&rev_item_a, &rev_item_b))
+ if (svn_fs_x__id_part_eq(&noderev_id_a, &noderev_id_b))
*relation = svn_fs_node_same;
else if (svn_fs_x__id_part_eq(&node_id_a, &node_id_b))
*relation = svn_fs_node_common_anchestor;
@@ -1519,7 +1520,7 @@ x_change_node_prop(svn_fs_root_t *root,
{
parent_path_t *parent_path;
apr_hash_t *proplist;
- const svn_fs_x__id_part_t *txn_id;
+ svn_fs_x__txn_id_t txn_id;
if (! root->is_txn_root)
return SVN_FS__NOT_TXN(root);
@@ -1709,7 +1710,7 @@ merge(svn_stringbuf_t *conflict_p,
dag_node_t *target,
dag_node_t *source,
dag_node_t *ancestor,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_int64_t *mergeinfo_increment_out,
apr_pool_t *pool)
{
@@ -2072,7 +2073,7 @@ merge_changes(dag_node_t *ancestor_node,
{
dag_node_t *txn_root_node;
svn_fs_t *fs = txn->fs;
- const svn_fs_x__id_part_t *txn_id = svn_fs_x__txn_get_id(txn);
+ svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(txn);
SVN_ERR(svn_fs_x__dag_txn_root(&txn_root_node, fs, txn_id, pool));
@@ -2352,7 +2353,7 @@ x_make_dir(svn_fs_root_t *root,
{
parent_path_t *parent_path;
dag_node_t *sub_dir;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(root);
+ svn_fs_x__txn_id_t txn_id = root_txn_id(root);
path = svn_fs__canonicalize_abspath(path, pool);
SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
@@ -2399,7 +2400,7 @@ x_delete_node(svn_fs_root_t *root,
apr_pool_t *pool)
{
parent_path_t *parent_path;
- const svn_fs_x__id_part_t *txn_id;
+ svn_fs_x__txn_id_t txn_id;
apr_int64_t mergeinfo_count = 0;
svn_node_kind_t kind;
@@ -2548,7 +2549,7 @@ copy_helper(svn_fs_root_t *from_root,
{
dag_node_t *from_node;
parent_path_t *to_parent_path;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(to_root);
+ svn_fs_x__txn_id_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
@@ -2576,11 +2577,11 @@ copy_helper(svn_fs_root_t *from_root,
{
/* if we don't copy from the TXN's base rev, check that the path has
not been touched in that revision range */
- if (from_root->rev != txn_id->revision)
+ if (from_root->rev != to_root->rev)
{
svn_boolean_t changed = TRUE;
svn_error_t *err = is_changed_node(&changed, from_root,
- from_path, txn_id->revision,
+ from_path, to_root->rev,
pool);
/* Only "not found" is considered to be caused by out-of-date-ness.
@@ -2598,7 +2599,7 @@ copy_helper(svn_fs_root_t *from_root,
/* always move from the txn's base rev */
SVN_ERR(svn_fs_x__revision_root(&from_root, from_root->fs,
- txn_id->revision, pool));
+ to_root->rev, pool));
}
}
@@ -2801,7 +2802,7 @@ x_make_file(svn_fs_root_t *root,
{
parent_path_t *parent_path;
dag_node_t *child;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(root);
+ svn_fs_x__txn_id_t txn_id = root_txn_id(root);
path = svn_fs__canonicalize_abspath(path, pool);
SVN_ERR(open_path(&parent_path, root, path, open_path_last_optional,
@@ -3035,7 +3036,7 @@ apply_textdelta(void *baton, apr_pool_t
{
txdelta_baton_t *tb = (txdelta_baton_t *) baton;
parent_path_t *parent_path;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(tb->root);
+ svn_fs_x__txn_id_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. */
@@ -3200,7 +3201,7 @@ apply_text(void *baton, apr_pool_t *pool
{
struct text_baton_t *tb = baton;
parent_path_t *parent_path;
- const svn_fs_x__id_part_t *txn_id = root_txn_id(tb->root);
+ svn_fs_x__txn_id_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. */
@@ -3518,172 +3519,22 @@ svn_error_t *x_closest_copy(svn_fs_root_
}
-/* Set *PREV_PATH and *PREV_REV to the path and revision which
- represent the location at which PATH in FS was located immediately
- prior to REVISION iff there was a copy operation (to PATH or one of
- its parent directories) between that previous location and
- PATH@REVISION.
-
- If there was no such copy operation in that portion of PATH's
- history, set *PREV_PATH to NULL and *PREV_REV to SVN_INVALID_REVNUM. */
-static svn_error_t *
-prev_location(const char **prev_path,
- svn_revnum_t *prev_rev,
- svn_fs_t *fs,
- svn_fs_root_t *root,
- const char *path,
- apr_pool_t *pool)
-{
- const char *copy_path, *copy_src_path, *remainder_path;
- svn_fs_root_t *copy_root;
- svn_revnum_t copy_src_rev;
-
- /* Ask about the most recent copy which affected PATH@REVISION. If
- there was no such copy, we're done. */
- SVN_ERR(x_closest_copy(©_root, ©_path, root, path, pool));
- if (! copy_root)
- {
- *prev_rev = SVN_INVALID_REVNUM;
- *prev_path = NULL;
- return SVN_NO_ERROR;
- }
-
- /* Ultimately, it's not the path of the closest copy's source that
- we care about -- it's our own path's location in the copy source
- revision. So we'll tack the relative path that expresses the
- difference between the copy destination and our path in the copy
- revision onto the copy source path to determine this information.
-
- In other words, if our path is "/branches/my-branch/foo/bar", and
- we know that the closest relevant copy was a copy of "/trunk" to
- "/branches/my-branch", then that relative path under the copy
- destination is "/foo/bar". Tacking that onto the copy source
- path tells us that our path was located at "/trunk/foo/bar"
- before the copy.
- */
- SVN_ERR(x_copied_from(©_src_rev, ©_src_path,
- copy_root, copy_path, pool));
- remainder_path = svn_fspath__skip_ancestor(copy_path, path);
- *prev_path = svn_fspath__join(copy_src_path, remainder_path, pool);
- *prev_rev = copy_src_rev;
- return SVN_NO_ERROR;
-}
-
-
static svn_error_t *
x_node_origin_rev(svn_revnum_t *revision,
svn_fs_root_t *root,
const char *path,
apr_pool_t *pool)
{
- svn_fs_t *fs = root->fs;
- const svn_fs_id_t *given_noderev_id, *cached_origin_id;
+ const svn_fs_id_t *given_noderev_id;
const svn_fs_x__id_part_t *node_id;
path = svn_fs__canonicalize_abspath(path, pool);
- /* Check the cache first. */
SVN_ERR(svn_fs_x__node_id(&given_noderev_id, root, path, pool));
node_id = svn_fs_x__id_node_id(given_noderev_id);
+ *revision = svn_fs_x__get_revnum(node_id->change_set);
- /* Is it a brand new uncommitted node or a new-style one?
- * (committed old-style nodes will have a 0 revision value;
- * rev 0, number 0 is rev 0 root node) */
- if (node_id->revision != 0 || node_id->number == 0)
- {
- *revision = node_id->revision;
- 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 (node_id->number == 0)
- {
- *revision = 0;
- return SVN_NO_ERROR;
- }
-
- /* OK, it's an old-style ID? Maybe it's cached. */
- SVN_ERR(svn_fs_x__get_node_origin(&cached_origin_id, fs, node_id, pool));
- if (cached_origin_id != NULL)
- {
- *revision = svn_fs_x__id_rev(cached_origin_id);
- return SVN_NO_ERROR;
- }
-
- {
- /* Ah well, the answer isn't in the ID itself or in the cache.
- Let's actually calculate it, then. */
- svn_fs_root_t *curroot = root;
- apr_pool_t *subpool = svn_pool_create(pool);
- apr_pool_t *predidpool = svn_pool_create(pool);
- svn_stringbuf_t *lastpath = svn_stringbuf_create(path, pool);
- svn_revnum_t lastrev = SVN_INVALID_REVNUM;
- dag_node_t *node;
- const svn_fs_id_t *pred_id;
-
- /* Walk the closest-copy chain back to the first copy in our history.
-
- NOTE: We merely *assume* that this is faster than walking the
- predecessor chain, because we *assume* that copies of parent
- directories happen less often than modifications to a given item. */
- while (1)
- {
- svn_revnum_t currev;
- const char *curpath = lastpath->data;
-
- svn_pool_clear(subpool);
-
- /* Get a root pointing to LASTREV. (The first time around,
- LASTREV is invalid, but that's cool because CURROOT is
- already initialized.) */
- if (SVN_IS_VALID_REVNUM(lastrev))
- SVN_ERR(svn_fs_x__revision_root(&curroot, fs, lastrev, subpool));
-
- /* Find the previous location using the closest-copy shortcut. */
- SVN_ERR(prev_location(&curpath, &currev, fs, curroot, curpath,
- subpool));
- if (! curpath)
- break;
-
- /* Update our LASTPATH and LASTREV variables (which survive
- SUBPOOL). */
- svn_stringbuf_set(lastpath, curpath);
- lastrev = currev;
- }
-
- /* Walk the predecessor links back to origin. */
- SVN_ERR(svn_fs_x__node_id(&pred_id, curroot, lastpath->data, predidpool));
- do
- {
- svn_pool_clear(subpool);
- SVN_ERR(svn_fs_x__dag_get_node(&node, fs, pred_id, subpool));
-
- /* Why not just fetch the predecessor ID in PREDIDPOOL?
- Because svn_fs_x__dag_get_predecessor_id() doesn't
- necessarily honor the passed-in pool, and might return a
- value cached in the node (which is allocated in
- SUBPOOL... maybe). */
- svn_pool_clear(predidpool);
- SVN_ERR(svn_fs_x__dag_get_predecessor_id(&pred_id, node));
- pred_id = pred_id ? svn_fs_x__id_copy(pred_id, predidpool) : NULL;
- }
- while (pred_id);
-
- /* When we get here, NODE should be the first node-revision in our
- chain. */
- SVN_ERR(svn_fs_x__dag_get_revision(revision, node, pool));
-
- /* Wow, I don't want to have to do all that again. Let's cache
- the result. */
- if (node_id->revision != SVN_INVALID_REVNUM)
- SVN_ERR(svn_fs_x__set_node_origin(fs, node_id,
- svn_fs_x__dag_get_id(node), pool));
-
- svn_pool_destroy(subpool);
- svn_pool_destroy(predidpool);
- return SVN_NO_ERROR;
- }
+ return SVN_NO_ERROR;
}
@@ -4394,17 +4245,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 svn_fs_x__id_part_t *txn,
+ svn_fs_x__txn_id_t txn_id,
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 = *txn;
+ frd->txn_id = txn_id;
root->is_txn_root = TRUE;
- root->txn = svn_fs_x__id_txn_unparse(txn, root->pool);
+ root->txn = svn_fs_x__txn_name(txn_id, root->pool);
root->txn_flags = flags;
root->rev = base_rev;
@@ -4418,7 +4269,7 @@ make_txn_root(svn_fs_root_t **root_p,
svn_fs_x__dag_deserialize,
APR_HASH_KEY_STRING,
32, 20, FALSE,
- apr_pstrcat(pool, txn, ":TXN",
+ apr_pstrcat(pool, root->txn, ":TXN",
SVN_VA_NULL),
root->pool));
@@ -4581,7 +4432,7 @@ svn_fs_x__verify_root(svn_fs_root_t *roo
if (root->is_txn_root)
{
fs_txn_root_data_t *frd = root->fsap_data;
- SVN_ERR(svn_fs_x__dag_txn_root(&root_dir, fs, &frd->txn_id, pool));
+ SVN_ERR(svn_fs_x__dag_txn_root(&root_dir, fs, frd->txn_id, pool));
}
else
{
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.c Mon Feb 17 05:53:23 2014
@@ -226,24 +226,47 @@ svn_fs_x__path_revprops(svn_fs_t *fs, sv
pool);
}
+const char *
+svn_fs_x__txn_name(svn_fs_x__txn_id_t txn_id,
+ apr_pool_t *pool)
+{
+ char *p = apr_palloc(pool, SVN_INT64_BUFFER_SIZE);
+ svn__ui64tobase36(p, txn_id);
+ return p;
+}
+
+svn_error_t *
+svn_fs_x__txn_by_name(svn_fs_x__txn_id_t *txn_id,
+ const char *txn_name)
+{
+ const char *next;
+ apr_uint64_t id = svn__base36toui64(&next, txn_name);
+ if (next == NULL || *next != 0 || *txn_name == 0)
+ return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+ "Malformed TXN name '%s'", txn_name);
+
+ *txn_id = id;
+ return SVN_NO_ERROR;
+}
+
+
/* Return TO_ADD appended to the C string representation of TXN_ID.
* Allocate the result in POOL.
*/
static const char *
-combine_txn_id_string(const svn_fs_x__id_part_t *txn_id,
+combine_txn_id_string(svn_fs_x__txn_id_t txn_id,
const char *to_add,
apr_pool_t *pool)
{
- return apr_pstrcat(pool, svn_fs_x__id_txn_unparse(txn_id, pool),
+ return apr_pstrcat(pool, svn_fs_x__txn_name(txn_id, pool),
to_add, SVN_VA_NULL);
}
const char *
svn_fs_x__path_txn_dir(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
- SVN_ERR_ASSERT_NO_RETURN(txn_id != NULL);
return svn_dirent_join_many(pool, fs->path, PATH_TXNS_DIR,
combine_txn_id_string(txn_id, PATH_EXT_TXN,
pool),
@@ -255,7 +278,7 @@ svn_fs_x__path_txn_dir(svn_fs_t *fs,
*/
const char *
svn_fs_x__path_txn_sha1(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
const unsigned char *sha1,
apr_pool_t *pool)
{
@@ -270,7 +293,7 @@ svn_fs_x__path_txn_sha1(svn_fs_t *fs,
const char *
svn_fs_x__path_txn_changes(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -279,7 +302,7 @@ svn_fs_x__path_txn_changes(svn_fs_t *fs,
const char *
svn_fs_x__path_txn_props(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -288,7 +311,7 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
const char *
svn_fs_x__path_txn_props_final(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -297,7 +320,7 @@ svn_fs_x__path_txn_props_final(svn_fs_t
const char*
svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -306,7 +329,7 @@ svn_fs_x__path_l2p_proto_index(svn_fs_t
const char*
svn_fs_x__path_p2l_proto_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -315,7 +338,7 @@ svn_fs_x__path_p2l_proto_index(svn_fs_t
const char *
svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -330,7 +353,7 @@ svn_fs_x__path_min_unpacked_rev(svn_fs_t
const char *
svn_fs_x__path_txn_item_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
@@ -339,7 +362,7 @@ svn_fs_x__path_txn_item_index(svn_fs_t *
const char *
svn_fs_x__path_txn_proto_rev(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR,
@@ -350,7 +373,7 @@ svn_fs_x__path_txn_proto_rev(svn_fs_t *f
const char *
svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool)
{
return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR,
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.h?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/util.h Mon Feb 17 05:53:23 2014
@@ -153,8 +153,16 @@ svn_fs_x__path_revprops(svn_fs_t *fs,
apr_pool_t *pool);
const char *
+svn_fs_x__txn_name(svn_fs_x__txn_id_t txn_id,
+ apr_pool_t *pool);
+
+svn_error_t *
+svn_fs_x__txn_by_name(svn_fs_x__txn_id_t *txn_id,
+ const char *txn_name);
+
+const char *
svn_fs_x__path_txn_dir(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
/* Return the name of the sha1->rep mapping file in transaction TXN_ID
@@ -162,38 +170,38 @@ svn_fs_x__path_txn_dir(svn_fs_t *fs,
*/
const char *
svn_fs_x__path_txn_sha1(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
const unsigned char *sha1,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_changes(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char*
svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char*
svn_fs_x__path_p2l_proto_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_props(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_props_final(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
@@ -203,17 +211,17 @@ svn_fs_x__path_min_unpacked_rev(svn_fs_t
const char *
svn_fs_x__path_txn_item_index(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_proto_rev(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
svn_fs_x__path_txn_proto_rev_lock(svn_fs_t *fs,
- const svn_fs_x__id_part_t *txn_id,
+ svn_fs_x__txn_id_t txn_id,
apr_pool_t *pool);
const char *
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/verify.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_fs_x/verify.c Mon Feb 17 05:53:23 2014
@@ -78,13 +78,14 @@ verify_walker(representation_t *rep,
if ( walker_baton->iteration_count > 1000
|| walker_baton->file_count > 16)
{
+ svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set);
if ( walker_baton->notify_func
- && rep->revision != walker_baton->last_notified_revision)
+ && revision != walker_baton->last_notified_revision)
{
- walker_baton->notify_func(rep->revision,
+ walker_baton->notify_func(revision,
walker_baton->notify_baton,
scratch_pool);
- walker_baton->last_notified_revision = rep->revision;
+ walker_baton->last_notified_revision = revision;
}
svn_pool_clear(walker_baton->pool);
@@ -186,11 +187,15 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
{
apr_off_t offset;
apr_uint32_t sub_item;
+ svn_fs_x__id_part_t l2p_item;
svn_fs_x__id_part_t *p2l_item;
+ l2p_item.change_set = svn_fs_x__change_set_by_rev(revision);
+ l2p_item.number = k;
+
/* get L2P entry. Ignore unused entries. */
- SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
- revision, NULL, k, iterpool));
+ SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, &l2p_item,
+ iterpool));
if (offset == -1)
continue;
@@ -207,13 +212,13 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
apr_off_t_toa(pool, offset),
(long)sub_item, revision, (long)k);
- if (p2l_item->number != k || p2l_item->revision != revision)
+ if (!svn_fs_x__id_part_eq(&l2p_item, p2l_item))
return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT,
NULL,
_("p2l index info LOG r%ld:i%ld"
" does not match "
"l2p index for LOG r%ld:i%ld"),
- p2l_item->revision,
+ svn_fs_x__get_revnum(p2l_item->change_set),
(long)p2l_item->number, revision,
(long)k);
@@ -287,10 +292,11 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
apr_off_t l2p_offset;
apr_uint32_t sub_item;
svn_fs_x__id_part_t *p2l_item = &entry->items[k];
+ svn_revnum_t revision
+ = svn_fs_x__get_revnum(p2l_item->change_set);
SVN_ERR(svn_fs_x__item_offset(&l2p_offset, &sub_item, fs,
- p2l_item->revision, NULL,
- p2l_item->number, iterpool));
+ p2l_item, iterpool));
if (sub_item != k || l2p_offset != entry->offset)
return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT,
@@ -300,7 +306,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
"LOG r%ld:i%ld for PHYS o%s:s%ld"),
apr_off_t_toa(pool, l2p_offset),
(long)sub_item,
- p2l_item->revision,
+ revision,
(long)p2l_item->number,
apr_off_t_toa(pool, entry->offset),
(long)k);
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/log.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/log.c Mon Feb 17 05:53:23 2014
@@ -602,7 +602,7 @@ svn_ra_serf__get_log(svn_ra_session_t *r
/* At this point, we may have a deleted file. So, we'll match ra_neon's
* behavior and use the larger of start or end as our 'peg' rev.
*/
- peg_rev = (start > end) ? start : end;
+ peg_rev = (start == SVN_INVALID_REVNUM || start > end) ? start : end;
SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
session, NULL /* conn */,
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/options.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/options.c Mon Feb 17 05:53:23 2014
@@ -368,7 +368,7 @@ options_response_handler(serf_request_t
serf_bucket_headers_do(hdrs, capabilities_headers_iterator_callback,
opt_ctx);
- /* Assume mergeinfo capability unsupported, if didn't recieve information
+ /* Assume mergeinfo capability unsupported, if didn't receive information
about server or repository mergeinfo capability. */
if (!svn_hash_gets(session->capabilities, SVN_RA_CAPABILITY_MERGEINFO))
svn_hash_sets(session->capabilities, SVN_RA_CAPABILITY_MERGEINFO,
Modified: subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/util.c?rev=1568883&r1=1568882&r2=1568883&view=diff
==============================================================================
--- subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/fsfs-ucsnorm/subversion/libsvn_ra_serf/util.c Mon Feb 17 05:53:23 2014
@@ -213,7 +213,6 @@ ssl_server_cert(void *baton, int failure
apr_hash_t *subject = NULL;
apr_hash_t *serf_cert = NULL;
void *creds;
- int found_matching_hostname = 0;
svn_failures = (ssl_convert_serf_failures(failures)
| conn->server_cert_failures);
@@ -225,26 +224,36 @@ ssl_server_cert(void *baton, int failure
### This should really be handled by serf, which should pass an error
for this case, but that has backwards compatibility issues. */
apr_array_header_t *san;
+ svn_boolean_t found_san_entry = FALSE;
+ svn_boolean_t found_matching_hostname = FALSE;
serf_cert = serf_ssl_cert_certificate(cert, scratch_pool);
san = svn_hash_gets(serf_cert, "subjectAltName");
/* Try to find matching server name via subjectAltName first... */
- if (san) {
+ if (san)
+ {
int i;
- for (i = 0; i < san->nelts; i++) {
+ found_san_entry = san->nelts > 0;
+ for (i = 0; i < san->nelts; i++)
+ {
const char *s = APR_ARRAY_IDX(san, i, const char*);
- if (apr_fnmatch(s, conn->session->session_url.hostname,
- APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
- {
- found_matching_hostname = 1;
+ if (APR_SUCCESS == apr_fnmatch(s,
+ conn->session->session_url.hostname,
+ APR_FNM_PERIOD |
+ APR_FNM_CASE_BLIND))
+ {
+ found_matching_hostname = TRUE;
break;
- }
- }
- }
+ }
+ }
+ }
- /* Match server certificate CN with the hostname of the server */
- if (!found_matching_hostname)
+ /* Match server certificate CN with the hostname of the server iff
+ * we didn't find any subjectAltName fields and try to match them.
+ * Per RFC 2818 they are authoritative if present and CommonName
+ * should be ignored. */
+ if (!found_matching_hostname && !found_san_entry)
{
const char *hostname = NULL;
@@ -253,13 +262,16 @@ ssl_server_cert(void *baton, int failure
if (subject)
hostname = svn_hash_gets(subject, "CN");
- if (!hostname
- || apr_fnmatch(hostname, conn->session->session_url.hostname,
- APR_FNM_PERIOD | APR_FNM_CASE_BLIND) != APR_SUCCESS)
- {
- svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
- }
- }
+ if (hostname
+ && apr_fnmatch(hostname, conn->session->session_url.hostname,
+ APR_FNM_PERIOD | APR_FNM_CASE_BLIND) == APR_SUCCESS)
+ {
+ found_matching_hostname = TRUE;
+ }
+ }
+
+ if (!found_matching_hostname)
+ svn_failures |= SVN_AUTH_SSL_CNMISMATCH;
}
if (!svn_failures)