You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gb...@apache.org on 2013/12/08 18:56:53 UTC
svn commit: r1549081 [6/18] - in
/subversion/branches/invoke-diff-cmd-feature: ./ build/ build/ac-macros/
build/generator/ build/generator/templates/ contrib/server-side/
contrib/server-side/svncutter/ subversion/bindings/javahl/native/
subversion/bind...
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/caching.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/caching.c Sun Dec 8 17:56:46 2013
@@ -25,6 +25,7 @@
#include "id.h"
#include "dag.h"
#include "tree.h"
+#include "index.h"
#include "temp_serializer.h"
#include "../libsvn_fs/fs-loader.h"
@@ -89,7 +90,7 @@ read_config(svn_memcache_t **memcache_p,
fs_fs_data_t *ffd = fs->fsap_data;
SVN_ERR(svn_cache__make_memcache_from_config(memcache_p, ffd->config,
- fs->pool));
+ fs->pool));
/* No cache namespace by default. I.e. all FS instances share the
* cached data. If you specify different namespaces, the data will
@@ -143,8 +144,8 @@ read_config(svn_memcache_t **memcache_p,
""), "2"))
*cache_revprops
= svn_hash__get_bool(fs->config,
- SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
- FALSE);
+ SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
+ FALSE);
else
*cache_revprops = svn_named_atomic__is_efficient();
@@ -403,7 +404,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
* - Data that can be reconstructed from other elements has low prio
* (e.g. fulltexts, directories etc.)
* - Index data required to find any of the other data has high prio
- * (e.g. noderevs)
+ * (e.g. noderevs, L2P and P2L index pages)
* - everthing else should use default prio
*/
@@ -492,7 +493,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(create_cache(&(ffd->node_revision_cache),
NULL,
membuffer,
- 0, 0, /* Do not use inprocess cache */
+ 32, 32, /* ~200 byte / entry; 1k entries total */
svn_fs_fs__serialize_node_revision,
svn_fs_fs__deserialize_node_revision,
sizeof(pair_cache_key_t),
@@ -506,7 +507,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(create_cache(&(ffd->rep_header_cache),
NULL,
membuffer,
- 0, 0, /* Do not use inprocess cache */
+ 1, 1000, /* ~8 bytes / entry; 1k entries total */
svn_fs_fs__serialize_rep_header,
svn_fs_fs__deserialize_rep_header,
sizeof(representation_cache_key_t),
@@ -520,7 +521,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(create_cache(&(ffd->changes_cache),
NULL,
membuffer,
- 0, 0, /* Do not use inprocess cache */
+ 1, 8, /* 1k / entry; 8 entries total, rarely used */
svn_fs_fs__serialize_changes,
svn_fs_fs__deserialize_changes,
sizeof(svn_revnum_t),
@@ -655,6 +656,71 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
ffd->combined_window_cache = NULL;
}
+ if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ {
+ SVN_ERR(create_cache(&(ffd->l2p_header_cache),
+ NULL,
+ membuffer,
+ 64, 16, /* entry size varies but we must cover
+ a reasonable number of revisions (1k) */
+ svn_fs_fs__serialize_l2p_header,
+ svn_fs_fs__deserialize_l2p_header,
+ sizeof(pair_cache_key_t),
+ apr_pstrcat(pool, prefix, "L2P_HEADER",
+ (char *)NULL),
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ fs,
+ no_handler,
+ fs->pool));
+ SVN_ERR(create_cache(&(ffd->l2p_page_cache),
+ NULL,
+ membuffer,
+ 64, 16, /* entry size varies but we must cover
+ a reasonable number of revisions (1k) */
+ svn_fs_fs__serialize_l2p_page,
+ svn_fs_fs__deserialize_l2p_page,
+ sizeof(svn_fs_fs__page_cache_key_t),
+ apr_pstrcat(pool, prefix, "L2P_PAGE",
+ (char *)NULL),
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ fs,
+ no_handler,
+ fs->pool));
+ SVN_ERR(create_cache(&(ffd->p2l_header_cache),
+ NULL,
+ membuffer,
+ 4, 1, /* Large entries. Rarely used. */
+ svn_fs_fs__serialize_p2l_header,
+ svn_fs_fs__deserialize_p2l_header,
+ sizeof(pair_cache_key_t),
+ apr_pstrcat(pool, prefix, "P2L_HEADER",
+ (char *)NULL),
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ fs,
+ no_handler,
+ fs->pool));
+ SVN_ERR(create_cache(&(ffd->p2l_page_cache),
+ NULL,
+ membuffer,
+ 4, 16, /* Variably sized entries. Rarely used. */
+ svn_fs_fs__serialize_p2l_page,
+ svn_fs_fs__deserialize_p2l_page,
+ sizeof(svn_fs_fs__page_cache_key_t),
+ apr_pstrcat(pool, prefix, "P2L_PAGE",
+ (char *)NULL),
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
+ fs,
+ no_handler,
+ fs->pool));
+ }
+ else
+ {
+ ffd->l2p_header_cache = NULL;
+ ffd->l2p_page_cache = NULL;
+ ffd->p2l_header_cache = NULL;
+ ffd->p2l_page_cache = NULL;
+ }
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.c Sun Dec 8 17:56:46 2013
@@ -221,6 +221,8 @@ static svn_error_t *
initialize_fs_struct(svn_fs_t *fs)
{
fs_fs_data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
+ ffd->min_log_addressing_rev = SVN_INVALID_REVNUM;
+
fs->vtable = &fs_vtable;
fs->fsap_data = ffd;
return SVN_NO_ERROR;
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.h?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs.h Sun Dec 8 17:56:46 2013
@@ -71,6 +71,10 @@ extern "C" {
#define PATH_PACKED "pack" /* Packed revision data file */
#define PATH_EXT_PACKED_SHARD ".pack" /* Extension for packed
shards */
+#define PATH_EXT_L2P_INDEX ".l2p" /* extension of the log-
+ to-phys index */
+#define PATH_EXT_P2L_INDEX ".p2l" /* extension of the phys-
+ to-log index */
/* If you change this, look at tests/svn_test_fs.c(maybe_install_fsfs_conf) */
#define PATH_CONFIG "fsfs.conf" /* Configuration */
@@ -84,6 +88,10 @@ extern "C" {
#define PATH_EXT_PROPS ".props" /* Extension for node props */
#define PATH_EXT_REV ".rev" /* Extension of protorev file */
#define PATH_EXT_REV_LOCK ".rev-lock" /* Extension of protorev lock file */
+#define PATH_TXN_ITEM_INDEX "itemidx" /* File containing the current item
+ index number */
+#define PATH_INDEX "index" /* name of index files w/o ext */
+
/* Names of files in legacy FS formats */
#define PATH_REV "rev" /* Proto rev file */
#define PATH_REV_LOCK "rev-lock" /* Proto rev (write) lock file */
@@ -101,11 +109,19 @@ extern "C" {
#define CONFIG_SECTION_PACKED_REVPROPS "packed-revprops"
#define CONFIG_OPTION_REVPROP_PACK_SIZE "revprop-pack-size"
#define CONFIG_OPTION_COMPRESS_PACKED_REVPROPS "compress-packed-revprops"
+#define CONFIG_SECTION_IO "io"
+#define CONFIG_OPTION_BLOCK_SIZE "block-size"
+#define CONFIG_OPTION_L2P_PAGE_SIZE "l2p-page-size"
+#define CONFIG_OPTION_P2L_PAGE_SIZE "p2l-page-size"
/* The format number of this filesystem.
This is independent of the repository format number, and
- independent of any other FS back ends. */
-#define SVN_FS_FS__FORMAT_NUMBER 6
+ independent of any other FS back ends.
+
+ Note: If you bump this, please update the switch statement in
+ svn_fs_fs__create() as well.
+ */
+#define SVN_FS_FS__FORMAT_NUMBER 7
/* The minimum format number that supports svndiff version 1. */
#define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2
@@ -148,6 +164,9 @@ extern "C" {
/* The minimum format number that supports packed revprops. */
#define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6
+/* The minimum format number that supports packed revprops. */
+#define SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT 7
+
/* Minimum format number that will record moves */
#define SVN_FS_FS__MIN_MOVE_SUPPORT_FORMAT 7
@@ -244,8 +263,8 @@ typedef struct representation_cache_key_
/* Packed or non-packed representation? */
svn_boolean_t is_packed;
- /* Item offset of the representation */
- apr_uint64_t offset;
+ /* Item index of the representation */
+ apr_uint64_t item_index;
} representation_cache_key_t;
/* Key type that identifies a txdelta window. */
@@ -257,8 +276,8 @@ typedef struct window_cache_key_t
/* Window number within that representation */
apr_int32_t chunk_index;
- /* Offset of the representation within REVISION */
- apr_uint64_t offset;
+ /* Item index of the representation */
+ apr_uint64_t item_index;
} window_cache_key_t;
/* Private (non-shared) FSFS-specific data for each svn_fs_t object.
@@ -267,10 +286,26 @@ typedef struct fs_fs_data_t
{
/* The format number of this FS. */
int format;
+
/* The maximum number of files to store per directory (for sharded
layouts) or zero (for linear layouts). */
int max_files_per_dir;
+ /* The first revision that uses logical addressing. SVN_INVALID_REVNUM
+ if there is no such revision (pre-f7 or non-sharded). May be a
+ future revision if the current shard started with physical addressing
+ and is not complete, yet. */
+ svn_revnum_t min_log_addressing_rev;
+
+ /* Rev / pack file read granularity. */
+ apr_int64_t block_size;
+
+ /* Capacity in entries of log-to-phys index pages */
+ apr_int64_t l2p_page_size;
+
+ /* Rev / pack file granularity covered by phys-to-log index pages */
+ apr_int64_t p2l_page_size;
+
/* The revision that was youngest, last time we checked. */
svn_revnum_t youngest_rev_cache;
@@ -332,7 +367,7 @@ typedef struct fs_fs_data_t
the key is window_cache_key_t */
svn_cache__t *combined_window_cache;
- /* Cache for node_revision_t objects; the key is (revision, id offset) */
+ /* Cache for node_revision_t objects; the key is (revision, item_index) */
svn_cache__t *node_revision_cache;
/* Cache for change lists as APR arrays of change_t * objects; the key
@@ -340,7 +375,7 @@ typedef struct fs_fs_data_t
svn_cache__t *changes_cache;
/* Cache for svn_fs_fs__rep_header_t objects; the key is a
- (revision, is_packed, offset) set */
+ (revision, item index) pair */
svn_cache__t *rep_header_cache;
/* Cache for svn_mergeinfo_t objects; the key is a combination of
@@ -352,6 +387,23 @@ typedef struct fs_fs_data_t
if the node has mergeinfo, "0" if it doesn't. */
svn_cache__t *mergeinfo_existence_cache;
+ /* Cache for l2p_header_t objects; the key is (revision, is-packed).
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *l2p_header_cache;
+
+ /* Cache for l2p_page_t objects; the key is svn_fs_fs__page_cache_key_t.
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *l2p_page_cache;
+
+ /* Cache for p2l_header_t objects; the key is (revision, is-packed).
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *p2l_header_cache;
+
+ /* Cache for apr_array_header_t objects containing svn_fs_fs__p2l_entry_t
+ elements; the key is svn_fs_fs__page_cache_key_t.
+ Will be NULL for pre-format7 repos */
+ svn_cache__t *p2l_page_cache;
+
/* TRUE while the we hold a lock on the write lock file. */
svn_boolean_t has_write_lock;
@@ -449,8 +501,8 @@ typedef struct representation_t
/* Revision where this representation is located. */
svn_revnum_t revision;
- /* Offset into the revision file where it is located. */
- svn_filesize_t offset;
+ /* Item index with the the revision. */
+ apr_uint64_t item_index;
/* The size of the representation in bytes as seen in the revision
file. */
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/fs_fs.c Sun Dec 8 17:56:46 2013
@@ -42,7 +42,6 @@
#include "private/svn_fs_util.h"
#include "private/svn_string_private.h"
-#include "private/svn_subr_private.h"
#include "../libsvn_fs/fs-loader.h"
/* The default maximum number of files per directory to store in the
@@ -271,16 +270,21 @@ check_format(int format)
}
/* Read the format number and maximum number of files per directory
- from PATH and return them in *PFORMAT and *MAX_FILES_PER_DIR
- respectively.
+ from PATH and return them in *PFORMAT, *MAX_FILES_PER_DIR and
+ MIN_LOG_ADDRESSING_REV respectively.
*MAX_FILES_PER_DIR is obtained from the 'layout' format option, and
will be set to zero if a linear scheme should be used.
+ *MIN_LOG_ADDRESSING_REV is obtained from the 'addressing' format option,
+ and will be set to SVN_INVALID_REVNUM for physical addressing.
Use POOL for temporary allocation. */
static svn_error_t *
-read_format(int *pformat, int *max_files_per_dir,
- const char *path, apr_pool_t *pool)
+read_format(int *pformat,
+ int *max_files_per_dir,
+ svn_revnum_t *min_log_addressing_rev,
+ const char *path,
+ apr_pool_t *pool)
{
svn_error_t *err;
svn_stream_t *stream;
@@ -325,6 +329,7 @@ read_format(int *pformat, int *max_files
/* Set the default values for anything that can be set via an option. */
*max_files_per_dir = 0;
+ *min_log_addressing_rev = SVN_INVALID_REVNUM;
/* Read any options. */
while (!eos)
@@ -351,17 +356,47 @@ read_format(int *pformat, int *max_files
}
}
+ if (*pformat >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT &&
+ strncmp(buf->data, "addressing ", 11) == 0)
+ {
+ if (strcmp(buf->data + 11, "physical") == 0)
+ {
+ *min_log_addressing_rev = SVN_INVALID_REVNUM;
+ continue;
+ }
+
+ if (strncmp(buf->data + 11, "logical ", 8) == 0)
+ {
+ int value;
+
+ /* Check that the argument is numeric. */
+ SVN_ERR(check_format_file_buffer_numeric(buf->data, 19, path, pool));
+ SVN_ERR(svn_cstring_atoi(&value, buf->data + 19));
+ *min_log_addressing_rev = value;
+ continue;
+ }
+ }
+
return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
_("'%s' contains invalid filesystem format option '%s'"),
svn_dirent_local_style(path, pool), buf->data);
}
+ /* Non-sharded repositories never use logical addressing.
+ * If the format file is inconsistent in that respect, something
+ * probably went wrong.
+ */
+ if (*min_log_addressing_rev != SVN_INVALID_REVNUM && !*max_files_per_dir)
+ return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
+ _("'%s' specifies logical addressing for a non-sharded repository"),
+ svn_dirent_local_style(path, pool));
+
return SVN_NO_ERROR;
}
-/* Write the format number and maximum number of files per directory
- to a new format file in PATH, possibly expecting to overwrite a
- previously existing file.
+/* Write the format number, maximum number of files per directory and
+ the addressing scheme to a new format file in PATH, possibly expecting
+ to overwrite a previously existing file.
Use POOL for temporary allocation. */
svn_error_t *
@@ -387,6 +422,17 @@ svn_fs_fs__write_format(svn_fs_t *fs,
svn_stringbuf_appendcstr(sb, "layout linear\n");
}
+ if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ {
+ if (ffd->min_log_addressing_rev == SVN_INVALID_REVNUM)
+ svn_stringbuf_appendcstr(sb, "addressing physical\n");
+ else
+ svn_stringbuf_appendcstr(sb,
+ apr_psprintf(pool,
+ "addressing logical %ld\n",
+ ffd->min_log_addressing_rev));
+ }
+
/* svn_io_write_version_file() does a load of magic to allow it to
replace version files that already exist. We only need to do
that when we're allowed to overwrite an existing file. */
@@ -482,6 +528,32 @@ read_config(fs_fs_data_t *ffd,
ffd->compress_packed_revprops = FALSE;
}
+ if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ {
+ SVN_ERR(svn_config_get_int64(ffd->config, &ffd->block_size,
+ CONFIG_SECTION_IO,
+ CONFIG_OPTION_BLOCK_SIZE,
+ 64));
+ SVN_ERR(svn_config_get_int64(ffd->config, &ffd->l2p_page_size,
+ CONFIG_SECTION_IO,
+ CONFIG_OPTION_L2P_PAGE_SIZE,
+ 0x2000));
+ SVN_ERR(svn_config_get_int64(ffd->config, &ffd->p2l_page_size,
+ CONFIG_SECTION_IO,
+ CONFIG_OPTION_P2L_PAGE_SIZE,
+ 64));
+
+ ffd->block_size *= 0x400;
+ ffd->p2l_page_size *= 0x400;
+ }
+ else
+ {
+ /* should be irrelevant but we initialize them anyway */
+ ffd->block_size = 0x1000;
+ ffd->l2p_page_size = 0x2000;
+ ffd->p2l_page_size = 0x1000;
+ }
+
return SVN_NO_ERROR;
}
@@ -616,6 +688,58 @@ write_config(svn_fs_t *fs,
"### unless you often modify revprops after packing." NL
"### Compressing packed revprops is disabled by default." NL
"# " CONFIG_OPTION_COMPRESS_PACKED_REVPROPS " = false" NL
+"" NL
+"[" CONFIG_SECTION_IO "]" NL
+"### Parameters in this section control the data access granularity in" NL
+"### format 7 repositories and later. The defaults should translate into" NL
+"### decent performance over a wide range of setups." NL
+"###" NL
+"### When a specific piece of information needs to be read from disk, a" NL
+"### data block is being read at once and its contents are being cached." NL
+"### If the repository is being stored on a RAID, the block size should" NL
+"### be either 50% or 100% of RAID block size / granularity. Also, your" NL
+"### file system (clusters) should be properly aligned and sized. In that" NL
+"### setup, each access will hit only one disk (minimizes I/O load) but" NL
+"### uses all the data provided by the disk in a single access." NL
+"### For SSD-based storage systems, slightly lower values around 16 kB" NL
+"### may improve latency while still maximizing throughput." NL
+"### Can be changed at any time but must be a power of 2." NL
+"### block-size is 64 kBytes by default." NL
+"# " CONFIG_OPTION_BLOCK_SIZE " = 64" NL
+"###" NL
+"### The log-to-phys index maps data item numbers to offsets within the" NL
+"### rev or pack file. A revision typically contains 2 .. 5 such items" NL
+"### per changed path. For each revision, at least one page is being" NL
+"### allocated in the l2p index with unused parts resulting in no wasted" NL
+"### space." NL
+"### Changing this parameter only affects larger revisions with thousands" NL
+"### of changed paths. A smaller value means that more pages need to be" NL
+"### allocated for such revisions, increasing the size of the page table" NL
+"### meaning it takes longer to read that table (once). Access to each" NL
+"### page is then faster because less data has to read. So, if you have" NL
+"### several extremely large revisions (approaching 1 mio changes), think" NL
+"### about increasing this setting. Reducing the value will rarely result" NL
+"### in a net speedup." NL
+"### This is an expert setting. Any non-zero value is possible." NL
+"### l2p-page-size is 8192 entries by default." NL
+"# " CONFIG_OPTION_L2P_PAGE_SIZE " = 8192" NL
+"###" NL
+"### The phys-to-log index maps positions within the rev or pack file to" NL
+"### to data items, i.e. describes what piece of information is being" NL
+"### stored at that particular offset. The index describes the rev file" NL
+"### in chunks (pages) and keeps a global list of all those pages. Large" NL
+"### pages mean a shorter page table but a larger per-page description of" NL
+"### data items in it. The latency sweetspot depends on the change size" NL
+"### distribution but is relatively wide." NL
+"### If the repository contains very large files, i.e. individual changes" NL
+"### of tens of MB each, increasing the page size will shorten the index" NL
+"### file at the expense of a slightly increased latency in sections with" NL
+"### smaller changes." NL
+"### For practical reasons, this should match block-size. Differing" NL
+"### values are perfectly legal but may result in some processing overhead." NL
+"### Must be a power of 2." NL
+"### p2l-page-size is 64 kBytes by default." NL
+"# " CONFIG_OPTION_P2L_PAGE_SIZE " = 64" NL
;
#undef NL
return svn_io_file_create(svn_dirent_join(fs->path, PATH_CONFIG, pool),
@@ -628,18 +752,20 @@ svn_fs_fs__open(svn_fs_t *fs, const char
fs_fs_data_t *ffd = fs->fsap_data;
apr_file_t *uuid_file;
int format, max_files_per_dir;
+ svn_revnum_t min_log_addressing_rev;
char buf[APR_UUID_FORMATTED_LENGTH + 2];
apr_size_t limit;
fs->path = apr_pstrdup(fs->pool, path);
/* Read the FS format number. */
- SVN_ERR(read_format(&format, &max_files_per_dir,
+ SVN_ERR(read_format(&format, &max_files_per_dir, &min_log_addressing_rev,
path_format(fs, pool), pool));
/* Now we've got a format number no matter what. */
ffd->format = format;
ffd->max_files_per_dir = max_files_per_dir;
+ ffd->min_log_addressing_rev = min_log_addressing_rev;
/* Read in and cache the repository uuid. */
SVN_ERR(svn_io_file_open(&uuid_file, path_uuid(fs, pool),
@@ -694,12 +820,14 @@ upgrade_body(void *baton, apr_pool_t *po
svn_fs_t *fs = upgrade_baton->fs;
fs_fs_data_t *ffd = fs->fsap_data;
int format, max_files_per_dir;
+ svn_revnum_t min_log_addressing_rev;
const char *format_path = path_format(fs, pool);
svn_node_kind_t kind;
svn_boolean_t needs_revprop_shard_cleanup = FALSE;
/* Read the FS format number and max-files-per-dir setting. */
- SVN_ERR(read_format(&format, &max_files_per_dir, format_path, pool));
+ SVN_ERR(read_format(&format, &max_files_per_dir, &min_log_addressing_rev,
+ format_path, pool));
/* If the config file does not exist, create one. */
SVN_ERR(svn_io_check_path(svn_dirent_join(fs->path, PATH_CONFIG, pool),
@@ -723,7 +851,7 @@ upgrade_body(void *baton, apr_pool_t *po
if (format == SVN_FS_FS__FORMAT_NUMBER)
return SVN_NO_ERROR;
- /* If our filesystem predates the existance of the 'txn-current
+ /* If our filesystem predates the existence of the 'txn-current
file', make that file and its corresponding lock file. */
if (format < SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
{
@@ -735,7 +863,7 @@ upgrade_body(void *baton, apr_pool_t *po
pool));
}
- /* If our filesystem predates the existance of the 'txn-protorevs'
+ /* If our filesystem predates the existence of the 'txn-protorevs'
dir, make that directory. */
if (format < SVN_FS_FS__MIN_PROTOREVS_DIR_FORMAT)
{
@@ -767,9 +895,19 @@ upgrade_body(void *baton, apr_pool_t *po
pool));
}
+ if ( format < SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT
+ && max_files_per_dir > 0)
+ {
+ min_log_addressing_rev
+ = (ffd->youngest_rev_cache / max_files_per_dir + 1)
+ * max_files_per_dir;
+ }
+
/* Bump the format file. */
ffd->format = SVN_FS_FS__FORMAT_NUMBER;
ffd->max_files_per_dir = max_files_per_dir;
+ ffd->min_log_addressing_rev = min_log_addressing_rev;
+
SVN_ERR(svn_fs_fs__write_format(fs, TRUE, pool));
if (upgrade_baton->notify_func)
SVN_ERR(upgrade_baton->notify_func(upgrade_baton->notify_baton,
@@ -892,7 +1030,7 @@ svn_fs_fs__noderev_same_rep_key(represen
if (a == NULL || b == NULL)
return FALSE;
- if (a->offset != b->offset)
+ if (a->item_index != b->item_index)
return FALSE;
if (a->revision != b->revision)
@@ -957,17 +1095,58 @@ write_revision_zero(svn_fs_t *fs)
svn_string_t date;
/* Write out a rev file for revision 0. */
- SVN_ERR(svn_io_file_create(path_revision_zero,
- "PLAIN\nEND\nENDREP\n"
- "id: 0.0.r0/17\n"
- "type: dir\n"
- "count: 0\n"
- "text: 0 0 4 4 "
- "2d2977d1c96f487abe4a1e202dd03b4e\n"
- "cpath: /\n"
- "\n\n17 107\n", fs->pool));
+ if (svn_fs_fs__use_log_addressing(fs, 0))
+ SVN_ERR(svn_io_file_create(path_revision_zero,
+ "PLAIN\nEND\nENDREP\n"
+ "id: 0.0.r0/2\n"
+ "type: dir\n"
+ "count: 0\n"
+ "text: 0 3 4 4 "
+ "2d2977d1c96f487abe4a1e202dd03b4e\n"
+ "cpath: /\n"
+ "\n\n", fs->pool));
+ else
+ SVN_ERR(svn_io_file_create(path_revision_zero,
+ "PLAIN\nEND\nENDREP\n"
+ "id: 0.0.r0/17\n"
+ "type: dir\n"
+ "count: 0\n"
+ "text: 0 0 4 4 "
+ "2d2977d1c96f487abe4a1e202dd03b4e\n"
+ "cpath: /\n"
+ "\n\n17 107\n", fs->pool));
+
SVN_ERR(svn_io_set_file_read_only(path_revision_zero, FALSE, fs->pool));
+ if (svn_fs_fs__use_log_addressing(fs, 0))
+ {
+ const char *path = svn_fs_fs__path_l2p_index(fs, 0, FALSE, fs->pool);
+ SVN_ERR(svn_io_file_create_binary
+ (path,
+ "\0\x80\x40" /* rev 0, 8k entries per page */
+ "\1\1\1" /* 1 rev, 1 page, 1 page in 1st rev */
+ "\6\4" /* page size: bytes, count */
+ "\0\xd6\1\xb1\1\x21", /* phys offsets + 1 */
+ 14,
+ fs->pool));
+ SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));
+
+ path = svn_fs_fs__path_p2l_index(fs, 0, FALSE, fs->pool);
+ SVN_ERR(svn_io_file_create_binary
+ (path,
+ "\0\x6b" /* start rev, rev file size */
+ "\x80\x80\4\1\x1D" /* 64k pages, 1 page using 29 bytes */
+ "\0" /* offset entry 0 page 1 */
+ /* len, item & type, rev, checksum */
+ "\x11\x34\0\xe0\xc6\xac\xa9\x07"
+ "\x59\x09\0\xc0\xfa\xf8\xc5\x04"
+ "\1\x0d\0\xf2\x95\xbe\xea\x01"
+ "\x95\xff\3\x1b\0\0", /* last entry fills up 64k page */
+ 38,
+ fs->pool));
+ SVN_ERR(svn_io_set_file_read_only(path, FALSE, fs->pool));
+ }
+
/* Set a date on revision 0. */
date.data = svn_time_to_cstring(apr_time_now(), fs->pool);
date.len = strlen(date.data);
@@ -988,14 +1167,36 @@ svn_fs_fs__create(svn_fs_t *fs,
/* See if compatibility with older versions was explicitly requested. */
if (fs->config)
{
- if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_4_COMPATIBLE))
- format = 1;
- else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_5_COMPATIBLE))
- format = 2;
- else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_6_COMPATIBLE))
- format = 3;
- else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_8_COMPATIBLE))
- format = 4;
+ svn_version_t *compatible_version;
+ SVN_ERR(svn_fs__compatible_version(&compatible_version, fs->config,
+ pool));
+
+ /* select format number */
+ switch(compatible_version->minor)
+ {
+ case 0: return svn_error_create(SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
+ _("FSFS is not compatible with Subversion prior to 1.1"));
+
+ case 1:
+ case 2:
+ case 3: format = 1;
+ break;
+
+ case 4: format = 2;
+ break;
+
+ case 5: format = 3;
+ break;
+
+ case 6:
+ case 7: format = 4;
+ break;
+
+ case 8: format = 6;
+ break;
+
+ default:format = SVN_FS_FS__FORMAT_NUMBER;
+ }
}
ffd->format = format;
@@ -1003,6 +1204,12 @@ svn_fs_fs__create(svn_fs_t *fs,
if (format >= SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT)
ffd->max_files_per_dir = SVN_FS_FS_DEFAULT_MAX_FILES_PER_DIR;
+ /* Select the addressing mode depending on the format. */
+ if (format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+ ffd->min_log_addressing_rev = 0;
+ else
+ ffd->min_log_addressing_rev = SVN_INVALID_REVNUM;
+
/* Create the revision data directories. */
if (ffd->max_files_per_dir)
SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_rev_shard(fs, 0,
@@ -1045,7 +1252,12 @@ svn_fs_fs__create(svn_fs_t *fs,
SVN_ERR(write_revision_zero(fs));
- SVN_ERR(write_config(fs, pool));
+ /* Create the fsfs.conf file if supported. Older server versions would
+ simply ignore the file but that might result in a different behavior
+ than with the later releases. Also, hotcopy would ignore, i.e. not
+ copy, a fsfs.conf with old formats. */
+ if (ffd->format >= SVN_FS_FS__MIN_CONFIG_FILE)
+ SVN_ERR(write_config(fs, pool));
SVN_ERR(read_config(ffd, fs->path, pool));
@@ -1379,8 +1591,11 @@ svn_fs_fs__info_format(int *fs_format,
case 6:
(*supports_version)->minor = 8;
break;
+ case 7:
+ (*supports_version)->minor = 9;
+ break;
#ifdef SVN_DEBUG
-# if SVN_FS_FS__FORMAT_NUMBER != 6
+# if SVN_FS_FS__FORMAT_NUMBER != 7
# error "Need to add a 'case' statement here"
# endif
#endif
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/hotcopy.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/hotcopy.c Sun Dec 8 17:56:46 2013
@@ -228,12 +228,14 @@ hotcopy_io_copy_dir_recursively(const ch
/* Copy an un-packed revision or revprop file for revision REV from SRC_SUBDIR
* to DST_SUBDIR. Assume a sharding layout based on MAX_FILES_PER_DIR.
+ * If INCLUDE_INDEXES is set, copy rev index files as well.
* Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
hotcopy_copy_shard_file(const char *src_subdir,
const char *dst_subdir,
svn_revnum_t rev,
int max_files_per_dir,
+ svn_boolean_t include_indexes,
apr_pool_t *scratch_pool)
{
const char *src_subdir_shard = src_subdir,
@@ -257,6 +259,19 @@ hotcopy_copy_shard_file(const char *src_
SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
apr_psprintf(scratch_pool, "%ld", rev),
scratch_pool));
+
+ if (include_indexes)
+ {
+ SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
+ apr_psprintf(scratch_pool, "%ld.l2p",
+ rev),
+ scratch_pool));
+ SVN_ERR(hotcopy_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
+ apr_psprintf(scratch_pool, "%ld.p2l",
+ rev),
+ scratch_pool));
+ }
+
return SVN_NO_ERROR;
}
@@ -312,7 +327,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
revprop_rev, max_files_per_dir,
- iterpool));
+ FALSE, iterpool));
}
svn_pool_destroy(iterpool);
}
@@ -321,7 +336,7 @@ hotcopy_copy_packed_shard(svn_revnum_t *
/* revprop for revision 0 will never be packed */
if (rev == 0)
SVN_ERR(hotcopy_copy_shard_file(src_subdir, dst_subdir,
- 0, max_files_per_dir,
+ 0, max_files_per_dir, FALSE,
scratch_pool));
/* packed revprops folder */
@@ -379,17 +394,33 @@ hotcopy_update_current(svn_revnum_t *dst
return SVN_NO_ERROR;
}
+/* Remove FILE in SHARD folder. Use POOL for temporary allocations. */
+static svn_error_t *
+hotcopy_remove_file(const char *shard,
+ const char *file,
+ apr_pool_t *pool)
+{
+ const char *rev_path = svn_dirent_join(shard, file, pool);
+
+ /* Make the rev file writable and remove it. */
+ SVN_ERR(svn_io_set_file_read_write(rev_path, TRUE, pool));
+ SVN_ERR(svn_io_remove_file2(rev_path, TRUE, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* Remove revision or revprop files between START_REV (inclusive) and
- * END_REV (non-inclusive) from folder DST_SUBDIR in DST_FS. Assume
- * sharding as per MAX_FILES_PER_DIR.
- * Use SCRATCH_POOL for temporary allocations. */
+ * END_REV (non-inclusive) from folder DST_SUBDIR in DST_FS. Also,
+ * remove index files if REMOVE_INDEXES is set. Assume sharding as per
+ * MAX_FILES_PER_DIR. Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
hotcopy_remove_files(svn_fs_t *dst_fs,
const char *dst_subdir,
svn_revnum_t start_rev,
svn_revnum_t end_rev,
int max_files_per_dir,
+ svn_boolean_t remove_indexes,
apr_pool_t *scratch_pool)
{
const char *shard;
@@ -404,7 +435,6 @@ hotcopy_remove_files(svn_fs_t *dst_fs,
iterpool = svn_pool_create(scratch_pool);
for (rev = start_rev; rev < end_rev; rev++)
{
- const char *path;
svn_pool_clear(iterpool);
/* If necessary, update paths for shard. */
@@ -415,13 +445,18 @@ hotcopy_remove_files(svn_fs_t *dst_fs,
}
/* remove files for REV */
- path = svn_dirent_join(dst_subdir_shard,
- apr_psprintf(iterpool, "%ld", rev),
- iterpool);
-
- /* Make the rev file writable and remove it. */
- SVN_ERR(svn_io_set_file_read_write(path, TRUE, iterpool));
- SVN_ERR(svn_io_remove_file2(path, TRUE, iterpool));
+ SVN_ERR(hotcopy_remove_file(dst_subdir_shard,
+ apr_psprintf(iterpool, "%ld", rev),
+ iterpool));
+ if (remove_indexes && svn_fs_fs__use_log_addressing(dst_fs, rev))
+ {
+ SVN_ERR(hotcopy_remove_file(dst_subdir_shard,
+ apr_psprintf(iterpool, "%ld.p2l", rev),
+ iterpool));
+ SVN_ERR(hotcopy_remove_file(dst_subdir_shard,
+ apr_psprintf(iterpool, "%ld.l2p", rev),
+ iterpool));
+ }
}
svn_pool_destroy(iterpool);
@@ -445,7 +480,7 @@ hotcopy_remove_rev_files(svn_fs_t *dst_f
PATH_REVS_DIR,
scratch_pool),
start_rev, end_rev,
- max_files_per_dir, scratch_pool));
+ max_files_per_dir, TRUE, scratch_pool));
return SVN_NO_ERROR;
}
@@ -469,7 +504,7 @@ hotcopy_remove_revprop_files(svn_fs_t *d
PATH_REVPROPS_DIR,
scratch_pool),
start_rev ? start_rev : 1, end_rev,
- max_files_per_dir, scratch_pool));
+ max_files_per_dir, FALSE, scratch_pool));
return SVN_NO_ERROR;
}
@@ -772,6 +807,7 @@ hotcopy_body(void *baton, apr_pool_t *po
/* Copy the rev file. */
err = hotcopy_copy_shard_file(src_subdir, dst_subdir,
rev, max_files_per_dir,
+ svn_fs_fs__use_log_addressing(src_fs, rev),
iterpool);
if (err)
{
@@ -822,7 +858,7 @@ hotcopy_body(void *baton, apr_pool_t *po
/* Copy the revprop file. */
SVN_ERR(hotcopy_copy_shard_file(revprop_src_subdir,
revprop_dst_subdir,
- rev, max_files_per_dir,
+ rev, max_files_per_dir, FALSE,
iterpool));
/* After completing a full shard, update 'current'. */
@@ -935,6 +971,7 @@ hotcopy_create_empty_dest(svn_fs_t *src_
dst_fs->path = apr_pstrdup(pool, dst_path);
dst_ffd->max_files_per_dir = src_ffd->max_files_per_dir;
+ dst_ffd->min_log_addressing_rev = src_ffd->min_log_addressing_rev;
dst_ffd->config = src_ffd->config;
dst_ffd->format = src_ffd->format;
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=1549081&r1=1549080&r2=1549081&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 Sun Dec 8 17:56:46 2013
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include "id.h"
+#include "index.h"
#include "../libsvn_fs/fs-loader.h"
#include "private/svn_temp_serializer.h"
@@ -41,7 +42,7 @@ typedef struct fs_fs__id_t
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;
+ svn_fs_fs__id_part_t rev_item;
} private_id;
} fs_fs__id_t;
@@ -214,11 +215,11 @@ svn_fs_fs__id_txn_id(const svn_fs_id_t *
const svn_fs_fs__id_part_t *
-svn_fs_fs__id_rev_offset(const svn_fs_id_t *fs_id)
+svn_fs_fs__id_rev_item(const svn_fs_id_t *fs_id)
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return &id->private_id.rev_offset;
+ return &id->private_id.rev_item;
}
svn_revnum_t
@@ -226,15 +227,15 @@ svn_fs_fs__id_rev(const svn_fs_id_t *fs_
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return id->private_id.rev_offset.revision;
+ return id->private_id.rev_item.revision;
}
apr_uint64_t
-svn_fs_fs__id_offset(const svn_fs_id_t *fs_id)
+svn_fs_fs__id_item(const svn_fs_id_t *fs_id)
{
fs_fs__id_t *id = (fs_fs__id_t *)fs_id;
- return id->private_id.rev_offset.number;
+ return id->private_id.rev_item.number;
}
svn_boolean_t
@@ -265,9 +266,9 @@ svn_fs_fs__id_unparse(const svn_fs_id_t
else
{
*(p++) = 'r';
- p += svn__i64toa(p, id->private_id.rev_offset.revision);
+ p += svn__i64toa(p, id->private_id.rev_item.revision);
*(p++) = '/';
- p += svn__i64toa(p, id->private_id.rev_offset.number);
+ p += svn__i64toa(p, id->private_id.rev_item.number);
}
return svn_string_ncreate(string, p - string, pool);
@@ -355,7 +356,22 @@ svn_fs_fs__id_txn_create_root(const svn_
/* node ID and copy ID are "0" */
id->private_id.txn_id = *txn_id;
- id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
+ id->private_id.rev_item.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_create_root(const svn_revnum_t revision,
+ apr_pool_t *pool)
+{
+ fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
+
+ id->private_id.txn_id.revision = SVN_INVALID_REVNUM;
+ id->private_id.rev_item.revision = revision;
+ id->private_id.rev_item.number = SVN_FS_FS__ITEM_INDEX_ROOT_NODE;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -374,7 +390,7 @@ svn_fs_fs__id_txn_create(const svn_fs_fs
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;
+ id->private_id.rev_item.revision = SVN_INVALID_REVNUM;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -386,7 +402,7 @@ svn_fs_fs__id_txn_create(const svn_fs_fs
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,
+ const svn_fs_fs__id_part_t *rev_item,
apr_pool_t *pool)
{
fs_fs__id_t *id = apr_pcalloc(pool, sizeof(*id));
@@ -394,7 +410,7 @@ svn_fs_fs__id_rev_create(const svn_fs_fs
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;
+ id->private_id.rev_item = *rev_item;
id->generic_id.vtable = &id_vtable;
id->generic_id.fsap_data = &id;
@@ -471,7 +487,7 @@ svn_fs_fs__id_parse(const char *data,
str = svn_cstring_tokenize("/", &data_copy);
if (str == NULL)
return NULL;
- id->private_id.rev_offset.revision = SVN_STR_TO_REV(str);
+ id->private_id.rev_item.revision = SVN_STR_TO_REV(str);
err = svn_cstring_atoi64(&val, data_copy);
if (err)
@@ -479,13 +495,13 @@ svn_fs_fs__id_parse(const char *data,
svn_error_clear(err);
return NULL;
}
- id->private_id.rev_offset.number = (apr_uint64_t)val;
+ id->private_id.rev_item.number = (apr_uint64_t)val;
}
else if (str[0] == 't')
{
/* This is a transaction type ID */
- id->private_id.rev_offset.revision = SVN_INVALID_REVNUM;
- id->private_id.rev_offset.number = 0;
+ id->private_id.rev_item.revision = SVN_INVALID_REVNUM;
+ id->private_id.rev_item.number = 0;
if (! txn_id_parse(&id->private_id.txn_id, str + 1))
return NULL;
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=1549081&r1=1549080&r2=1549081&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 Sun Dec 8 17:56:46 2013
@@ -45,7 +45,7 @@ typedef struct svn_fs_fs__id_part_t
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
+ the part itself. In rev_item, it is the index_index value, in others
it represents a unique counter value. */
apr_uint64_t number;
} svn_fs_fs__id_part_t;
@@ -88,16 +88,16 @@ const svn_fs_fs__id_part_t *svn_fs_fs__i
/* Get the "txn id" portion of ID, or NULL if it is a permanent 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,item" portion of ID. */
+const svn_fs_fs__id_part_t *svn_fs_fs__id_rev_item(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 0 if it is a transaction
+/* Access the "item" portion of the ID, or 0 if it is a transaction
ID. */
-apr_uint64_t svn_fs_fs__id_offset(const svn_fs_id_t *id);
+apr_uint64_t svn_fs_fs__id_item(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);
@@ -126,6 +126,11 @@ int svn_fs_fs__id_part_compare(const svn
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 the root ID for REVISION (logical addressing node only).
+ Allocate it in POOL. */
+svn_fs_id_t *svn_fs_fs__id_create_root(const svn_revnum_t revision,
+ 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 svn_fs_fs__id_part_t *node_id,
@@ -133,11 +138,11 @@ svn_fs_id_t *svn_fs_fs__id_txn_create(co
const svn_fs_fs__id_part_t *txn_id,
apr_pool_t *pool);
-/* Create a permanent ID based on NODE_ID, COPY_ID and REV_OFFSET,
+/* Create a permanent ID based on NODE_ID, COPY_ID and REV_ITEM,
allocated in POOL. */
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,
+ const svn_fs_fs__id_part_t *rev_item,
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=1549081&r1=1549080&r2=1549081&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 Sun Dec 8 17:56:46 2013
@@ -252,24 +252,23 @@ read_digest_file(apr_hash_t **children_p
apr_hash_t *hash;
svn_stream_t *stream;
const char *val;
+ svn_node_kind_t kind;
if (lock_p)
*lock_p = NULL;
if (children_p)
*children_p = apr_hash_make(pool);
- err = svn_stream_open_readonly(&stream, digest_path, pool, pool);
- if (err && APR_STATUS_IS_ENOENT(err->apr_err))
- {
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- SVN_ERR(err);
+ SVN_ERR(svn_io_check_path(digest_path, &kind, pool));
+ if (kind == svn_node_none)
+ return SVN_NO_ERROR;
/* If our caller doesn't care about anything but the presence of the
file... whatever. */
- if (! (lock_p || children_p))
- return svn_stream_close(stream);
+ if (kind == svn_node_file && !lock_p && !children_p)
+ return SVN_NO_ERROR;
+
+ SVN_ERR(svn_stream_open_readonly(&stream, digest_path, pool, pool));
hash = apr_hash_make(pool);
if ((err = svn_hash_read2(hash, stream, SVN_HASH_TERMINATOR, pool)))
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.c Sun Dec 8 17:56:46 2013
@@ -25,6 +25,7 @@
#include "svn_pools.h"
#include "svn_sorts.h"
#include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
#include "../libsvn_fs/fs-loader.h"
@@ -482,13 +483,14 @@ read_header_block(apr_hash_t **headers,
svn_stream_t *stream,
apr_pool_t *pool)
{
- *headers = apr_hash_make(pool);
+ *headers = svn_hash__make(pool);
while (1)
{
svn_stringbuf_t *header_str;
const char *name, *value;
- apr_size_t i = 0;
+ apr_ssize_t i = 0;
+ apr_ssize_t name_len;
svn_boolean_t eof;
SVN_ERR(svn_stream_readline(stream, &header_str, "\n", &eof, pool));
@@ -509,6 +511,7 @@ read_header_block(apr_hash_t **headers,
/* Create a 'name' string and point to it. */
header_str->data[i] = '\0';
name = header_str->data;
+ name_len = i;
/* Skip over the NULL byte and the space following it. */
i += 2;
@@ -528,7 +531,7 @@ read_header_block(apr_hash_t **headers,
/* header_str is safely in our pool, so we can use bits of it as
key and value. */
- svn_hash_sets(*headers, name, value);
+ apr_hash_set(*headers, name, name_len, value);
}
return SVN_NO_ERROR;
@@ -571,7 +574,7 @@ svn_fs_fs__parse_representation(represen
}
SVN_ERR(svn_cstring_atoi64(&val, str));
- rep->offset = (apr_off_t)val;
+ rep->item_index = (apr_uint64_t)val;
str = svn_cstring_tokenize(" ", &string);
if (str == NULL)
@@ -851,17 +854,17 @@ svn_fs_fs__unparse_representation(repres
if (format < SVN_FS_FS__MIN_REP_SHARING_FORMAT || !rep->has_sha1)
return svn_stringbuf_createf
- (pool, "%ld %" APR_OFF_T_FMT " %" SVN_FILESIZE_T_FMT
+ (pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
" %" SVN_FILESIZE_T_FMT " %s",
- rep->revision, rep->offset, rep->size,
+ rep->revision, rep->item_index, rep->size,
rep->expanded_size,
format_digest(rep->md5_digest, svn_checksum_md5, FALSE, pool));
svn__ui64tobase36(buffer, rep->uniquifier.number);
return svn_stringbuf_createf
- (pool, "%ld %" APR_OFF_T_FMT " %" SVN_FILESIZE_T_FMT
+ (pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
" %" SVN_FILESIZE_T_FMT " %s %s %s/_%s",
- rep->revision, rep->offset, rep->size,
+ rep->revision, rep->item_index, rep->size,
rep->expanded_size,
format_digest(rep->md5_digest, svn_checksum_md5, FALSE, pool),
format_digest(rep->sha1_digest, svn_checksum_sha1,
@@ -985,7 +988,7 @@ svn_fs_fs__read_rep_header(svn_fs_fs__re
if (! str)
goto error;
SVN_ERR(svn_cstring_atoi64(&val, str));
- (*header)->base_offset = (apr_off_t)val;
+ (*header)->base_item_index = (apr_off_t)val;
str = svn_cstring_tokenize(" ", &last_str);
if (! str)
@@ -1020,7 +1023,7 @@ svn_fs_fs__write_rep_header(svn_fs_fs__r
default:
text = apr_psprintf(pool, REP_DELTA " %ld %" APR_OFF_T_FMT " %"
SVN_FILESIZE_T_FMT "\n",
- header->base_revision, header->base_offset,
+ header->base_revision, header->base_item_index,
header->base_length);
}
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.h?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_fs_fs/low_level.h Sun Dec 8 17:56:46 2013
@@ -142,9 +142,9 @@ typedef struct svn_fs_fs__rep_header_t
svn_revnum_t base_revision;
/* if this rep is a delta against some other rep, that base rep can
- * be found at this offset within the base rep's revision. Should
+ * be found at this item index within the base rep's revision. Should
* be 0 if there is no base rep. */
- apr_off_t base_offset;
+ apr_off_t base_item_index;
/* if this rep is a delta against some other rep, this is the (deltified)
* size of that base rep. Should be 0 if there is no base rep. */