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
