subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From g..@apache.org
Subject svn commit: r1526487 [6/10] - in /subversion/branches/invoke-diff-cmd-feature: ./ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ notes/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apach...
Date Thu, 26 Sep 2013 13:47:26 GMT
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.h?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.h Thu Sep 26 13:47:21 2013
@@ -45,162 +45,19 @@ svn_error_t *svn_fs_fs__upgrade(svn_fs_t
                                 void *cancel_baton,
                                 apr_pool_t *pool);
 
-/* Verify metadata in fsfs filesystem FS.  Limit the checks to revisions
- * START to END where possible.  Indicate progress via the optional
- * NOTIFY_FUNC callback using NOTIFY_BATON.  The optional CANCEL_FUNC
- * will periodically be called with CANCEL_BATON to allow for preemption.
- * Use POOL for temporary allocations. */
-svn_error_t *svn_fs_fs__verify(svn_fs_t *fs,
-                               svn_revnum_t start,
-                               svn_revnum_t end,
-                               svn_fs_progress_notify_func_t notify_func,
-                               void *notify_baton,
-                               svn_cancel_func_t cancel_func,
-                               void *cancel_baton,
-                               apr_pool_t *pool);
-
-/* Copy the fsfs filesystem SRC_FS at SRC_PATH into a new copy DST_FS at
- * DST_PATH. If INCREMENTAL is TRUE, do not re-copy data which already
- * exists in DST_FS. Use POOL for temporary allocations. */
-svn_error_t * svn_fs_fs__hotcopy(svn_fs_t *src_fs,
-                                 svn_fs_t *dst_fs,
-                                 const char *src_path,
-                                 const char *dst_path,
-                                 svn_boolean_t incremental,
-                                 svn_cancel_func_t cancel_func,
-                                 void *cancel_baton,
-                                 apr_pool_t *pool);
-
-/* Recover the fsfs associated with filesystem FS.
-   Use optional CANCEL_FUNC/CANCEL_BATON for cancellation support.
-   Use POOL for temporary allocations. */
-svn_error_t *svn_fs_fs__recover(svn_fs_t *fs,
-                                svn_cancel_func_t cancel_func,
-                                void *cancel_baton,
-                                apr_pool_t *pool);
-
-/* Set *NODEREV_P to the node-revision for the node ID in FS.  Do any
-   allocations in POOL. */
-svn_error_t *svn_fs_fs__get_node_revision(node_revision_t **noderev_p,
-                                          svn_fs_t *fs,
-                                          const svn_fs_id_t *id,
-                                          apr_pool_t *pool);
-
-/* Store NODEREV as the node-revision for the node whose id is ID in
-   FS, after setting its is_fresh_txn_root to FRESH_TXN_ROOT.  Do any
-   necessary temporary allocation in POOL. */
-svn_error_t *svn_fs_fs__put_node_revision(svn_fs_t *fs,
-                                          const svn_fs_id_t *id,
-                                          node_revision_t *noderev,
-                                          svn_boolean_t fresh_txn_root,
-                                          apr_pool_t *pool);
-
-/* Write the node-revision NODEREV into the stream OUTFILE, compatible with
-   filesystem format FORMAT.  Only write mergeinfo-related metadata if
-   INCLUDE_MERGEINFO is true.  Temporary allocations are from POOL. */
-/* ### Currently used only by fs_fs.c */
-svn_error_t *
-svn_fs_fs__write_noderev(svn_stream_t *outfile,
-                         node_revision_t *noderev,
-                         int format,
-                         svn_boolean_t include_mergeinfo,
-                         apr_pool_t *pool);
-
-/* Read a node-revision from STREAM. Set *NODEREV to the new structure,
-   allocated in POOL. */
-/* ### Currently used only by fs_fs.c */
-svn_error_t *
-svn_fs_fs__read_noderev(node_revision_t **noderev,
-                        svn_stream_t *stream,
-                        apr_pool_t *pool);
-
-
 /* Set *YOUNGEST to the youngest revision in filesystem FS.  Do any
    temporary allocation in POOL. */
 svn_error_t *svn_fs_fs__youngest_rev(svn_revnum_t *youngest,
                                      svn_fs_t *fs,
                                      apr_pool_t *pool);
 
-/* Return an error iff REV does not exist in FS. */
-svn_error_t *
-svn_fs_fs__revision_exists(svn_revnum_t rev,
-                           svn_fs_t *fs,
-                           apr_pool_t *pool);
-
-/* Set *ROOT_ID to the node-id for the root of revision REV in
-   filesystem FS.  Do any allocations in POOL. */
-svn_error_t *svn_fs_fs__rev_get_root(svn_fs_id_t **root_id,
-                                     svn_fs_t *fs,
-                                     svn_revnum_t rev,
-                                     apr_pool_t *pool);
-
-/* Set *ENTRIES to an apr_hash_t of dirent structs that contain the
-   directory entries of node-revision NODEREV in filesystem FS.  The
-   returned table (and its keys and values) is allocated in POOL,
-   which is also used for temporary allocations. */
-svn_error_t *svn_fs_fs__rep_contents_dir(apr_hash_t **entries,
-                                         svn_fs_t *fs,
-                                         node_revision_t *noderev,
-                                         apr_pool_t *pool);
-
-/* Set *DIRENT to the entry identified by NAME in the directory given
-   by NODEREV in filesystem FS.  If no such entry exits, *DIRENT will
-   be NULL. The returned object is allocated in RESULT_POOL; SCRATCH_POOL
-   used for temporary allocations. */
+/* Return SVN_ERR_FS_NO_SUCH_REVISION if the given revision REV is newer
+   than the current youngest revision in FS or is simply not a valid
+   revision number, else return success. */
 svn_error_t *
-svn_fs_fs__rep_contents_dir_entry(svn_fs_dirent_t **dirent,
+svn_fs_fs__ensure_revision_exists(svn_revnum_t rev,
                                   svn_fs_t *fs,
-                                  node_revision_t *noderev,
-                                  const char *name,
-                                  apr_pool_t *result_pool,
-                                  apr_pool_t *scratch_pool);
-
-/* Set *CONTENTS to be a readable svn_stream_t that receives the text
-   representation of node-revision NODEREV as seen in filesystem FS.
-   Use POOL for temporary allocations. */
-svn_error_t *svn_fs_fs__get_contents(svn_stream_t **contents,
-                                     svn_fs_t *fs,
-                                     node_revision_t *noderev,
-                                     apr_pool_t *pool);
-
-/* Attempt to fetch the text representation of node-revision NODEREV as
-   seen in filesystem FS and pass it along with the BATON to the PROCESSOR.
-   Set *SUCCESS only of the data could be provided and the processing
-   had been called.
-   Use POOL for all allocations.
- */
-svn_error_t *
-svn_fs_fs__try_process_file_contents(svn_boolean_t *success,
-                                     svn_fs_t *fs,
-                                     node_revision_t *noderev,
-                                     svn_fs_process_contents_func_t processor,
-                                     void* baton,
-                                     apr_pool_t *pool);
-
-/* Set *STREAM_P to a delta stream turning the contents of the file SOURCE into
-   the contents of the file TARGET, allocated in POOL.
-   If SOURCE is null, the empty string will be used. */
-svn_error_t *svn_fs_fs__get_file_delta_stream(svn_txdelta_stream_t **stream_p,
-                                              svn_fs_t *fs,
-                                              node_revision_t *source,
-                                              node_revision_t *target,
-                                              apr_pool_t *pool);
-
-/* Set *PROPLIST to be an apr_hash_t containing the property list of
-   node-revision NODEREV as seen in filesystem FS.  Use POOL for
-   temporary allocations. */
-svn_error_t *svn_fs_fs__get_proplist(apr_hash_t **proplist,
-                                     svn_fs_t *fs,
-                                     node_revision_t *noderev,
-                                     apr_pool_t *pool);
-
-/* Set *PROPLIST to be an apr_hash_t containing the property list of
-   revision REV as seen in filesystem FS.  Use POOL for temporary
-   allocations. */
-svn_error_t *svn_fs_fs__revision_proplist(apr_hash_t **proplist,
-                                          svn_fs_t *fs,
-                                          svn_revnum_t rev,
-                                          apr_pool_t *pool);
+                                  apr_pool_t *pool);
 
 /* Set *LENGTH to the be fulltext length of the node revision
    specified by NODEREV.  Use POOL for temporary allocations. */
@@ -227,155 +84,9 @@ svn_error_t *svn_fs_fs__file_checksum(sv
                                       svn_checksum_kind_t kind,
                                       apr_pool_t *pool);
 
-/* Find the paths which were changed in revision REV of filesystem FS
-   and store them in *CHANGED_PATHS_P.  Cached copyfrom information
-   will be stored in *COPYFROM_CACHE.  Get any temporary allocations
-   from POOL. */
-svn_error_t *svn_fs_fs__paths_changed(apr_hash_t **changed_paths_p,
-                                      svn_fs_t *fs,
-                                      svn_revnum_t rev,
-                                      apr_hash_t *copyfrom_cache,
-                                      apr_pool_t *pool);
-
-/* Create a new transaction in filesystem FS, based on revision REV,
-   and store it in *TXN_P.  Allocate all necessary variables from
-   POOL. */
-svn_error_t *svn_fs_fs__create_txn(svn_fs_txn_t **txn_p,
-                                   svn_fs_t *fs,
-                                   svn_revnum_t rev,
-                                   apr_pool_t *pool);
-
-/* Set the transaction property NAME to the value VALUE in transaction
-   TXN.  Perform temporary allocations from POOL. */
-svn_error_t *svn_fs_fs__change_txn_prop(svn_fs_txn_t *txn,
-                                        const char *name,
-                                        const svn_string_t *value,
-                                        apr_pool_t *pool);
-
-/* Change transaction properties in transaction TXN based on PROPS.
-   Perform temporary allocations from POOL. */
-svn_error_t *svn_fs_fs__change_txn_props(svn_fs_txn_t *txn,
-                                         const apr_array_header_t *props,
-                                         apr_pool_t *pool);
-
 /* Return whether or not the given FS supports mergeinfo metadata. */
 svn_boolean_t svn_fs_fs__fs_supports_mergeinfo(svn_fs_t *fs);
 
-/* Store a transaction record in *TXN_P for the transaction identified
-   by TXN_ID in filesystem FS.  Allocate everything from POOL. */
-svn_error_t *svn_fs_fs__get_txn(transaction_t **txn_p,
-                                svn_fs_t *fs,
-                                const char *txn_id,
-                                apr_pool_t *pool);
-
-/* Abort the existing transaction TXN, performing any temporary
-   allocations in POOL. */
-svn_error_t *svn_fs_fs__abort_txn(svn_fs_txn_t *txn, apr_pool_t *pool);
-
-/* Create an entirely new mutable node in the filesystem FS, whose
-   node-revision is NODEREV.  Set *ID_P to the new node revision's ID.
-   Use POOL for any temporary allocation.  COPY_ID is the copy_id to
-   use in the node revision ID.  TXN_ID is the Subversion transaction
-   under which this occurs. */
-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,
-                                    apr_pool_t *pool);
-
-/* Remove all references to the transaction TXN_ID from filesystem FS.
-   Temporary allocations are from POOL. */
-svn_error_t *svn_fs_fs__purge_txn(svn_fs_t *fs,
-                                  const char *txn_id,
-                                  apr_pool_t *pool);
-
-/* Add or set in filesystem FS, transaction TXN_ID, in directory
-   PARENT_NODEREV a directory entry for NAME pointing to ID of type
-   KIND.  Allocations are done in POOL. */
-svn_error_t *svn_fs_fs__set_entry(svn_fs_t *fs,
-                                  const char *txn_id,
-                                  node_revision_t *parent_noderev,
-                                  const char *name,
-                                  const svn_fs_id_t *id,
-                                  svn_node_kind_t kind,
-                                  apr_pool_t *pool);
-
-/* Add a change to the changes record for filesystem FS in transaction
-   TXN_ID.  Mark path PATH, having node-id ID, as changed according to
-   the type in CHANGE_KIND.  If the text representation was changed
-   set TEXT_MOD to TRUE, and likewise for PROP_MOD.  If this change
-   was the result of a copy, set COPYFROM_REV and COPYFROM_PATH to the
-   revision and path of the copy source, otherwise they should be set
-   to SVN_INVALID_REVNUM and NULL.  Perform any temporary allocations
-   from POOL. */
-svn_error_t *svn_fs_fs__add_change(svn_fs_t *fs,
-                                   const char *txn_id,
-                                   const char *path,
-                                   const svn_fs_id_t *id,
-                                   svn_fs_path_change_kind_t change_kind,
-                                   svn_boolean_t text_mod,
-                                   svn_boolean_t prop_mod,
-                                   svn_node_kind_t node_kind,
-                                   svn_revnum_t copyfrom_rev,
-                                   const char *copyfrom_path,
-                                   apr_pool_t *pool);
-
-/* Return a writable stream in *STREAM that allows storing the text
-   representation of node-revision NODEREV in filesystem FS.
-   Allocations are from POOL. */
-svn_error_t *svn_fs_fs__set_contents(svn_stream_t **stream,
-                                     svn_fs_t *fs,
-                                     node_revision_t *noderev,
-                                     apr_pool_t *pool);
-
-/* Create a node revision in FS which is an immediate successor of
-   OLD_ID, whose contents are NEW_NR.  Set *NEW_ID_P to the new node
-   revision's ID.  Use POOL for any temporary allocation.
-
-   COPY_ID, if non-NULL, is a key into the `copies' table, and
-   indicates that this new node is being created as the result of a
-   copy operation, and specifically which operation that was.  If
-   COPY_ID is NULL, then re-use the copy ID from the predecessor node.
-
-   TXN_ID is the Subversion transaction under which this occurs.
-
-   After this call, the deltification code assumes that the new node's
-   contents will change frequently, and will avoid representing other
-   nodes as deltas against this node's contents.  */
-svn_error_t *svn_fs_fs__create_successor(const svn_fs_id_t **new_id_p,
-                                         svn_fs_t *fs,
-                                         const svn_fs_id_t *old_idp,
-                                         node_revision_t *new_noderev,
-                                         const char *copy_id,
-                                         const char *txn_id,
-                                         apr_pool_t *pool);
-
-/* Write a new property list PROPLIST for node-revision NODEREV in
-   filesystem FS.  Perform any temporary allocations in POOL. */
-svn_error_t *svn_fs_fs__set_proplist(svn_fs_t *fs,
-                                     node_revision_t *noderev,
-                                     apr_hash_t *proplist,
-                                     apr_pool_t *pool);
-
-/* Commit the transaction TXN in filesystem FS and return its new
-   revision number in *REV.  If the transaction is out of date, return
-   the error SVN_ERR_FS_TXN_OUT_OF_DATE. Update commit time to ensure that
-   svn:date revprops remain ordered if SET_TIMESTAMP is non-zero. Use POOL for
-   temporary allocations. */
-svn_error_t *svn_fs_fs__commit(svn_revnum_t *new_rev_p,
-                               svn_fs_t *fs,
-                               svn_fs_txn_t *txn,
-                               svn_boolean_t set_timestamp,
-                               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_t *fs,
-                                        const char *txn_id,
-                                        apr_pool_t *pool);
-
 /* Create a fs_fs fileysystem referenced by FS at path PATH.  Get any
    temporary allocations from POOL.
 
@@ -392,63 +103,20 @@ svn_error_t *svn_fs_fs__set_uuid(svn_fs_
                                  const char *uuid,
                                  apr_pool_t *pool);
 
-/* Set *NAMES_P to an array of names which are all the active
-   transactions in filesystem FS.  Allocate the array from POOL. */
-svn_error_t *svn_fs_fs__list_transactions(apr_array_header_t **names_p,
-                                          svn_fs_t *fs,
-                                          apr_pool_t *pool);
-
-/* Open the transaction named NAME in filesystem FS.  Set *TXN_P to
- * the transaction. If there is no such transaction, return
-` * SVN_ERR_FS_NO_SUCH_TRANSACTION.  Allocate the new transaction in
- * POOL. */
-svn_error_t *svn_fs_fs__open_txn(svn_fs_txn_t **txn_p,
-                                 svn_fs_t *fs,
-                                 const char *name,
-                                 apr_pool_t *pool);
-
-/* Return the property list from transaction TXN and store it in
-   *PROPLIST.  Allocate the property list from POOL. */
-svn_error_t *svn_fs_fs__txn_proplist(apr_hash_t **proplist,
-                                     svn_fs_txn_t *txn,
-                                     apr_pool_t *pool);
-
-/* Delete the mutable node-revision referenced by ID, along with any
-   mutable props or directory contents associated with it.  Perform
-   temporary allocations in POOL. */
-svn_error_t *svn_fs_fs__delete_node_revision(svn_fs_t *fs,
-                                             const svn_fs_id_t *id,
-                                             apr_pool_t *pool);
-
-
-/* Find the paths which were changed in transaction TXN_ID of
-   filesystem FS and store them in *CHANGED_PATHS_P.
-   Get any temporary allocations from POOL. */
-svn_error_t *svn_fs_fs__txn_changes_fetch(apr_hash_t **changes,
-                                          svn_fs_t *fs,
-                                          const char *txn_id,
-                                          apr_pool_t *pool);
-
-
-/* Set *PATH to the path of REV in FS, whether in a pack file or not.
-   Allocate *PATH in POOL.
-
-   Note: If the caller does not have the write lock on FS, then the path is
-   not guaranteed to be correct or to remain correct after the function
-   returns, because the revision might become packed before or after this
-   call.  If a file exists at that path, then it is correct; if not, then
-   the caller should call update_min_unpacked_rev() and re-try once. */
-svn_error_t *
-svn_fs_fs__path_rev_absolute(const char **path,
-                             svn_fs_t *fs,
-                             svn_revnum_t rev,
-                             apr_pool_t *pool);
-
 /* Return the path to the 'current' file in FS.
    Perform allocation in POOL. */
 const char *
 svn_fs_fs__path_current(svn_fs_t *fs, apr_pool_t *pool);
 
+/* Write the format number and maximum number of files per directory
+   for FS, possibly expecting to overwrite a previously existing file.
+
+   Use POOL for temporary allocation. */
+svn_error_t *
+svn_fs_fs__write_format(svn_fs_t *fs,
+                        svn_boolean_t overwrite,
+                        apr_pool_t *pool);
+
 /* Obtain a write lock on the filesystem FS in a subpool of POOL, call
    BODY with BATON and that subpool, destroy the subpool (releasing the write
    lock) and return what BODY returned. */
@@ -459,6 +127,15 @@ svn_fs_fs__with_write_lock(svn_fs_t *fs,
                            void *baton,
                            apr_pool_t *pool);
 
+/* Run BODY (with BATON and POOL) while the txn-current file
+   of FS is locked. */
+svn_error_t *
+svn_fs_fs__with_txn_current_lock(svn_fs_t *fs,
+                                 svn_error_t *(*body)(void *baton,
+                                                      apr_pool_t *pool),
+                                 void *baton,
+                                 apr_pool_t *pool);
+
 /* Find the value of the property named PROPNAME in transaction TXN.
    Return the contents in *VALUE_P.  The contents will be allocated
    from POOL. */
@@ -478,38 +155,6 @@ svn_error_t *svn_fs_fs__change_rev_prop(
                                         const svn_string_t *value,
                                         apr_pool_t *pool);
 
-/* Retrieve information about the Subversion transaction SVN_TXN from
-   the `transactions' table of FS, allocating from POOL.  Set
-   *ROOT_ID_P to the ID of the transaction's root directory.  Set
-   *BASE_ROOT_ID_P to the ID of the root directory of the
-   transaction's base revision.
-
-   If there is no such transaction, SVN_ERR_FS_NO_SUCH_TRANSACTION is
-   the error returned.
-
-   Returns SVN_ERR_FS_TRANSACTION_NOT_MUTABLE if TXN_NAME refers to a
-   transaction that has already been committed.
-
-   Allocate *ROOT_ID_P and *BASE_ROOT_ID_P in POOL.  */
-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,
-                                    apr_pool_t *pool);
-
-/* Begin a new transaction in filesystem FS, based on existing
-   revision REV.  The new transaction is returned in *TXN_P.  Allocate
-   the new transaction structure from POOL. */
-svn_error_t *svn_fs_fs__begin_txn(svn_fs_txn_t **txn_p, svn_fs_t *fs,
-                                  svn_revnum_t rev, apr_uint32_t flags,
-                                  apr_pool_t *pool);
-
-/* Find the value of the property named PROPNAME in transaction TXN.
-   Return the contents in *VALUE_P.  The contents will be allocated
-   from POOL. */
-svn_error_t *svn_fs_fs__txn_prop(svn_string_t **value_p, svn_fs_txn_t *txn,
-                                 const char *propname, apr_pool_t *pool);
-
 /* If directory PATH does not exist, create it and give it the same
    permissions as FS_PATH.*/
 svn_error_t *svn_fs_fs__ensure_dir_exists(const char *path,
@@ -525,7 +170,7 @@ svn_error_t *svn_fs_fs__ensure_dir_exist
  */
 svn_error_t *
 svn_fs_fs__set_node_origin(svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            const svn_fs_id_t *node_rev_id,
                            apr_pool_t *pool);
 
@@ -539,7 +184,7 @@ svn_fs_fs__set_node_origin(svn_fs_t *fs,
 svn_error_t *
 svn_fs_fs__get_node_origin(const svn_fs_id_t **origin_id,
                            svn_fs_t *fs,
-                           const char *node_id,
+                           const svn_fs_fs__id_part_t *node_id,
                            apr_pool_t *pool);
 
 
@@ -567,18 +212,4 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
 void
 svn_fs_fs__reset_txn_caches(svn_fs_t *fs);
 
-/* Possibly pack the repository at PATH.  This just take full shards, and
-   combines all the revision files into a single one, with a manifest header.
-   Use optional CANCEL_FUNC/CANCEL_BATON for cancellation support.
-
-   Existing filesystem references need not change.  */
-svn_error_t *
-svn_fs_fs__pack(svn_fs_t *fs,
-                svn_fs_pack_notify_t notify_func,
-                void *notify_baton,
-                svn_cancel_func_t cancel_func,
-                void *cancel_baton,
-                apr_pool_t *pool);
-
-
 #endif

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.c Thu Sep 26 13:47:21 2013
@@ -24,90 +24,253 @@
 #include <stdlib.h>
 
 #include "id.h"
+
 #include "../libsvn_fs/fs-loader.h"
 #include "private/svn_temp_serializer.h"
 #include "private/svn_string_private.h"
 
 
-typedef struct id_private_t {
-  const char *node_id;
-  const char *copy_id;
-  const char *txn_id;
-  svn_revnum_t rev;
-  apr_off_t offset;
-} id_private_t;
+typedef struct fs_fs__id_t
+{
+  /* API visible part */
+  svn_fs_id_t generic_id;
+
+  /* private members */
+  struct
+    {
+      svn_fs_fs__id_part_t node_id;
+      svn_fs_fs__id_part_t copy_id;
+      svn_fs_fs__id_part_t txn_id;
+      svn_fs_fs__id_part_t rev_offset;
+    } private_id;
+} fs_fs__id_t;
 
 
-/* Accessing ID Pieces.  */
 
-const char *
-svn_fs_fs__id_node_id(const svn_fs_id_t *id)
+/* Parse the NUL-terminated ID part at DATA and write the result into *PART.
+ * Return TRUE if no errors were detected. */
+static svn_boolean_t
+part_parse(svn_fs_fs__id_part_t *part,
+           const char *data)
 {
-  id_private_t *pvt = id->fsap_data;
+  /* special case: ID inside some transaction */
+  if (data[0] == '_')
+    {
+      part->revision = SVN_INVALID_REVNUM;
+      part->number = svn__base36toui64(&data, data + 1);
+      return *data == '\0';
+    }
 
-  return pvt->node_id;
+  /* special case: 0 / default ID */
+  if (data[0] == '0' && data[1] == '\0')
+    {
+      part->revision = 0;
+      part->number = 0;
+      return TRUE;
+    }
+
+  /* read old style / new style ID */
+  part->number = svn__base36toui64(&data, data);
+  if (data[0] != '-')
+    {
+      part->revision = 0;
+      return *data == '\0';
+    }
+
+  part->revision = SVN_STR_TO_REV(++data);
+
+  return TRUE;
 }
 
+/* Parse the transaction id in DATA and store the result in *TXN_ID.
+ * Return FALSE if there was some problem.
+ */
+static svn_boolean_t
+txn_id_parse(svn_fs_fs__id_part_t *txn_id,
+             const char *data)
+{
+  txn_id->revision = SVN_STR_TO_REV(data);
+  data = strchr(data, '-');
+  if (data == NULL)
+    return FALSE;
+  
+  txn_id->number = svn__base36toui64(&data, ++data);
+  return *data == '\0';
+}
 
-const char *
-svn_fs_fs__id_copy_id(const svn_fs_id_t *id)
+/* Write the textual representation of *PART into P and return a pointer
+ * to the first position behind that string.
+ */
+static char *
+unparse_id_part(char *p,
+                const svn_fs_fs__id_part_t *part)
 {
-  id_private_t *pvt = id->fsap_data;
+  if (SVN_IS_VALID_REVNUM(part->revision))
+    {
+      /* ordinary old style / new style ID */
+      p += svn__ui64tobase36(p, part->number);
+      if (part->revision > 0)
+        {
+          *(p++) = '-';
+          p += svn__i64toa(p, part->revision);
+        }
+    }
+  else
+    {
+      /* in txn: mark with "_" prefix */
+      *(p++) = '_';
+      p += svn__ui64tobase36(p, part->number);
+    }
 
-  return pvt->copy_id;
+  *(p++) = '.';
+
+  return p;
 }
 
+
+
+/* Operations on ID parts */
+
+svn_boolean_t
+svn_fs_fs__id_part_is_root(const svn_fs_fs__id_part_t* part)
+{
+  return part->revision == 0 && part->number == 0;
+}
+
+svn_boolean_t
+svn_fs_fs__id_part_eq(const svn_fs_fs__id_part_t *lhs,
+                      const svn_fs_fs__id_part_t *rhs)
+{
+  return lhs->revision == rhs->revision && lhs->number == rhs->number;
+}
+
+svn_boolean_t
+svn_fs_fs__id_txn_used(const svn_fs_fs__id_part_t *txn_id)
+{
+  return SVN_IS_VALID_REVNUM(txn_id->revision) || (txn_id->number != 0);
+}
+
+void
+svn_fs_fs__id_txn_reset(svn_fs_fs__id_part_t *txn_id)
+{
+  txn_id->revision = SVN_INVALID_REVNUM;
+  txn_id->number = 0;
+}
+
+svn_error_t *
+svn_fs_fs__id_txn_parse(svn_fs_fs__id_part_t *txn_id,
+                        const char *data)
+{
+  if (! txn_id_parse(txn_id, data))
+    return svn_error_createf(SVN_ERR_FS_MALFORMED_TXN_ID, NULL,
+                             "malformed txn id '%s'", data);
+
+  return SVN_NO_ERROR;
+}
 
 const char *
-svn_fs_fs__id_txn_id(const svn_fs_id_t *id)
+svn_fs_fs__id_txn_unparse(const svn_fs_fs__id_part_t *txn_id,
+                          apr_pool_t *pool)
 {
-  id_private_t *pvt = id->fsap_data;
+  char string[2 * SVN_INT64_BUFFER_SIZE + 1];
+  char *p = string;
+  
+  p += svn__i64toa(p, txn_id->revision);
+  *(p++) = '-';
+  p += svn__ui64tobase36(p, txn_id->number);
 
-  return pvt->txn_id;
+  return apr_pstrmemdup(pool, string, p - string);
 }
 
+
+
+/* Accessing ID Pieces.  */
 
-svn_revnum_t
-svn_fs_fs__id_rev(const svn_fs_id_t *id)
+const svn_fs_fs__id_part_t *
+svn_fs_fs__id_node_id(const svn_fs_id_t *fs_id)
+{
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
+
+  return &id->private_id.node_id;
+}
+
+
+const svn_fs_fs__id_part_t *
+svn_fs_fs__id_copy_id(const svn_fs_id_t *fs_id)
+{
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
+
+  return &id->private_id.copy_id;
+}
+
+
+const svn_fs_fs__id_part_t *
+svn_fs_fs__id_txn_id(const svn_fs_id_t *fs_id)
+{
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
+
+  return &id->private_id.txn_id;
+}
+
+
+const svn_fs_fs__id_part_t *
+svn_fs_fs__id_rev_offset(const svn_fs_id_t *fs_id)
 {
-  id_private_t *pvt = id->fsap_data;
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
-  return pvt->rev;
+  return &id->private_id.rev_offset;
 }
 
+svn_revnum_t
+svn_fs_fs__id_rev(const svn_fs_id_t *fs_id)
+{
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
+
+  return id->private_id.rev_offset.revision;
+}
 
-apr_off_t
-svn_fs_fs__id_offset(const svn_fs_id_t *id)
+apr_uint64_t
+svn_fs_fs__id_offset(const svn_fs_id_t *fs_id)
 {
-  id_private_t *pvt = id->fsap_data;
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
-  return pvt->offset;
+  return id->private_id.rev_offset.number;
 }
 
+svn_boolean_t
+svn_fs_fs__id_is_txn(const svn_fs_id_t *fs_id)
+{
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
+
+  return svn_fs_fs__id_txn_used(&id->private_id.txn_id);
+}
 
 svn_string_t *
-svn_fs_fs__id_unparse(const svn_fs_id_t *id,
+svn_fs_fs__id_unparse(const svn_fs_id_t *fs_id,
                       apr_pool_t *pool)
 {
-  id_private_t *pvt = id->fsap_data;
+  char string[6 * SVN_INT64_BUFFER_SIZE + 10];
+  fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
 
-  if ((! pvt->txn_id))
-    {
-      char rev_string[SVN_INT64_BUFFER_SIZE];
-      char offset_string[SVN_INT64_BUFFER_SIZE];
+  char *p = unparse_id_part(string, &id->private_id.node_id);
+  p = unparse_id_part(p, &id->private_id.copy_id);
 
-      svn__i64toa(rev_string, pvt->rev);
-      svn__i64toa(offset_string, pvt->offset);
-      return svn_string_createf(pool, "%s.%s.r%s/%s",
-                                pvt->node_id, pvt->copy_id,
-                                rev_string, offset_string);
+  if (svn_fs_fs__id_txn_used(&id->private_id.txn_id))
+    {
+      *(p++) = 't';
+      p += svn__i64toa(p, id->private_id.txn_id.revision);
+      *(p++) = '-';
+      p += svn__ui64tobase36(p, id->private_id.txn_id.number);
     }
   else
     {
-      return svn_string_createf(pool, "%s.%s.t%s",
-                                pvt->node_id, pvt->copy_id,
-                                pvt->txn_id);
+      *(p++) = 'r';
+      p += svn__i64toa(p, id->private_id.rev_offset.revision);
+      *(p++) = '/';
+      p += svn__i64toa(p, id->private_id.rev_offset.number);
     }
+
+  return svn_string_ncreate(string, p - string, pool);
 }
 
 
@@ -117,23 +280,14 @@ svn_boolean_t
 svn_fs_fs__id_eq(const svn_fs_id_t *a,
                  const svn_fs_id_t *b)
 {
-  id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
+  fs_fs__id_t *id_a = (fs_fs__id_t *)a;
+  fs_fs__id_t *id_b = (fs_fs__id_t *)b;
 
   if (a == b)
     return TRUE;
-  if (strcmp(pvta->node_id, pvtb->node_id) != 0)
-     return FALSE;
-  if (strcmp(pvta->copy_id, pvtb->copy_id) != 0)
-    return FALSE;
-  if ((pvta->txn_id == NULL) != (pvtb->txn_id == NULL))
-    return FALSE;
-  if (pvta->txn_id && pvtb->txn_id && strcmp(pvta->txn_id, pvtb->txn_id) != 0)
-    return FALSE;
-  if (pvta->rev != pvtb->rev)
-    return FALSE;
-  if (pvta->offset != pvtb->offset)
-    return FALSE;
-  return TRUE;
+
+  return memcmp(&id_a->private_id, &id_b->private_id,
+                sizeof(id_a->private_id)) == 0;
 }
 
 
@@ -141,20 +295,24 @@ svn_boolean_t
 svn_fs_fs__id_check_related(const svn_fs_id_t *a,
                             const svn_fs_id_t *b)
 {
-  id_private_t *pvta = a->fsap_data, *pvtb = b->fsap_data;
+  fs_fs__id_t *id_a = (fs_fs__id_t *)a;
+  fs_fs__id_t *id_b = (fs_fs__id_t *)b;
 
   if (a == b)
     return TRUE;
+
   /* If both node_ids start with _ and they have differing transaction
      IDs, then it is impossible for them to be related. */
-  if (pvta->node_id[0] == '_')
+  if (id_a->private_id.node_id.revision == SVN_INVALID_REVNUM)
     {
-      if (pvta->txn_id && pvtb->txn_id &&
-          (strcmp(pvta->txn_id, pvtb->txn_id) != 0))
+      if (   !svn_fs_fs__id_part_eq(&id_a->private_id.txn_id,
+                                    &id_b->private_id.txn_id)
+          || !svn_fs_fs__id_txn_used(&id_a->private_id.txn_id))
         return FALSE;
     }
 
-  return (strcmp(pvta->node_id, pvtb->node_id) == 0);
+  return svn_fs_fs__id_part_eq(&id_a->private_id.node_id,
+                               &id_b->private_id.node_id);
 }
 
 
@@ -167,6 +325,18 @@ svn_fs_fs__id_compare(const svn_fs_id_t 
   return (svn_fs_fs__id_check_related(a, b) ? 1 : -1);
 }
 
+int
+svn_fs_fs__id_part_compare(const svn_fs_fs__id_part_t *a,
+                           const svn_fs_fs__id_part_t *b)
+{
+  if (a->revision < b->revision)
+    return -1;
+  if (a->revision > b->revision)
+    return 1;
+
+  return a->number < b->number ? -1 : a->number == b->number ? 0 : 1;
+}
+
 
 
 /* Creating ID's.  */
@@ -176,66 +346,73 @@ static id_vtable_t id_vtable = {
   svn_fs_fs__id_compare
 };
 
+svn_fs_id_t *
+svn_fs_fs__id_txn_create_root(const svn_fs_fs__id_part_t *txn_id,
+                              apr_pool_t *pool)
+{
+  fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
+
+  /* node ID and copy ID are "0" */
+  
+  id->private_id.txn_id = *txn_id;
+  id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
+
+  id->generic_id.vtable = &id_vtable;
+  id->generic_id.fsap_data = &id;
+
+  return (svn_fs_id_t *)id;
+}
 
 svn_fs_id_t *
-svn_fs_fs__id_txn_create(const char *node_id,
-                         const char *copy_id,
-                         const char *txn_id,
+svn_fs_fs__id_txn_create(const svn_fs_fs__id_part_t *node_id,
+                         const svn_fs_fs__id_part_t *copy_id,
+                         const svn_fs_fs__id_part_t *txn_id,
                          apr_pool_t *pool)
 {
-  svn_fs_id_t *id = apr_palloc(pool, sizeof(*id));
-  id_private_t *pvt = apr_palloc(pool, sizeof(*pvt));
+  fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
+
+  id->private_id.node_id = *node_id;
+  id->private_id.copy_id = *copy_id;
+  id->private_id.txn_id = *txn_id;
+  id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
 
-  pvt->node_id = apr_pstrdup(pool, node_id);
-  pvt->copy_id = apr_pstrdup(pool, copy_id);
-  pvt->txn_id = apr_pstrdup(pool, txn_id);
-  pvt->rev = SVN_INVALID_REVNUM;
-  pvt->offset = -1;
-
-  id->vtable = &id_vtable;
-  id->fsap_data = pvt;
-  return id;
+  id->generic_id.vtable = &id_vtable;
+  id->generic_id.fsap_data = &id;
+
+  return (svn_fs_id_t *)id;
 }
 
 
 svn_fs_id_t *
-svn_fs_fs__id_rev_create(const char *node_id,
-                         const char *copy_id,
-                         svn_revnum_t rev,
-                         apr_off_t offset,
+svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
+                         const svn_fs_fs__id_part_t *copy_id,
+                         const svn_fs_fs__id_part_t *rev_offset,
                          apr_pool_t *pool)
 {
-  svn_fs_id_t *id = apr_palloc(pool, sizeof(*id));
-  id_private_t *pvt = apr_palloc(pool, sizeof(*pvt));
+  fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
+
+  id->private_id.node_id = *node_id;
+  id->private_id.copy_id = *copy_id;
+  id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
+  id->private_id.rev_offset = *rev_offset;
 
-  pvt->node_id = apr_pstrdup(pool, node_id);
-  pvt->copy_id = apr_pstrdup(pool, copy_id);
-  pvt->txn_id = NULL;
-  pvt->rev = rev;
-  pvt->offset = offset;
-
-  id->vtable = &id_vtable;
-  id->fsap_data = pvt;
-  return id;
+  id->generic_id.vtable = &id_vtable;
+  id->generic_id.fsap_data = &id;
+
+  return (svn_fs_id_t *)id;
 }
 
 
 svn_fs_id_t *
-svn_fs_fs__id_copy(const svn_fs_id_t *id, apr_pool_t *pool)
+svn_fs_fs__id_copy(const svn_fs_id_t *source, apr_pool_t *pool)
 {
-  svn_fs_id_t *new_id = apr_palloc(pool, sizeof(*new_id));
-  id_private_t *new_pvt = apr_palloc(pool, sizeof(*new_pvt));
-  id_private_t *pvt = id->fsap_data;
-
-  new_pvt->node_id = apr_pstrdup(pool, pvt->node_id);
-  new_pvt->copy_id = apr_pstrdup(pool, pvt->copy_id);
-  new_pvt->txn_id = pvt->txn_id ? apr_pstrdup(pool, pvt->txn_id) : NULL;
-  new_pvt->rev = pvt->rev;
-  new_pvt->offset = pvt->offset;
-
-  new_id->vtable = &id_vtable;
-  new_id->fsap_data = new_pvt;
-  return new_id;
+  fs_fs__id_t *id = (fs_fs__id_t *)source;
+  fs_fs__id_t *new_id = apr_palloc(pool, sizeof(*new_id));
+
+  *new_id = *id;
+  new_id->generic_id.fsap_data = new_id;
+
+  return (svn_fs_id_t *)new_id;
 }
 
 
@@ -244,8 +421,7 @@ svn_fs_fs__id_parse(const char *data,
                     apr_size_t len,
                     apr_pool_t *pool)
 {
-  svn_fs_id_t *id;
-  id_private_t *pvt;
+  fs_fs__id_t *id;
   char *data_copy, *str;
 
   /* Dup the ID data into POOL.  Our returned ID will have references
@@ -253,10 +429,9 @@ svn_fs_fs__id_parse(const char *data,
   data_copy = apr_pstrmemdup(pool, data, len);
 
   /* Alloc a new svn_fs_id_t structure. */
-  id = apr_palloc(pool, sizeof(*id));
-  pvt = apr_palloc(pool, sizeof(*pvt));
-  id->vtable = &id_vtable;
-  id->fsap_data = pvt;
+  id = apr_pcalloc(pool, sizeof(*id));
+  id->generic_id.vtable = &id_vtable;
+  id->generic_id.fsap_data = &id;
 
   /* Now, we basically just need to "split" this data on `.'
      characters.  We will use svn_cstring_tokenize, which will put
@@ -268,13 +443,15 @@ svn_fs_fs__id_parse(const char *data,
   str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
-  pvt->node_id = str;
+  if (! part_parse(&id->private_id.node_id, str))
+    return NULL;
 
   /* Copy Id */
   str = svn_cstring_tokenize(".", &data_copy);
   if (str == NULL)
     return NULL;
-  pvt->copy_id = str;
+  if (! part_parse(&id->private_id.copy_id, str))
+    return NULL;
 
   /* Txn/Rev Id */
   str = svn_cstring_tokenize(".", &data_copy);
@@ -287,119 +464,78 @@ svn_fs_fs__id_parse(const char *data,
       svn_error_t *err;
 
       /* This is a revision type ID */
-      pvt->txn_id = NULL;
+      id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
+      id->private_id.txn_id.number = 0;
 
       data_copy = str + 1;
       str = svn_cstring_tokenize("/", &data_copy);
       if (str == NULL)
         return NULL;
-      pvt->rev = SVN_STR_TO_REV(str);
+      id->private_id.rev_offset.revision = SVN_STR_TO_REV(str);
 
-      str = svn_cstring_tokenize("/", &data_copy);
-      if (str == NULL)
-        return NULL;
-      err = svn_cstring_atoi64(&val, str);
+      err = svn_cstring_atoi64(&val, data_copy);
       if (err)
         {
           svn_error_clear(err);
           return NULL;
         }
-      pvt->offset = (apr_off_t)val;
+      id->private_id.rev_offset.number = (apr_uint64_t)val;
     }
   else if (str[0] == 't')
     {
       /* This is a transaction type ID */
-      pvt->txn_id = str + 1;
-      pvt->rev = SVN_INVALID_REVNUM;
-      pvt->offset = -1;
+      id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
+      id->private_id.rev_offset.number = 0;
+
+      if (! txn_id_parse(&id->private_id.txn_id, str + 1))
+        return NULL;
     }
   else
     return NULL;
 
-  return id;
+  return (svn_fs_id_t *)id;
 }
 
 /* (de-)serialization support */
 
-/* Serialization of the PVT sub-structure within the CONTEXT.
- */
-static void
-serialize_id_private(svn_temp_serializer__context_t *context,
-                     const id_private_t * const *pvt)
-{
-  const id_private_t *private = *pvt;
-
-  /* serialize the pvt data struct itself */
-  svn_temp_serializer__push(context,
-                            (const void * const *)pvt,
-                            sizeof(*private));
-
-  /* append the referenced strings */
-  svn_temp_serializer__add_string(context, &private->node_id);
-  svn_temp_serializer__add_string(context, &private->copy_id);
-  svn_temp_serializer__add_string(context, &private->txn_id);
-
-  /* return to caller's nesting level */
-  svn_temp_serializer__pop(context);
-}
-
 /* Serialize an ID within the serialization CONTEXT.
  */
 void
 svn_fs_fs__id_serialize(svn_temp_serializer__context_t *context,
-                        const struct svn_fs_id_t * const *id)
+                        const svn_fs_id_t * const *in)
 {
+  const fs_fs__id_t *id = (const fs_fs__id_t *)*in;
+  
   /* nothing to do for NULL ids */
-  if (*id == NULL)
+  if (id == NULL)
     return;
 
   /* serialize the id data struct itself */
-  svn_temp_serializer__push(context,
-                            (const void * const *)id,
-                            sizeof(**id));
-
-  /* serialize the id_private_t data sub-struct */
-  serialize_id_private(context,
-                       (const id_private_t * const *)&(*id)->fsap_data);
-
-  /* return to caller's nesting level */
-  svn_temp_serializer__pop(context);
-}
-
-/* Deserialization of the PVT sub-structure in BUFFER.
- */
-static void
-deserialize_id_private(void *buffer, id_private_t **pvt)
-{
-  /* fixup the reference to the only sub-structure */
-  id_private_t *private;
-  svn_temp_deserializer__resolve(buffer, (void**)pvt);
-
-  /* fixup the sub-structure itself */
-  private = *pvt;
-  svn_temp_deserializer__resolve(private, (void**)&private->node_id);
-  svn_temp_deserializer__resolve(private, (void**)&private->copy_id);
-  svn_temp_deserializer__resolve(private, (void**)&private->txn_id);
+  svn_temp_serializer__add_leaf(context,
+                                (const void * const *)in,
+                                sizeof(fs_fs__id_t));
 }
 
 /* Deserialize an ID inside the BUFFER.
  */
 void
-svn_fs_fs__id_deserialize(void *buffer, svn_fs_id_t **id)
+svn_fs_fs__id_deserialize(void *buffer, svn_fs_id_t **in_out)
 {
+  fs_fs__id_t *id;
+
   /* The id maybe all what is in the whole buffer.
    * Don't try to fixup the pointer in that case*/
-  if (*id != buffer)
-    svn_temp_deserializer__resolve(buffer, (void**)id);
+  if (*in_out != buffer)
+    svn_temp_deserializer__resolve(buffer, (void**)in_out);
+
+  id = (fs_fs__id_t *)*in_out;
 
   /* no id, no sub-structure fixup necessary */
-  if (*id == NULL)
+  if (id == NULL)
     return;
 
   /* the stored vtable is bogus at best -> set the right one */
-  (*id)->vtable = &id_vtable;
-
-  /* handle sub-structures */
-  deserialize_id_private(*id, (id_private_t **)&(*id)->fsap_data);
+  id->generic_id.vtable = &id_vtable;
+  id->generic_id.fsap_data = id;
 }
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.h?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/id.h Thu Sep 26 13:47:21 2013
@@ -29,25 +29,78 @@
 extern "C" {
 #endif /* __cplusplus */
 
+/* Node-revision IDs in FSFS consist of 3 of sub-IDs ("parts") that consist
+ * of a creation REVISION number and some revision- / transaction-local
+ * counter value (NUMBER).  Old-style ID parts use global counter values.
+ *
+ * The parts are: node_id, copy_id and txn_id for in-txn IDs as well as
+ * node_id, copy_id and rev_offset for in-revision IDs.  This struct the
+ * data structure used for each of those parts.
+ */
+typedef struct svn_fs_fs__id_part_t
+{
+  /* SVN_INVALID_REVNUM for txns -> not a txn, COUNTER must be 0.
+     SVN_INVALID_REVNUM for others -> not assigned to a revision, yet.
+     0                  for others -> old-style ID or the root in rev 0. */
+  svn_revnum_t revision;
+
+  /* sub-id value relative to REVISION.  Its interpretation depends on
+     the part itself.  In rev_offset, it is the offset value, in others
+     it represents a unique counter value. */
+  apr_uint64_t number;
+} svn_fs_fs__id_part_t;
+
+
+/*** Operations on ID parts. ***/
+
+/* Return TRUE, if both elements of the PART is 0, i.e. this is the default
+ * value if e.g. no copies were made of this node. */
+svn_boolean_t svn_fs_fs__id_part_is_root(const svn_fs_fs__id_part_t *part);
+
+/* Return TRUE, if all element values of *LHS and *RHS match. */
+svn_boolean_t svn_fs_fs__id_part_eq(const svn_fs_fs__id_part_t *lhs,
+                                    const svn_fs_fs__id_part_t *rhs);
+
+/* Return TRUE, if TXN_ID is used, i.e. doesn't contain just the defaults. */
+svn_boolean_t svn_fs_fs__id_txn_used(const svn_fs_fs__id_part_t *txn_id);
+
+/* Reset TXN_ID to the defaults. */
+void svn_fs_fs__id_txn_reset(svn_fs_fs__id_part_t *txn_id);
+
+/* Parse the transaction id in DATA and store the result in *TXN_ID */
+svn_error_t *svn_fs_fs__id_txn_parse(svn_fs_fs__id_part_t *txn_id,
+                                     const char *data);
+
+/* Convert the transaction id in *TXN_ID into a textual representation
+ * allocated in POOL. */
+const char *svn_fs_fs__id_txn_unparse(const svn_fs_fs__id_part_t *txn_id,
+                                      apr_pool_t *pool);
+
 
 /*** ID accessor functions. ***/
 
 /* Get the "node id" portion of ID. */
-const char *svn_fs_fs__id_node_id(const svn_fs_id_t *id);
+const svn_fs_fs__id_part_t *svn_fs_fs__id_node_id(const svn_fs_id_t *id);
 
 /* Get the "copy id" portion of ID. */
-const char *svn_fs_fs__id_copy_id(const svn_fs_id_t *id);
+const svn_fs_fs__id_part_t *svn_fs_fs__id_copy_id(const svn_fs_id_t *id);
 
 /* Get the "txn id" portion of ID, or NULL if it is a permanent ID. */
-const char *svn_fs_fs__id_txn_id(const svn_fs_id_t *id);
+const svn_fs_fs__id_part_t *svn_fs_fs__id_txn_id(const svn_fs_id_t *id);
+
+/* Get the "rev,offset" portion of ID. */
+const svn_fs_fs__id_part_t *svn_fs_fs__id_rev_offset(const svn_fs_id_t *id);
 
 /* Get the "rev" portion of ID, or SVN_INVALID_REVNUM if it is a
    transaction ID. */
 svn_revnum_t svn_fs_fs__id_rev(const svn_fs_id_t *id);
 
-/* Access the "offset" portion of the ID, or -1 if it is a transaction
+/* Access the "offset" portion of the ID, or 0 if it is a transaction
    ID. */
-apr_off_t svn_fs_fs__id_offset(const svn_fs_id_t *id);
+apr_uint64_t svn_fs_fs__id_offset(const svn_fs_id_t *id);
+
+/* Return TRUE, if this is a transaction ID. */
+svn_boolean_t svn_fs_fs__id_is_txn(const svn_fs_id_t *id);
 
 /* Convert ID into string form, allocated in POOL. */
 svn_string_t *svn_fs_fs__id_unparse(const svn_fs_id_t *id,
@@ -65,19 +118,26 @@ svn_boolean_t svn_fs_fs__id_check_relate
 int svn_fs_fs__id_compare(const svn_fs_id_t *a,
                           const svn_fs_id_t *b);
 
+/* Return 0 if A and B are equal, 1 if A is "greater than" B, -1 otherwise. */
+int svn_fs_fs__id_part_compare(const svn_fs_fs__id_part_t *a,
+                               const svn_fs_fs__id_part_t *b);
+
+/* Create the txn root ID for transaction TXN_ID.  Allocate it in POOL. */
+svn_fs_id_t *svn_fs_fs__id_txn_create_root(const svn_fs_fs__id_part_t *txn_id,
+                                           apr_pool_t *pool);
+
 /* Create an ID within a transaction based on NODE_ID, COPY_ID, and
    TXN_ID, allocated in POOL. */
-svn_fs_id_t *svn_fs_fs__id_txn_create(const char *node_id,
-                                      const char *copy_id,
-                                      const char *txn_id,
+svn_fs_id_t *svn_fs_fs__id_txn_create(const svn_fs_fs__id_part_t *node_id,
+                                      const svn_fs_fs__id_part_t *copy_id,
+                                      const svn_fs_fs__id_part_t *txn_id,
                                       apr_pool_t *pool);
 
-/* Create a permanent ID based on NODE_ID, COPY_ID, REV, and OFFSET,
+/* Create a permanent ID based on NODE_ID, COPY_ID and REV_OFFSET,
    allocated in POOL. */
-svn_fs_id_t *svn_fs_fs__id_rev_create(const char *node_id,
-                                      const char *copy_id,
-                                      svn_revnum_t rev,
-                                      apr_off_t offset,
+svn_fs_id_t *svn_fs_fs__id_rev_create(const svn_fs_fs__id_part_t *node_id,
+                                      const svn_fs_fs__id_part_t *copy_id,
+                                      const svn_fs_fs__id_part_t *rev_offset,
                                       apr_pool_t *pool);
 
 /* Return a copy of ID, allocated from POOL. */

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/lock.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/lock.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/lock.c Thu Sep 26 13:47:21 2013
@@ -37,6 +37,7 @@
 #include "lock.h"
 #include "tree.h"
 #include "fs_fs.h"
+#include "util.h"
 #include "../libsvn_fs/fs-loader.h"
 
 #include "private/svn_fs_util.h"
@@ -455,8 +456,7 @@ delete_lock(svn_fs_t *fs,
         }
       else
         {
-          const char *rev_0_path;
-          SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, fs, 0, pool));
+          const char *rev_0_path = svn_fs_fs__path_rev_absolute(fs, 0, pool);
           SVN_ERR(write_digest_file(this_children, this_lock, fs->path,
                                     digest_path, rev_0_path, subpool));
         }
@@ -863,7 +863,8 @@ lock_body(void *baton, apr_pool_t *pool)
   lock->is_dav_comment = lb->is_dav_comment;
   lock->creation_date = apr_time_now();
   lock->expiration_date = lb->expiration_date;
-  SVN_ERR(svn_fs_fs__path_rev_absolute(&rev_0_path, lb->fs, 0, pool));
+
+  rev_0_path = svn_fs_fs__path_rev_absolute(lb->fs, 0, pool);
   SVN_ERR(set_lock(lb->fs->path, lock, rev_0_path, pool));
   *lb->lock_p = lock;
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/rep-cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/rep-cache.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/rep-cache.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/rep-cache.c Thu Sep 26 13:47:21 2013
@@ -58,7 +58,7 @@ rep_has_been_born(representation_t *rep,
 {
   SVN_ERR_ASSERT(rep);
 
-  SVN_ERR(svn_fs_fs__revision_exists(rep->revision, fs, pool));
+  SVN_ERR(svn_fs_fs__ensure_revision_exists(rep->revision, fs, pool));
 
   return SVN_NO_ERROR;
 }
@@ -163,7 +163,7 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
       max = svn_sqlite__column_revnum(stmt, 0);
       SVN_ERR(svn_sqlite__reset(stmt));
       if (SVN_IS_VALID_REVNUM(max))  /* The rep-cache could be empty. */
-        SVN_ERR(svn_fs_fs__revision_exists(max, fs, iterpool));
+        SVN_ERR(svn_fs_fs__ensure_revision_exists(max, fs, iterpool));
     }
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db,
@@ -178,6 +178,7 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
       representation_t *rep;
       const char *sha1_digest;
       svn_error_t *err;
+      svn_checksum_t *checksum;
 
       /* Clear ITERPOOL occasionally. */
       if (iterations++ % 16 == 0)
@@ -193,12 +194,15 @@ svn_fs_fs__walk_rep_reference(svn_fs_t *
 
       /* Construct a representation_t. */
       rep = apr_pcalloc(iterpool, sizeof(*rep));
+      svn_fs_fs__id_txn_reset(&rep->txn_id);
       sha1_digest = svn_sqlite__column_text(stmt, 0, iterpool);
-      err = svn_checksum_parse_hex(&rep->sha1_checksum,
-                                   svn_checksum_sha1, sha1_digest,
-                                   iterpool);
+      err = svn_checksum_parse_hex(&checksum, svn_checksum_sha1,
+                                   sha1_digest, iterpool);
       if (err)
         return svn_error_compose_create(err, svn_sqlite__reset(stmt));
+
+      rep->has_sha1 = TRUE;
+      memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest));
       rep->revision = svn_sqlite__column_revnum(stmt, 1);
       rep->offset = svn_sqlite__column_int64(stmt, 2);
       rep->size = svn_sqlite__column_int64(stmt, 3);
@@ -250,7 +254,10 @@ svn_fs_fs__get_rep_reference(representat
   if (have_row)
     {
       *rep = apr_pcalloc(pool, sizeof(**rep));
-      (*rep)->sha1_checksum = svn_checksum_dup(checksum, pool);
+      svn_fs_fs__id_txn_reset(&(*rep)->txn_id);
+      memcpy((*rep)->sha1_digest, checksum->digest,
+             sizeof((*rep)->sha1_digest));
+      (*rep)->has_sha1 = TRUE;
       (*rep)->revision = svn_sqlite__column_revnum(stmt, 0);
       (*rep)->offset = svn_sqlite__column_int64(stmt, 1);
       (*rep)->size = svn_sqlite__column_int64(stmt, 2);
@@ -276,20 +283,23 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_sqlite__stmt_t *stmt;
   svn_error_t *err;
+  svn_checksum_t checksum;
+  checksum.kind = svn_checksum_sha1;
+  checksum.digest = rep->sha1_digest;
 
   SVN_ERR_ASSERT(ffd->rep_sharing_allowed);
   if (! ffd->rep_cache_db)
     SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
 
   /* We only allow SHA1 checksums in this table. */
-  if (rep->sha1_checksum == NULL)
+  if (! rep->has_sha1)
     return svn_error_create(SVN_ERR_BAD_CHECKSUM_KIND, NULL,
                             _("Only SHA1 checksums can be used as keys in the "
                               "rep_cache table.\n"));
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, ffd->rep_cache_db, STMT_SET_REP));
   SVN_ERR(svn_sqlite__bindf(stmt, "siiii",
-                            svn_checksum_to_cstring(rep->sha1_checksum, pool),
+                            svn_checksum_to_cstring(&checksum, pool),
                             (apr_int64_t) rep->revision,
                             (apr_int64_t) rep->offset,
                             (apr_int64_t) rep->size,
@@ -309,8 +319,7 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
          should exist.  If so, and the value is the same one we were
          about to write, that's cool -- just do nothing.  If, however,
          the value is *different*, that's a red flag!  */
-      SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, fs, rep->sha1_checksum,
-                                           pool));
+      SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, fs, &checksum, pool));
 
       if (old_rep)
         {
@@ -327,10 +336,10 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f
                               APR_OFF_T_FMT, SVN_FILESIZE_T_FMT,
                               SVN_FILESIZE_T_FMT, APR_OFF_T_FMT,
                               SVN_FILESIZE_T_FMT, SVN_FILESIZE_T_FMT),
-                 svn_checksum_to_cstring_display(rep->sha1_checksum, pool),
-                 fs->path, old_rep->revision, old_rep->offset, old_rep->size,
-                 old_rep->expanded_size, rep->revision, rep->offset, rep->size,
-                 rep->expanded_size);
+                 svn_checksum_to_cstring_display(&checksum, pool),
+                 fs->path, old_rep->revision, old_rep->offset,
+                 old_rep->size, old_rep->expanded_size, rep->revision,
+                 rep->offset, rep->size, rep->expanded_size);
           else
             return SVN_NO_ERROR;
         }

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.c?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.c Thu Sep 26 13:47:21 2013
@@ -34,6 +34,7 @@
 #include "private/svn_subr_private.h"
 
 #include "temp_serializer.h"
+#include "low_level.h"
 
 /* Utility to encode a signed NUMBER into a variable-length sequence of
  * 8-bit chars in KEY_BUFFER and return the last writen position.
@@ -127,43 +128,6 @@ deserialize_svn_string(void *buffer, svn
   svn_temp_deserializer__resolve(*string, (void **)&(*string)->data);
 }
 
-/* Utility function to serialize checkum CS within the given serialization
- * CONTEXT.
- */
-static void
-serialize_checksum(svn_temp_serializer__context_t *context,
-                   svn_checksum_t * const *cs)
-{
-  const svn_checksum_t *checksum = *cs;
-  if (checksum == NULL)
-    return;
-
-  svn_temp_serializer__push(context,
-                            (const void * const *)cs,
-                            sizeof(*checksum));
-
-  /* The digest is arbitrary binary data.
-   * Thus, we cannot use svn_temp_serializer__add_string. */
-  svn_temp_serializer__add_leaf(context,
-                                (const void * const *)&checksum->digest,
-                                svn_checksum_size(checksum));
-
-  /* return to the caller's nesting level */
-  svn_temp_serializer__pop(context);
-}
-
-/* Utility function to deserialize the checksum CS inside the BUFFER.
- */
-static void
-deserialize_checksum(void *buffer, svn_checksum_t **cs)
-{
-  svn_temp_deserializer__resolve(buffer, (void **)cs);
-  if (*cs == NULL)
-    return;
-
-  svn_temp_deserializer__resolve(*cs, (void **)&(*cs)->digest);
-}
-
 /* Utility function to serialize the REPRESENTATION within the given
  * serialization CONTEXT.
  */
@@ -176,41 +140,9 @@ serialize_representation(svn_temp_serial
     return;
 
   /* serialize the representation struct itself */
-  svn_temp_serializer__push(context,
-                            (const void * const *)representation,
-                            sizeof(*rep));
-
-  /* serialize sub-structures */
-  serialize_checksum(context, &rep->md5_checksum);
-  serialize_checksum(context, &rep->sha1_checksum);
-
-  svn_temp_serializer__add_string(context, &rep->txn_id);
-  svn_temp_serializer__add_string(context, &rep->uniquifier);
-
-  /* return to the caller's nesting level */
-  svn_temp_serializer__pop(context);
-}
-
-/* Utility function to deserialize the REPRESENTATIONS inside the BUFFER.
- */
-static void
-deserialize_representation(void *buffer,
-                           representation_t **representation)
-{
-  representation_t *rep;
-
-  /* fixup the reference to the representation itself */
-  svn_temp_deserializer__resolve(buffer, (void **)representation);
-  rep = *representation;
-  if (rep == NULL)
-    return;
-
-  /* fixup of sub-structures */
-  deserialize_checksum(rep, &rep->md5_checksum);
-  deserialize_checksum(rep, &rep->sha1_checksum);
-
-  svn_temp_deserializer__resolve(rep, (void **)&rep->txn_id);
-  svn_temp_deserializer__resolve(rep, (void **)&rep->uniquifier);
+  svn_temp_serializer__add_leaf(context,
+                                (const void * const *)representation,
+                                sizeof(*rep));
 }
 
 /* auxilliary structure representing the content of a directory hash */
@@ -412,8 +344,8 @@ svn_fs_fs__noderev_deserialize(void *buf
   /* fixup of sub-structures */
   svn_fs_fs__id_deserialize(noderev, (svn_fs_id_t **)&noderev->id);
   svn_fs_fs__id_deserialize(noderev, (svn_fs_id_t **)&noderev->predecessor_id);
-  deserialize_representation(noderev, &noderev->prop_rep);
-  deserialize_representation(noderev, &noderev->data_rep);
+  svn_temp_deserializer__resolve(noderev, (void **)&noderev->prop_rep);
+  svn_temp_deserializer__resolve(noderev, (void **)&noderev->data_rep);
 
   svn_temp_deserializer__resolve(noderev, (void **)&noderev->copyfrom_path);
   svn_temp_deserializer__resolve(noderev, (void **)&noderev->copyroot_path);
@@ -1057,6 +989,36 @@ svn_fs_fs__replace_dir_entry(void **data
   return SVN_NO_ERROR;
 }
 
+svn_error_t  *
+svn_fs_fs__serialize_rep_header(void **data,
+                                apr_size_t *data_len,
+                                void *in,
+                                apr_pool_t *pool)
+{
+  svn_fs_fs__rep_header_t *copy = apr_palloc(pool, sizeof(*copy));
+  *copy = *(svn_fs_fs__rep_header_t *)in;
+
+  *data_len = sizeof(svn_fs_fs__rep_header_t);
+  *data = copy;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__deserialize_rep_header(void **out,
+                                  void *data,
+                                  apr_size_t data_len,
+                                  apr_pool_t *pool)
+{
+  svn_fs_fs__rep_header_t *copy = apr_palloc(pool, sizeof(*copy));
+  SVN_ERR_ASSERT(data_len == sizeof(*copy));
+
+  *copy = *(svn_fs_fs__rep_header_t *)data;
+  *out = data;
+
+  return SVN_NO_ERROR;
+}
+
 /* Utility function to serialize change CHANGE_P in the given serialization
  * CONTEXT.
  */
@@ -1074,10 +1036,10 @@ serialize_change(svn_temp_serializer__co
                             sizeof(*change));
 
   /* serialize sub-structures */
-  svn_fs_fs__id_serialize(context, &change->noderev_id);
+  svn_fs_fs__id_serialize(context, &change->info.node_rev_id);
 
-  svn_temp_serializer__add_string(context, &change->path);
-  svn_temp_serializer__add_string(context, &change->copyfrom_path);
+  svn_temp_serializer__add_string(context, &change->path.data);
+  svn_temp_serializer__add_string(context, &change->info.copyfrom_path);
 
   /* return to the caller's nesting level */
   svn_temp_serializer__pop(context);
@@ -1099,10 +1061,10 @@ deserialize_change(void *buffer, change_
     return;
 
   /* fix-up of sub-structures */
-  svn_fs_fs__id_deserialize(change, (svn_fs_id_t **)&change->noderev_id);
+  svn_fs_fs__id_deserialize(change, (svn_fs_id_t **)&change->info.node_rev_id);
 
-  svn_temp_deserializer__resolve(change, (void **)&change->path);
-  svn_temp_deserializer__resolve(change, (void **)&change->copyfrom_path);
+  svn_temp_deserializer__resolve(change, (void **)&change->path.data);
+  svn_temp_deserializer__resolve(change, (void **)&change->info.copyfrom_path);
 }
 
 /* Auxiliary structure representing the content of a change_t array.

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.h?rev=1526487&r1=1526486&r2=1526487&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/temp_serializer.h Thu Sep 26 13:47:21 2013
@@ -226,6 +226,24 @@ svn_fs_fs__replace_dir_entry(void **data
                              apr_pool_t *pool);
 
 /**
+ * Implements #svn_cache__serialize_func_t for a #svn_fs_fs__rep_header_t.
+ */
+svn_error_t *
+svn_fs_fs__serialize_rep_header(void **data,
+                                apr_size_t *data_len,
+                                void *in,
+                                apr_pool_t *pool);
+
+/**
+ * Implements #svn_cache__deserialize_func_t for a #svn_fs_fs__rep_header_t.
+ */
+svn_error_t *
+svn_fs_fs__deserialize_rep_header(void **out,
+                                  void *data,
+                                  apr_size_t data_len,
+                                  apr_pool_t *pool);
+
+/**
  * Implements #svn_cache__serialize_func_t for an #apr_array_header_t of
  * #change_t *.
  */



Mime
View raw message