You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/04/29 20:38:56 UTC
svn commit: r1741682 [6/26] - in /subversion/branches/authzperf: ./ build/
build/ac-macros/ build/generator/ contrib/server-side/svncutter/ notes/
notes/api-errata/1.9/ notes/move-tracking/ subversion/
subversion/bindings/ctypes-python/ subversion/bind...
Modified: subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.c Fri Apr 29 18:38:53 2016
@@ -26,7 +26,6 @@
#include <apr.h>
#include <apr_atomic.h>
#include <apr_hash.h>
-#include <apr_md5.h>
#include <apr_uuid.h>
#include <apr_strings.h>
@@ -46,6 +45,7 @@
#include "private/svn_atomic.h"
#include "private/svn_fs_private.h"
#include "private/svn_fs_util.h"
+#include "private/svn_fspath.h"
#include "private/svn_utf_private.h"
#include "private/svn_mutex.h"
#include "private/svn_subr_private.h"
@@ -60,6 +60,22 @@
#define FS_TYPE_FILENAME "fs-type"
+/* If a FS backend does not implement the PATHS_CHANGED vtable function,
+ it will get emulated. However, if this macro is defined to non-null
+ then the API will always be emulated when feasible, i.e. the calls
+ get "re-directed" to the old API implementation. */
+#ifndef SVN_FS_EMULATE_PATHS_CHANGED
+#define SVN_FS_EMULATE_PATHS_CHANGED TRUE
+#endif
+
+/* If a FS backend does not implement the REPORT_CHANGES vtable function,
+ it will get emulated. However, if this macro is defined to non-null
+ then the API will always be emulated when feasible, i.e. the calls
+ get "re-directed" to the old API implementation. */
+#ifndef SVN_FS_EMULATE_REPORT_CHANGES
+#define SVN_FS_EMULATE_REPORT_CHANGES TRUE
+#endif
+
/* A pool common to all FS objects. See the documentation on the
open/create functions in fs-loader.h and for svn_fs_initialize(). */
static apr_pool_t *common_pool = NULL;
@@ -506,24 +522,28 @@ svn_fs_set_warning_func(svn_fs_t *fs, sv
}
svn_error_t *
-svn_fs_create(svn_fs_t **fs_p, const char *path, apr_hash_t *fs_config,
- apr_pool_t *pool)
+svn_fs_create2(svn_fs_t **fs_p,
+ const char *path,
+ apr_hash_t *fs_config,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
fs_library_vtable_t *vtable;
const char *fs_type = svn_hash__get_cstring(fs_config,
SVN_FS_CONFIG_FS_TYPE,
DEFAULT_FS_TYPE);
- SVN_ERR(get_library_vtable(&vtable, fs_type, pool));
+ SVN_ERR(get_library_vtable(&vtable, fs_type, scratch_pool));
/* Create the FS directory and write out the fsap-name file. */
- SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, pool));
- SVN_ERR(write_fs_type(path, fs_type, pool));
+ SVN_ERR(svn_io_dir_make_sgid(path, APR_OS_DEFAULT, scratch_pool));
+ SVN_ERR(write_fs_type(path, fs_type, scratch_pool));
/* Perform the actual creation. */
- *fs_p = fs_new(fs_config, pool);
+ *fs_p = fs_new(fs_config, result_pool);
- SVN_ERR(vtable->create(*fs_p, path, common_pool_lock, pool, common_pool));
+ SVN_ERR(vtable->create(*fs_p, path, common_pool_lock, scratch_pool,
+ common_pool));
SVN_ERR(vtable->set_svn_fs_open(*fs_p, svn_fs_open2));
return SVN_NO_ERROR;
@@ -546,15 +566,6 @@ svn_fs_open2(svn_fs_t **fs_p, const char
}
svn_error_t *
-svn_fs_open(svn_fs_t **fs_p,
- const char *path,
- apr_hash_t *fs_config,
- apr_pool_t *pool)
-{
- return svn_fs_open2(fs_p, path, fs_config, pool, pool);
-}
-
-svn_error_t *
svn_fs_upgrade2(const char *path,
svn_fs_upgrade_notify_t notify_func,
void *notify_baton,
@@ -1045,40 +1056,163 @@ svn_fs_revision_root_revision(svn_fs_roo
}
svn_error_t *
+svn_fs_path_change_get(svn_fs_path_change3_t **change,
+ svn_fs_path_change_iterator_t *iterator)
+{
+ return iterator->vtable->get(change, iterator);
+}
+
+svn_error_t *
svn_fs_paths_changed2(apr_hash_t **changed_paths_p,
svn_fs_root_t *root,
apr_pool_t *pool)
{
- return root->vtable->paths_changed(changed_paths_p, root, pool);
+ svn_boolean_t emulate = !root->vtable->paths_changed
+ || SVN_FS_EMULATE_PATHS_CHANGED;
+
+ if (emulate)
+ {
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
+ apr_hash_t *changes = svn_hash__make(pool);
+
+ svn_fs_path_change_iterator_t *iterator;
+ svn_fs_path_change3_t *change;
+
+ SVN_ERR(svn_fs_paths_changed3(&iterator, root, scratch_pool,
+ scratch_pool));
+
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
+ while (change)
+ {
+ svn_fs_path_change2_t *copy;
+ const svn_fs_id_t *id_copy;
+ const char *change_path = change->path.data;
+ svn_fs_root_t *change_root = root;
+
+ /* Copy CHANGE to old API struct. */
+ if (change->change_kind == svn_fs_path_change_delete)
+ SVN_ERR(svn_fs__get_deleted_node(&change_root, &change_path,
+ change_root, change_path,
+ scratch_pool, scratch_pool));
+
+ SVN_ERR(svn_fs_node_id(&id_copy, change_root, change_path, pool));
+
+ copy = svn_fs_path_change2_create(id_copy, change->change_kind,
+ pool);
+ copy->copyfrom_known = change->copyfrom_known;
+ if ( copy->copyfrom_known
+ && SVN_IS_VALID_REVNUM(change->copyfrom_rev))
+ {
+ copy->copyfrom_rev = change->copyfrom_rev;
+ copy->copyfrom_path = apr_pstrdup(pool, change->copyfrom_path);
+ }
+ copy->mergeinfo_mod = change->mergeinfo_mod;
+ copy->node_kind = change->node_kind;
+ copy->prop_mod = change->prop_mod;
+ copy->text_mod = change->text_mod;
+
+ svn_hash_sets(changes, apr_pstrmemdup(pool, change->path.data,
+ change->path.len), copy);
+
+ /* Next change. */
+ SVN_ERR(svn_fs_path_change_get(&change, iterator));
+ }
+ svn_pool_destroy(scratch_pool);
+
+ *changed_paths_p = changes;
+ }
+ else
+ {
+ SVN_ERR(root->vtable->paths_changed(changed_paths_p, root, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Implement svn_fs_path_change_iterator_t on top of svn_fs_paths_changed2. */
+
+/* The iterator builds upon a hash iterator, which in turn operates on the
+ full prefetched changes list. */
+typedef struct fsap_iterator_data_t
+{
+ apr_hash_index_t *hi;
+
+ /* For efficicency such that we don't need to dynamically allocate
+ yet another copy of that data. */
+ svn_fs_path_change3_t change;
+} fsap_iterator_data_t;
+
+static svn_error_t *
+changes_iterator_get(svn_fs_path_change3_t **change,
+ svn_fs_path_change_iterator_t *iterator)
+{
+ fsap_iterator_data_t *data = iterator->fsap_data;
+
+ if (data->hi)
+ {
+ const char *path = apr_hash_this_key(data->hi);
+ svn_fs_path_change2_t *entry = apr_hash_this_val(data->hi);
+
+ data->change.path.data = path;
+ data->change.path.len = apr_hash_this_key_len(data->hi);
+ data->change.change_kind = entry->change_kind;
+ data->change.node_kind = entry->node_kind;
+ data->change.text_mod = entry->text_mod;
+ data->change.prop_mod = entry->prop_mod;
+ data->change.mergeinfo_mod = entry->mergeinfo_mod;
+ data->change.copyfrom_known = entry->copyfrom_known;
+ data->change.copyfrom_rev = entry->copyfrom_rev;
+ data->change.copyfrom_path = entry->copyfrom_path;
+
+ *change = &data->change;
+ data->hi = apr_hash_next(data->hi);
+ }
+ else
+ {
+ *change = NULL;
+ }
+
+ return SVN_NO_ERROR;
}
+static changes_iterator_vtable_t iterator_vtable =
+{
+ changes_iterator_get
+};
+
svn_error_t *
-svn_fs_paths_changed(apr_hash_t **changed_paths_p, svn_fs_root_t *root,
- apr_pool_t *pool)
+svn_fs_paths_changed3(svn_fs_path_change_iterator_t **iterator,
+ svn_fs_root_t *root,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- apr_hash_t *changed_paths_new_structs;
- apr_hash_index_t *hi;
+ svn_boolean_t emulate = !root->vtable->report_changes
+ || ( SVN_FS_EMULATE_REPORT_CHANGES
+ && root->vtable->paths_changed);
+
+ if (emulate)
+ {
+ svn_fs_path_change_iterator_t *result;
+ fsap_iterator_data_t *data;
+
+ apr_hash_t *changes;
+ SVN_ERR(root->vtable->paths_changed(&changes, root, result_pool));
- SVN_ERR(svn_fs_paths_changed2(&changed_paths_new_structs, root, pool));
- *changed_paths_p = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, changed_paths_new_structs);
- hi;
- hi = apr_hash_next(hi))
- {
- const void *vkey;
- apr_ssize_t klen;
- void *vval;
- svn_fs_path_change2_t *val;
- svn_fs_path_change_t *change;
- apr_hash_this(hi, &vkey, &klen, &vval);
- val = vval;
- change = apr_palloc(pool, sizeof(*change));
- change->node_rev_id = val->node_rev_id;
- change->change_kind = val->change_kind;
- change->text_mod = val->text_mod;
- change->prop_mod = val->prop_mod;
- apr_hash_set(*changed_paths_p, vkey, klen, change);
+ data = apr_pcalloc(result_pool, sizeof(*data));
+ data->hi = apr_hash_first(result_pool, changes);
+
+ result = apr_pcalloc(result_pool, sizeof(*result));
+ result->fsap_data = data;
+ result->vtable = &iterator_vtable;
+
+ *iterator = result;
+ }
+ else
+ {
+ SVN_ERR(root->vtable->report_changes(iterator, root, result_pool,
+ scratch_pool));
}
+
return SVN_NO_ERROR;
}
@@ -1100,14 +1234,6 @@ svn_fs_node_history2(svn_fs_history_t **
}
svn_error_t *
-svn_fs_node_history(svn_fs_history_t **history_p, svn_fs_root_t *root,
- const char *path, apr_pool_t *pool)
-{
- return svn_error_trace(root->vtable->node_history(history_p, root, path,
- pool, pool));
-}
-
-svn_error_t *
svn_fs_is_dir(svn_boolean_t *is_dir, svn_fs_root_t *root, const char *path,
apr_pool_t *pool)
{
@@ -1268,20 +1394,6 @@ svn_fs_get_mergeinfo2(svn_mergeinfo_cata
}
svn_error_t *
-svn_fs_get_mergeinfo(svn_mergeinfo_catalog_t *catalog,
- svn_fs_root_t *root,
- const apr_array_header_t *paths,
- svn_mergeinfo_inheritance_t inherit,
- svn_boolean_t include_descendants,
- apr_pool_t *pool)
-{
- return svn_error_trace(root->vtable->get_mergeinfo(catalog, root, paths,
- inherit,
- include_descendants,
- TRUE, pool, pool));
-}
-
-svn_error_t *
svn_fs__get_mergeinfo_for_path(svn_mergeinfo_t *mergeinfo,
svn_fs_root_t *root,
const char *path,
@@ -1404,21 +1516,6 @@ svn_fs_file_checksum(svn_checksum_t **ch
}
svn_error_t *
-svn_fs_file_md5_checksum(unsigned char digest[],
- svn_fs_root_t *root,
- const char *path,
- apr_pool_t *pool)
-{
- svn_checksum_t *md5sum;
-
- SVN_ERR(svn_fs_file_checksum(&md5sum, svn_checksum_md5, root, path, TRUE,
- pool));
- memcpy(digest, md5sum->digest, APR_MD5_DIGESTSIZE);
-
- return SVN_NO_ERROR;
-}
-
-svn_error_t *
svn_fs_file_contents(svn_stream_t **contents, svn_fs_root_t *root,
const char *path, apr_pool_t *pool)
{
@@ -1553,19 +1650,39 @@ svn_fs_deltify_revision(svn_fs_t *fs, sv
}
svn_error_t *
-svn_fs_revision_prop(svn_string_t **value_p, svn_fs_t *fs, svn_revnum_t rev,
- const char *propname, apr_pool_t *pool)
+svn_fs_refresh_revision_props(svn_fs_t *fs,
+ apr_pool_t *scratch_pool)
+{
+ return svn_error_trace(fs->vtable->refresh_revprops(fs, scratch_pool));
+}
+
+svn_error_t *
+svn_fs_revision_prop2(svn_string_t **value_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ const char *propname,
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
return svn_error_trace(fs->vtable->revision_prop(value_p, fs, rev,
- propname, pool));
+ propname, refresh,
+ result_pool,
+ scratch_pool));
}
svn_error_t *
-svn_fs_revision_proplist(apr_hash_t **table_p, svn_fs_t *fs, svn_revnum_t rev,
- apr_pool_t *pool)
+svn_fs_revision_proplist2(apr_hash_t **table_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
return svn_error_trace(fs->vtable->revision_proplist(table_p, fs, rev,
- pool));
+ refresh,
+ result_pool,
+ scratch_pool));
}
svn_error_t *
@@ -1592,6 +1709,64 @@ svn_fs_get_file_delta_stream(svn_txdelta
}
svn_error_t *
+svn_fs__get_deleted_node(svn_fs_root_t **node_root,
+ const char **node_path,
+ svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const char *parent_path, *name;
+ svn_fs_root_t *copy_root;
+ const char *copy_path;
+
+ /* History traversal does not work with transaction roots.
+ * Therefore, do it "by hand". */
+
+ /* If the parent got copied in ROOT, PATH got copied with it.
+ * Otherwise, we will find the node at PATH in the revision prior to ROOT.
+ */
+ svn_fspath__split(&parent_path, &name, path, scratch_pool);
+ SVN_ERR(svn_fs_closest_copy(©_root, ©_path, root, parent_path,
+ scratch_pool));
+
+ /* Copied in ROOT? */
+ if ( copy_root
+ && ( svn_fs_revision_root_revision(copy_root)
+ == svn_fs_revision_root_revision(root)))
+ {
+ svn_revnum_t copyfrom_rev;
+ const char *copyfrom_path;
+ const char *rel_path;
+ SVN_ERR(svn_fs_copied_from(©from_rev, ©from_path,
+ copy_root, copy_path, scratch_pool));
+
+ SVN_ERR(svn_fs_revision_root(node_root, svn_fs_root_fs(root),
+ copyfrom_rev, result_pool));
+ rel_path = svn_fspath__skip_ancestor(copy_path, path);
+ *node_path = svn_fspath__join(copyfrom_path, rel_path, result_pool);
+ }
+ else
+ {
+ svn_revnum_t revision;
+ svn_revnum_t previous_rev;
+
+ /* Determine the latest revision before ROOT. */
+ revision = svn_fs_revision_root_revision(root);
+ if (SVN_IS_VALID_REVNUM(revision))
+ previous_rev = revision - 1;
+ else
+ previous_rev = svn_fs_txn_root_base_revision(root);
+
+ SVN_ERR(svn_fs_revision_root(node_root, svn_fs_root_fs(root),
+ previous_rev, result_pool));
+ *node_path = apr_pstrdup(result_pool, path);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_fs_get_uuid(svn_fs_t *fs, const char **uuid, apr_pool_t *pool)
{
/* If you change this, consider changing svn_fs__identifier(). */
@@ -1860,15 +2035,6 @@ svn_fs_history_prev2(svn_fs_history_t **
}
svn_error_t *
-svn_fs_history_prev(svn_fs_history_t **prev_history_p,
- svn_fs_history_t *history, svn_boolean_t cross_copies,
- apr_pool_t *pool)
-{
- return svn_error_trace(history->vtable->prev(prev_history_p, history,
- cross_copies, pool, pool));
-}
-
-svn_error_t *
svn_fs_history_location(const char **path, svn_revnum_t *revision,
svn_fs_history_t *history, apr_pool_t *pool)
{
@@ -1967,6 +2133,28 @@ svn_fs_path_change2_create(const svn_fs_
return svn_fs__path_change_create_internal(node_rev_id, change_kind, pool);
}
+svn_fs_path_change3_t *
+svn_fs_path_change3_create(svn_fs_path_change_kind_t change_kind,
+ apr_pool_t *result_pool)
+{
+ return svn_fs__path_change_create_internal2(change_kind, result_pool);
+}
+
+svn_fs_path_change3_t *
+svn_fs_path_change3_dup(svn_fs_path_change3_t *change,
+ apr_pool_t *result_pool)
+{
+ svn_fs_path_change3_t *copy = apr_pmemdup(result_pool, change,
+ sizeof(*copy));
+
+ copy->path.data = apr_pstrmemdup(result_pool, copy->path.data,
+ copy->path.len);
+ if (copy->copyfrom_path)
+ copy->copyfrom_path = apr_pstrdup(result_pool, change->copyfrom_path);
+
+ return copy;
+}
+
/* Return the library version number. */
const svn_version_t *
svn_fs_version(void)
Modified: subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs/fs-loader.h Fri Apr 29 18:38:53 2016
@@ -79,11 +79,11 @@ typedef struct fs_library_vtable_t
parameter for allocating fs-global objects such as an env cache. */
svn_error_t *(*create)(svn_fs_t *fs, const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool);
svn_error_t *(*open_fs)(svn_fs_t *fs, const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool);
/* open_for_recovery() is like open(), but used to fill in an fs pointer
that will be passed to recover(). We assume that the open() method
@@ -196,11 +196,17 @@ typedef struct fs_vtable_t
{
svn_error_t *(*youngest_rev)(svn_revnum_t *youngest_p, svn_fs_t *fs,
apr_pool_t *pool);
+ svn_error_t *(*refresh_revprops)(svn_fs_t *fs, apr_pool_t *scratch_pool);
svn_error_t *(*revision_prop)(svn_string_t **value_p, svn_fs_t *fs,
svn_revnum_t rev, const char *propname,
- apr_pool_t *pool);
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *(*revision_proplist)(apr_hash_t **table_p, svn_fs_t *fs,
- svn_revnum_t rev, apr_pool_t *pool);
+ svn_revnum_t rev,
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *(*change_rev_prop)(svn_fs_t *fs, svn_revnum_t rev,
const char *name,
const svn_string_t *const *old_value_p,
@@ -295,6 +301,10 @@ typedef struct root_vtable_t
svn_error_t *(*paths_changed)(apr_hash_t **changed_paths_p,
svn_fs_root_t *root,
apr_pool_t *pool);
+ svn_error_t *(*report_changes)(svn_fs_path_change_iterator_t **iterator,
+ svn_fs_root_t *root,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* Generic node operations */
svn_error_t *(*check_path)(svn_node_kind_t *kind_p, svn_fs_root_t *root,
@@ -420,6 +430,13 @@ typedef struct root_vtable_t
} root_vtable_t;
+typedef struct changes_iterator_vtable_t
+{
+ svn_error_t *(*get)(svn_fs_path_change3_t **change,
+ svn_fs_path_change_iterator_t *iterator);
+} changes_iterator_vtable_t;
+
+
typedef struct history_vtable_t
{
svn_error_t *(*prev)(svn_fs_history_t **prev_history_p,
@@ -468,7 +485,7 @@ struct svn_fs_t
svn_fs_access_t *access_ctx;
/* FSAP-specific vtable and private data */
- fs_vtable_t *vtable;
+ const fs_vtable_t *vtable;
void *fsap_data;
/* UUID, stored by open(), create(), and set_uuid(). */
@@ -490,7 +507,7 @@ struct svn_fs_txn_t
const char *id;
/* FSAP-specific vtable and private data */
- txn_vtable_t *vtable;
+ const txn_vtable_t *vtable;
void *fsap_data;
};
@@ -518,15 +535,21 @@ struct svn_fs_root_t
svn_revnum_t rev;
/* FSAP-specific vtable and private data */
- root_vtable_t *vtable;
+ const root_vtable_t *vtable;
void *fsap_data;
};
+struct svn_fs_path_change_iterator_t
+{
+ /* FSAP-specific vtable and private data */
+ const changes_iterator_vtable_t *vtable;
+ void *fsap_data;
+};
struct svn_fs_history_t
{
/* FSAP-specific vtable and private data */
- history_vtable_t *vtable;
+ const history_vtable_t *vtable;
void *fsap_data;
};
@@ -534,7 +557,7 @@ struct svn_fs_history_t
struct svn_fs_id_t
{
/* FSAP-specific vtable and private data */
- id_vtable_t *vtable;
+ const id_vtable_t *vtable;
void *fsap_data;
};
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/dag.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/dag.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/dag.c Fri Apr 29 18:38:53 2016
@@ -1657,8 +1657,14 @@ svn_fs_base__things_different(svn_boolea
/* Compare contents keys and their (optional) uniquifiers. */
if (contents_changed != NULL)
- *contents_changed = (! svn_fs_base__same_keys(noderev1->data_key,
- noderev2->data_key));
+ *contents_changed =
+ (! (svn_fs_base__same_keys(noderev1->data_key,
+ noderev2->data_key)
+ /* Technically, these uniquifiers aren't used and "keys",
+ but keys are base-36 stringified numbers, so we'll take
+ this liberty. */
+ && (svn_fs_base__same_keys(noderev1->data_key_uniquifier,
+ noderev2->data_key_uniquifier))));
return SVN_NO_ERROR;
}
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/fs.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/fs.c Fri Apr 29 18:38:53 2016
@@ -471,6 +471,13 @@ bdb_write_config(svn_fs_t *fs)
}
static svn_error_t *
+base_bdb_refresh_revision(svn_fs_t *fs,
+ apr_pool_t *scratch_pool)
+{
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
base_bdb_info_format(int *fs_format,
svn_version_t **supports_version,
svn_fs_t *fs,
@@ -545,6 +552,7 @@ base_bdb_freeze(svn_fs_t *fs,
static fs_vtable_t fs_vtable = {
svn_fs_base__youngest_rev,
+ base_bdb_refresh_revision,
svn_fs_base__revision_prop,
svn_fs_base__revision_proplist,
svn_fs_base__change_rev_prop,
@@ -572,13 +580,12 @@ static fs_vtable_t fs_vtable = {
#define FORMAT_FILE "format"
/* Depending on CREATE, create or open the environment and databases
- for filesystem FS in PATH. Use POOL for temporary allocations. */
+ for filesystem FS in PATH. */
static svn_error_t *
open_databases(svn_fs_t *fs,
svn_boolean_t create,
int format,
- const char *path,
- apr_pool_t *pool)
+ const char *path)
{
base_fs_data_t *bfd;
@@ -732,7 +739,7 @@ static svn_error_t *
base_create(svn_fs_t *fs,
const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool)
{
int format = SVN_FS_BASE__FORMAT_NUMBER;
@@ -743,7 +750,7 @@ base_create(svn_fs_t *fs,
{
svn_version_t *compatible_version;
SVN_ERR(svn_fs__compatible_version(&compatible_version, fs->config,
- pool));
+ scratch_pool));
/* select format number */
switch(compatible_version->minor)
@@ -765,7 +772,7 @@ base_create(svn_fs_t *fs,
}
/* Create the environment and databases. */
- svn_err = open_databases(fs, TRUE, format, path, pool);
+ svn_err = open_databases(fs, TRUE, format, path);
if (svn_err) goto error;
/* Initialize the DAG subsystem. */
@@ -773,13 +780,14 @@ base_create(svn_fs_t *fs,
if (svn_err) goto error;
/* This filesystem is ready. Stamp it with a format number. */
- svn_err = svn_io_write_version_file(
- svn_dirent_join(fs->path, FORMAT_FILE, pool), format, pool);
+ svn_err = svn_io_write_version_file(svn_dirent_join(fs->path, FORMAT_FILE,
+ scratch_pool),
+ format, scratch_pool);
if (svn_err) goto error;
((base_fs_data_t *) fs->fsap_data)->format = format;
- SVN_ERR(populate_opened_fs(fs, pool));
+ SVN_ERR(populate_opened_fs(fs, scratch_pool));
return SVN_NO_ERROR;
error:
@@ -826,7 +834,7 @@ static svn_error_t *
base_open(svn_fs_t *fs,
const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool)
{
int format;
@@ -835,8 +843,9 @@ base_open(svn_fs_t *fs,
/* Read the FS format number. */
svn_err = svn_io_read_version_file(&format,
- svn_dirent_join(path, FORMAT_FILE, pool),
- pool);
+ svn_dirent_join(path, FORMAT_FILE,
+ scratch_pool),
+ scratch_pool);
if (svn_err && APR_STATUS_IS_ENOENT(svn_err->apr_err))
{
/* Pre-1.2 filesystems did not have a format file (you could say
@@ -852,7 +861,7 @@ base_open(svn_fs_t *fs,
goto error;
/* Create the environment and databases. */
- svn_err = open_databases(fs, FALSE, format, path, pool);
+ svn_err = open_databases(fs, FALSE, format, path);
if (svn_err) goto error;
((base_fs_data_t *) fs->fsap_data)->format = format;
@@ -862,12 +871,12 @@ base_open(svn_fs_t *fs,
if (write_format_file)
{
svn_err = svn_io_write_version_file(svn_dirent_join(path, FORMAT_FILE,
- pool),
- format, pool);
+ scratch_pool),
+ format, scratch_pool);
if (svn_err) goto error;
}
- SVN_ERR(populate_opened_fs(fs, pool));
+ SVN_ERR(populate_opened_fs(fs, scratch_pool));
return SVN_NO_ERROR;
error:
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/fs.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/fs.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/fs.h Fri Apr 29 18:38:53 2016
@@ -195,11 +195,7 @@ typedef struct node_revision_t
only because one or both of us decided to pick up a shared
representation after-the-fact." May be NULL (if this node
revision isn't using a shared rep, or isn't the original
- "assignee" of a shared rep).
-
- This is no longer used by the 1.9 code but we have to keep
- reading and writing it to remain compatible with 1.8, and
- earlier, that require it. */
+ "assignee" of a shared rep). */
const char *data_key_uniquifier;
/* representation key for this node's text-data-in-progess (files
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.c Fri Apr 29 18:38:53 2016
@@ -194,7 +194,9 @@ svn_error_t *
svn_fs_base__revision_proplist(apr_hash_t **table_p,
svn_fs_t *fs,
svn_revnum_t rev,
- apr_pool_t *pool)
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
struct revision_proplist_args args;
apr_hash_t *table;
@@ -204,9 +206,9 @@ svn_fs_base__revision_proplist(apr_hash_
args.table_p = &table;
args.rev = rev;
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args,
- FALSE, pool));
+ FALSE, result_pool));
- *table_p = table ? table : apr_hash_make(pool);
+ *table_p = table ? table : apr_hash_make(result_pool);
return SVN_NO_ERROR;
}
@@ -216,7 +218,9 @@ svn_fs_base__revision_prop(svn_string_t
svn_fs_t *fs,
svn_revnum_t rev,
const char *propname,
- apr_pool_t *pool)
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
struct revision_proplist_args args;
apr_hash_t *table;
@@ -227,7 +231,7 @@ svn_fs_base__revision_prop(svn_string_t
args.table_p = &table;
args.rev = rev;
SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_revision_proplist, &args,
- FALSE, pool));
+ FALSE, result_pool));
/* And then the prop from that list (if there was a list). */
*value_p = svn_hash_gets(table, propname);
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/revs-txns.h Fri Apr 29 18:38:53 2016
@@ -172,12 +172,16 @@ svn_error_t *svn_fs_base__youngest_rev(s
svn_error_t *svn_fs_base__revision_prop(svn_string_t **value_p, svn_fs_t *fs,
svn_revnum_t rev,
const char *propname,
- apr_pool_t *pool);
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *svn_fs_base__revision_proplist(apr_hash_t **table_p,
svn_fs_t *fs,
svn_revnum_t rev,
- apr_pool_t *pool);
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
svn_error_t *svn_fs_base__change_rev_prop(svn_fs_t *fs, svn_revnum_t rev,
const char *name,
Modified: subversion/branches/authzperf/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_base/tree.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_base/tree.c Fri Apr 29 18:38:53 2016
@@ -68,6 +68,7 @@
#include "private/svn_fspath.h"
#include "private/svn_fs_util.h"
#include "private/svn_mergeinfo_private.h"
+#include "private/svn_sorts_private.h"
/* ### I believe this constant will become internal to reps-strings.c.
@@ -2580,8 +2581,7 @@ verify_locks(const char *txn_name,
apr_hash_this(hi, &key, NULL, NULL);
APR_ARRAY_PUSH(changed_paths, const char *) = key;
}
- qsort(changed_paths->elts, changed_paths->nelts,
- changed_paths->elt_size, svn_sort_compare_paths);
+ svn_sort__array(changed_paths, svn_sort_compare_paths);
/* Now, traverse the array of changed paths, verify locks. Note
that if we need to do a recursive verification a path, we'll skip
@@ -2661,7 +2661,7 @@ txn_body_commit(void *baton, trail_t *tr
svn_revnum_t youngest_rev;
const svn_fs_id_t *y_rev_root_id;
- dag_node_t *txn_base_root_node;
+ dag_node_t *txn_base_root_node, *txn_root_node;
/* Getting the youngest revision locks the revisions table until
this trail is done. */
@@ -2694,6 +2694,19 @@ txn_body_commit(void *baton, trail_t *tr
discovered locks. */
SVN_ERR(verify_locks(txn_name, trail, trail->pool));
+ /* Ensure every txn has a mutable root as then the new revision will
+ have a distinct root node-revision-id. This is necessary as
+ future transactions use the root node-revision-id as a proxy for
+ the transaction base revision. */
+ SVN_ERR(svn_fs_base__dag_txn_root(&txn_root_node, fs, txn_name,
+ trail, trail->pool));
+ if (!svn_fs_base__dag_check_mutable(txn_root_node, txn->id))
+ {
+ dag_node_t *clone;
+ SVN_ERR(svn_fs_base__dag_clone_root(&clone, fs, txn->id,
+ trail, trail->pool));
+ }
+
/* Else, commit the txn. */
return svn_fs_base__dag_commit_txn(&(args->new_rev), txn, trail,
trail->pool);
@@ -5493,6 +5506,7 @@ base_get_mergeinfo(svn_mergeinfo_catalog
static root_vtable_t root_vtable = {
base_paths_changed,
+ NULL,
base_check_path,
base_node_history,
base_node_id,
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/cached_data.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/cached_data.c Fri Apr 29 18:38:53 2016
@@ -425,14 +425,13 @@ get_node_revision_body(node_revision_t *
scratch_pool),
APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
scratch_pool);
- if (err)
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ svn_error_clear(err);
+ return svn_error_trace(err_dangling_id(fs, id));
+ }
+ else if (err)
{
- if (APR_STATUS_IS_ENOENT(err->apr_err))
- {
- svn_error_clear(err);
- return svn_error_trace(err_dangling_id(fs, id));
- }
-
return svn_error_trace(err);
}
@@ -747,15 +746,15 @@ typedef struct rep_state_t
int chunk_index; /* number of the window to read */
} rep_state_t;
-/* Simple wrapper around svn_fs_fs__get_file_offset to simplify callers. */
+/* Simple wrapper around svn_io_file_get_offset to simplify callers. */
static svn_error_t *
get_file_offset(apr_off_t *offset,
rep_state_t *rs,
apr_pool_t *pool)
{
- return svn_error_trace(svn_fs_fs__get_file_offset(offset,
- rs->sfile->rfile->file,
- pool));
+ return svn_error_trace(svn_io_file_get_offset(offset,
+ rs->sfile->rfile->file,
+ pool));
}
/* Simple wrapper around svn_io_file_aligned_seek to simplify callers. */
@@ -1802,10 +1801,10 @@ get_contents_from_windows(struct rep_rea
This is where we need the pseudo rep_state created
by build_rep_list(). */
apr_size_t offset = (apr_size_t)rs->current;
- if (copy_len + offset > rb->base_window->len)
- copy_len = offset < rb->base_window->len
- ? rb->base_window->len - offset
- : 0ul;
+ if (offset >= rb->base_window->len)
+ copy_len = 0ul;
+ else if (copy_len > rb->base_window->len - offset)
+ copy_len = rb->base_window->len - offset;
memcpy (cur, rb->base_window->data + offset, copy_len);
}
@@ -2043,7 +2042,7 @@ skip_contents(struct rep_read_baton *bat
else if (len > 0)
{
/* Simply drain LEN bytes from the window stream. */
- apr_pool_t *subpool = subpool = svn_pool_create(baton->pool);
+ apr_pool_t *subpool = svn_pool_create(baton->pool);
char *buffer = apr_palloc(subpool, SVN__STREAM_CHUNK_SIZE);
while (len > 0 && !err)
@@ -2422,12 +2421,12 @@ compare_dirent_name(const void *a, const
return strcmp(lhs->name, rhs);
}
-/* Into ENTRIES, read all directories entries from the key-value text in
+/* Into *ENTRIES_P, read all directories entries from the key-value text in
* STREAM. If INCREMENTAL is TRUE, read until the end of the STREAM and
* update the data. ID is provided for nicer error messages.
*/
static svn_error_t *
-read_dir_entries(apr_array_header_t *entries,
+read_dir_entries(apr_array_header_t **entries_p,
svn_stream_t *stream,
svn_boolean_t incremental,
const svn_fs_id_t *id,
@@ -2435,8 +2434,14 @@ read_dir_entries(apr_array_header_t *ent
apr_pool_t *scratch_pool)
{
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- apr_hash_t *hash = incremental ? svn_hash__make(scratch_pool) : NULL;
+ apr_hash_t *hash = NULL;
const char *terminator = SVN_HASH_TERMINATOR;
+ apr_array_header_t *entries = NULL;
+
+ if (incremental)
+ hash = svn_hash__make(scratch_pool);
+ else
+ entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
/* Read until the terminator (non-incremental) or the end of STREAM
(incremental mode). In the latter mode, we use a temporary HASH
@@ -2448,8 +2453,11 @@ read_dir_entries(apr_array_header_t *ent
char *str;
svn_pool_clear(iterpool);
- SVN_ERR(svn_hash__read_entry(&entry, stream, terminator,
- incremental, iterpool));
+ SVN_ERR_W(svn_hash__read_entry(&entry, stream, terminator,
+ incremental, iterpool),
+ apr_psprintf(iterpool,
+ _("Directory representation corrupt in '%s'"),
+ svn_fs_fs__id_unparse(id, scratch_pool)->data));
/* End of directory? */
if (entry.key == NULL)
@@ -2517,6 +2525,9 @@ read_dir_entries(apr_array_header_t *ent
if (incremental)
{
apr_hash_index_t *hi;
+
+ entries = apr_array_make(result_pool, apr_hash_count(hash),
+ sizeof(svn_fs_dirent_t *));
for (hi = apr_hash_first(iterpool, hash); hi; hi = apr_hash_next(hi))
APR_ARRAY_PUSH(entries, svn_fs_dirent_t *) = apr_hash_this_val(hi);
}
@@ -2526,6 +2537,7 @@ read_dir_entries(apr_array_header_t *ent
svn_pool_destroy(iterpool);
+ *entries_p = entries;
return SVN_NO_ERROR;
}
@@ -2572,7 +2584,6 @@ get_dir_contents(svn_fs_fs__dir_data_t *
svn_stream_t *contents;
/* Initialize the result. */
- dir->entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
dir->txn_filesize = SVN_INVALID_FILESIZE;
/* Read dir contents - unless there is none in which case we are done. */
@@ -2595,7 +2606,7 @@ get_dir_contents(svn_fs_fs__dir_data_t *
SVN_ERR(svn_io_file_size_get(&dir->txn_filesize, file, scratch_pool));
contents = svn_stream_from_aprfile2(file, FALSE, scratch_pool);
- SVN_ERR(read_dir_entries(dir->entries, contents, TRUE, noderev->id,
+ SVN_ERR(read_dir_entries(&dir->entries, contents, TRUE, noderev->id,
result_pool, scratch_pool));
SVN_ERR(svn_stream_close(contents));
}
@@ -2615,9 +2626,13 @@ get_dir_contents(svn_fs_fs__dir_data_t *
/* de-serialize hash */
contents = svn_stream_from_stringbuf(text, scratch_pool);
- SVN_ERR(read_dir_entries(dir->entries, contents, FALSE, noderev->id,
+ SVN_ERR(read_dir_entries(&dir->entries, contents, FALSE, noderev->id,
result_pool, scratch_pool));
}
+ else
+ {
+ dir->entries = apr_array_make(result_pool, 0, sizeof(svn_fs_dirent_t *));
+ }
return SVN_NO_ERROR;
}
@@ -2636,27 +2651,27 @@ locate_dir_cache(svn_fs_t *fs,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
- if (svn_fs_fs__id_is_txn(noderev->id))
+ if (!noderev->data_rep)
+ {
+ /* no data rep -> empty directory.
+ A NULL key causes a cache miss. */
+ *key = NULL;
+ return ffd->dir_cache;
+ }
+
+ if (svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
{
/* data in txns requires the expensive fs_id-based addressing mode */
*key = svn_fs_fs__id_unparse(noderev->id, pool)->data;
+
return ffd->txn_dir_cache;
}
else
{
/* committed data can use simple rev,item pairs */
- if (noderev->data_rep)
- {
- pair_key->revision = noderev->data_rep->revision;
- pair_key->second = noderev->data_rep->item_index;
- *key = pair_key;
- }
- else
- {
- /* no data rep -> empty directory.
- A NULL key causes a cache miss. */
- *key = NULL;
- }
+ pair_key->revision = noderev->data_rep->revision;
+ pair_key->second = noderev->data_rep->item_index;
+ *key = pair_key;
return ffd->dir_cache;
}
@@ -2703,8 +2718,12 @@ svn_fs_fs__rep_contents_dir(apr_array_he
SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
*entries_p = dir->entries;
- /* Update the cache, if we are to use one. */
- if (cache)
+ /* Update the cache, if we are to use one.
+ *
+ * Don't even attempt to serialize very large directories; it would cause
+ * an unnecessary memory allocation peak. 150 bytes/entry is about right.
+ */
+ if (cache && svn_cache__is_cachable(cache, 150 * dir->entries->nelts))
SVN_ERR(svn_cache__set(cache, key, dir, scratch_pool));
return SVN_NO_ERROR;
@@ -2728,6 +2747,7 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
+ extract_dir_entry_baton_t baton;
svn_boolean_t found = FALSE;
/* find the cache we may use */
@@ -2737,8 +2757,6 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
scratch_pool);
if (cache)
{
- extract_dir_entry_baton_t baton;
-
svn_filesize_t filesize;
SVN_ERR(get_txn_dir_info(&filesize, fs, noderev, scratch_pool));
@@ -2755,7 +2773,7 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
}
/* fetch data from disk if we did not find it in the cache */
- if (! found)
+ if (! found || baton.out_of_date)
{
svn_fs_dirent_t *entry;
svn_fs_dirent_t *entry_copy = NULL;
@@ -2765,8 +2783,12 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
SVN_ERR(get_dir_contents(&dir, fs, noderev, scratch_pool,
scratch_pool));
- /* Update the cache, if we are to use one. */
- if (cache)
+ /* Update the cache, if we are to use one.
+ *
+ * Don't even attempt to serialize very large directories; it would
+ * cause an unnecessary memory allocation peak. 150 bytes / entry is
+ * about right. */
+ if (cache && svn_cache__is_cachable(cache, 150 * dir.entries->nelts))
SVN_ERR(svn_cache__set(cache, key, &dir, scratch_pool));
/* find desired entry and return a copy in POOL, if found */
@@ -3226,9 +3248,8 @@ read_rep_header(svn_fs_fs__rep_header_t
/* Fetch the representation data (header, txdelta / plain windows)
* addressed by ENTRY->ITEM in FS and cache it if caches are enabled.
- * Read the data from the already open FILE and the wrapping
- * STREAM object. If MAX_OFFSET is not -1, don't read windows that start
- * at or beyond that offset.
+ * Read the data from REV_FILE. If MAX_OFFSET is not -1, don't read
+ * windows that start at or beyond that offset.
* Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
@@ -3236,7 +3257,6 @@ block_read_contents(svn_fs_t *fs,
svn_fs_fs__revision_file_t *rev_file,
svn_fs_fs__p2l_entry_t* entry,
apr_off_t max_offset,
- apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
pair_cache_key_t header_key = { 0 };
@@ -3246,9 +3266,9 @@ block_read_contents(svn_fs_t *fs,
header_key.second = entry->item.number;
SVN_ERR(read_rep_header(&rep_header, fs, rev_file->stream, &header_key,
- result_pool, scratch_pool));
+ scratch_pool, scratch_pool));
SVN_ERR(block_read_windows(rep_header, fs, rev_file, entry, max_offset,
- result_pool, scratch_pool));
+ scratch_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -3305,8 +3325,8 @@ read_item(svn_stream_t **stream,
/* If not already cached or if MUST_READ is set, read the changed paths
* list addressed by ENTRY in FS and retúrn it in *CHANGES. Cache the
- * result if caching is enabled. Read the data from the already open
- * FILE and wrapping FILE_STREAM. Use POOL for allocations.
+ * result if caching is enabled. Read the data from REV_FILE. Allocate
+ * *CHANGES in RESUSLT_POOL and allocate temporaries in SCRATCH_POOL.
*/
static svn_error_t *
block_read_changes(apr_array_header_t **changes,
@@ -3347,10 +3367,10 @@ block_read_changes(apr_array_header_t **
return SVN_NO_ERROR;
}
-/* If not already cached or if MUST_READ is set, read the nod revision
+/* If not already cached or if MUST_READ is set, read the node revision
* addressed by ENTRY in FS and retúrn it in *NODEREV_P. Cache the
- * result if caching is enabled. Read the data from the already open
- * FILE and wrapping FILE_STREAM. Use SCRATCH_POOL for temporary allocations.
+ * result if caching is enabled. Read the data from REV_FILE. Allocate
+ * *NODEREV_P in RESUSLT_POOL and allocate temporaries in SCRATCH_POOL.
*/
static svn_error_t *
block_read_noderev(node_revision_t **noderev_p,
@@ -3500,7 +3520,7 @@ block_read(void **result,
is_wanted
? -1
: block_start + ffd->block_size,
- pool, iterpool));
+ iterpool));
break;
case SVN_FS_FS__ITEM_TYPE_NODEREV:
@@ -3528,7 +3548,7 @@ block_read(void **result,
/* if we crossed a block boundary, read the remainder of
* the last block as well */
offset = entry->offset + entry->size;
- if (offset > block_start + ffd->block_size)
+ if (offset - block_start > ffd->block_size)
++run_count;
}
}
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/caching.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/caching.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/caching.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/caching.c Fri Apr 29 18:38:53 2016
@@ -66,8 +66,9 @@ normalize_key_part(const char *original,
return normalized->data;
}
-/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS flags will be set according to
- FS->CONFIG. *CACHE_NAMESPACE receives the cache prefix to use.
+/* *CACHE_TXDELTAS, *CACHE_FULLTEXTS, *CACHE_NODEPROPS flags will be set
+ according to FS->CONFIG. *CACHE_NAMESPACE receives the cache prefix to
+ use.
Use FS->pool for allocating the memcache and CACHE_NAMESPACE, and POOL
for temporary allocations. */
@@ -75,6 +76,7 @@ static svn_error_t *
read_config(const char **cache_namespace,
svn_boolean_t *cache_txdeltas,
svn_boolean_t *cache_fulltexts,
+ svn_boolean_t *cache_nodeprops,
svn_fs_t *fs,
apr_pool_t *pool)
{
@@ -117,6 +119,14 @@ read_config(const char **cache_namespace
SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
TRUE);
+ /* by default, cache nodeprops: this will match pre-1.10
+ * behavior where node properties caching was controlled
+ * by SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS configuration option.
+ */
+ *cache_nodeprops
+ = svn_hash__get_bool(fs->config,
+ SVN_FS_CONFIG_FSFS_CACHE_NODEPROPS,
+ TRUE);
return SVN_NO_ERROR;
}
@@ -353,6 +363,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
svn_boolean_t no_handler = ffd->fail_stop;
svn_boolean_t cache_txdeltas;
svn_boolean_t cache_fulltexts;
+ svn_boolean_t cache_nodeprops;
const char *cache_namespace;
svn_boolean_t has_namespace;
@@ -360,6 +371,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
SVN_ERR(read_config(&cache_namespace,
&cache_txdeltas,
&cache_fulltexts,
+ &cache_nodeprops,
fs,
pool));
@@ -438,7 +450,7 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
svn_fs_fs__deserialize_dir_entries,
sizeof(pair_cache_key_t),
apr_pstrcat(pool, prefix, "DIR", SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
has_namespace,
fs,
no_handler,
@@ -506,6 +518,21 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
no_handler,
fs->pool, pool));
+ /* if enabled, cache revprops */
+ SVN_ERR(create_cache(&(ffd->revprop_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use inprocess cache */
+ svn_fs_fs__serialize_revprops,
+ svn_fs_fs__deserialize_revprops,
+ sizeof(pair_cache_key_t),
+ apr_pstrcat(pool, prefix, "REVPROP", SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ TRUE, /* contents is short-lived */
+ fs,
+ no_handler,
+ fs->pool, pool));
+
/* if enabled, cache fulltext and other derived information */
if (cache_fulltexts)
{
@@ -523,21 +550,6 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
no_handler,
fs->pool, pool));
- SVN_ERR(create_cache(&(ffd->properties_cache),
- NULL,
- membuffer,
- 0, 0, /* Do not use the inprocess cache */
- svn_fs_fs__serialize_properties,
- svn_fs_fs__deserialize_properties,
- sizeof(pair_cache_key_t),
- apr_pstrcat(pool, prefix, "PROP",
- SVN_VA_NULL),
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
- has_namespace,
- fs,
- no_handler,
- fs->pool, pool));
-
SVN_ERR(create_cache(&(ffd->mergeinfo_cache),
NULL,
membuffer,
@@ -571,11 +583,33 @@ svn_fs_fs__initialize_caches(svn_fs_t *f
else
{
ffd->fulltext_cache = NULL;
- ffd->properties_cache = NULL;
ffd->mergeinfo_cache = NULL;
ffd->mergeinfo_existence_cache = NULL;
}
+ /* if enabled, cache node properties */
+ if (cache_nodeprops)
+ {
+ SVN_ERR(create_cache(&(ffd->properties_cache),
+ NULL,
+ membuffer,
+ 0, 0, /* Do not use the inprocess cache */
+ svn_fs_fs__serialize_properties,
+ svn_fs_fs__deserialize_properties,
+ sizeof(pair_cache_key_t),
+ apr_pstrcat(pool, prefix, "PROP",
+ SVN_VA_NULL),
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+ has_namespace,
+ fs,
+ no_handler,
+ fs->pool, pool));
+ }
+ else
+ {
+ ffd->properties_cache = NULL;
+ }
+
/* if enabled, cache text deltas and their combinations */
if (cache_txdeltas)
{
@@ -801,18 +835,7 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
-
- /* Transaction content needs to be carefully prefixed to virtually
- eliminate any chance for conflicts. The (repo, txn_id) pair
- should be unique but if a transaction fails, it might be possible
- to start a new transaction later that receives the same id.
- Therefore, throw in a uuid as well - just to be sure. */
- const char *prefix = apr_pstrcat(pool,
- "fsfs:", fs->uuid,
- "/", fs->path,
- ":", txn_id,
- ":", svn_uuid_generate(pool), ":",
- SVN_VA_NULL);
+ const char *prefix;
/* We don't support caching for concurrent transactions in the SAME
* FSFS session. Maybe, you forgot to clean POOL. */
@@ -824,17 +847,39 @@ svn_fs_fs__initialize_txn_caches(svn_fs_
return SVN_NO_ERROR;
}
+ /* Transaction content needs to be carefully prefixed to virtually
+ eliminate any chance for conflicts. The (repo, txn_id) pair
+ should be unique but if the filesystem format doesn't store the
+ global transaction ID via the txn-current file, and a transaction
+ fails, it might be possible to start a new transaction later that
+ receives the same id. For such older formats, throw in an uuid as
+ well -- just to be sure. */
+ if (ffd->format >= SVN_FS_FS__MIN_TXN_CURRENT_FORMAT)
+ prefix = apr_pstrcat(pool,
+ "fsfs:", fs->uuid,
+ "/", fs->path,
+ ":", txn_id,
+ ":", "TXNDIR",
+ SVN_VA_NULL);
+ else
+ prefix = apr_pstrcat(pool,
+ "fsfs:", fs->uuid,
+ "/", fs->path,
+ ":", txn_id,
+ ":", svn_uuid_generate(pool),
+ ":", "TXNDIR",
+ SVN_VA_NULL);
+
/* create a txn-local directory cache */
SVN_ERR(create_cache(&ffd->txn_dir_cache,
NULL,
svn_cache__get_global_membuffer_cache(),
1024, 8,
- svn_fs_fs__serialize_dir_entries,
+ svn_fs_fs__serialize_txndir_entries,
svn_fs_fs__deserialize_dir_entries,
APR_HASH_KEY_STRING,
- apr_pstrcat(pool, prefix, "TXNDIR",
- SVN_VA_NULL),
- 0,
+ prefix,
+ SVN_CACHE__MEMBUFFER_HIGH_PRIORITY,
TRUE, /* The TXN-ID is our namespace. */
fs,
TRUE,
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/dag.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/dag.c Fri Apr 29 18:38:53 2016
@@ -753,8 +753,7 @@ svn_fs_fs__dag_clone_child(dag_node_t **
noderev->copyfrom_rev = SVN_INVALID_REVNUM;
noderev->predecessor_id = svn_fs_fs__id_copy(cur_entry->id, pool);
- if (noderev->predecessor_count != -1)
- noderev->predecessor_count++;
+ noderev->predecessor_count++;
noderev->created_path = svn_fspath__join(parent_path, name, pool);
SVN_ERR(svn_fs_fs__create_successor(&new_node_id, fs, cur_entry->id,
@@ -1267,8 +1266,7 @@ svn_fs_fs__dag_copy(dag_node_t *to_node,
/* Create a successor with its predecessor pointing at the copy
source. */
to_noderev->predecessor_id = svn_fs_fs__id_copy(src_id, pool);
- if (to_noderev->predecessor_count != -1)
- to_noderev->predecessor_count++;
+ to_noderev->predecessor_count++;
to_noderev->created_path =
svn_fspath__join(svn_fs_fs__dag_get_created_path(to_node), entry,
pool);
@@ -1305,34 +1303,58 @@ svn_fs_fs__dag_things_different(svn_bool
apr_pool_t *pool)
{
node_revision_t *noderev1, *noderev2;
- svn_fs_t *fs;
- svn_boolean_t same;
/* If we have no place to store our results, don't bother doing
anything. */
if (! props_changed && ! contents_changed)
return SVN_NO_ERROR;
- fs = svn_fs_fs__dag_get_fs(node1);
-
/* The node revision skels for these two nodes. */
SVN_ERR(get_node_revision(&noderev1, node1));
SVN_ERR(get_node_revision(&noderev2, node2));
- /* Compare property keys. */
- if (props_changed != NULL)
+ if (strict)
{
- SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, noderev1, noderev2,
- strict, pool));
- *props_changed = !same;
- }
+ /* In strict mode, compare text and property representations in the
+ svn_fs_contents_different() / svn_fs_props_different() manner.
- /* Compare contents keys. */
- if (contents_changed != NULL)
+ See the "No-op changes no longer dumped by 'svnadmin dump' in 1.9"
+ discussion (http://svn.haxx.se/dev/archive-2015-09/0269.shtml) and
+ issue #4598 (https://issues.apache.org/jira/browse/SVN-4598). */
+ svn_fs_t *fs = svn_fs_fs__dag_get_fs(node1);
+ svn_boolean_t same;
+
+ /* Compare property keys. */
+ if (props_changed != NULL)
+ {
+ SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, noderev1,
+ noderev2, pool));
+ *props_changed = !same;
+ }
+
+ /* Compare contents keys. */
+ if (contents_changed != NULL)
+ {
+ SVN_ERR(svn_fs_fs__file_text_rep_equal(&same, fs, noderev1,
+ noderev2, pool));
+ *contents_changed = !same;
+ }
+ }
+ else
{
- SVN_ERR(svn_fs_fs__file_text_rep_equal(&same, fs, noderev1, noderev2,
- strict, pool));
- *contents_changed = !same;
+ /* Otherwise, compare representation keys -- as in Subversion 1.8. */
+
+ /* Compare property keys. */
+ if (props_changed != NULL)
+ *props_changed =
+ !svn_fs_fs__noderev_same_rep_key(noderev1->prop_rep,
+ noderev2->prop_rep);
+
+ /* Compare contents keys. */
+ if (contents_changed != NULL)
+ *contents_changed =
+ !svn_fs_fs__noderev_same_rep_key(noderev1->data_rep,
+ noderev2->data_rep);
}
return SVN_NO_ERROR;
@@ -1399,8 +1421,7 @@ svn_fs_fs__dag_update_ancestry(dag_node_
target_noderev->predecessor_id = source->id;
target_noderev->predecessor_count = source_noderev->predecessor_count;
- if (target_noderev->predecessor_count != -1)
- target_noderev->predecessor_count++;
+ target_noderev->predecessor_count++;
return svn_fs_fs__put_node_revision(target->fs, target->id, target_noderev,
FALSE, pool);
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.c Fri Apr 29 18:38:53 2016
@@ -148,6 +148,15 @@ svn_fs_fs__initialize_shared_data(svn_fs
+static svn_error_t *
+fs_refresh_revprops(svn_fs_t *fs,
+ apr_pool_t *scratch_pool)
+{
+ svn_fs_fs__reset_revprop_cache(fs);
+
+ return SVN_NO_ERROR;
+}
+
/* This function is provided for Subversion 1.0.x compatibility. It
has no effect for fsfs backed Subversion filesystems. It conforms
to the fs_library_vtable_t.bdb_set_errcall() API. */
@@ -249,6 +258,7 @@ fs_set_uuid(svn_fs_t *fs,
/* The vtable associated with a specific open filesystem. */
static fs_vtable_t fs_vtable = {
svn_fs_fs__youngest_rev,
+ fs_refresh_revprops,
svn_fs_fs__revision_prop,
svn_fs_fs__get_revision_proplist,
svn_fs_fs__change_rev_prop,
@@ -281,6 +291,8 @@ initialize_fs_struct(svn_fs_t *fs)
{
fs_fs_data_t *ffd = apr_pcalloc(fs->pool, sizeof(*ffd));
ffd->use_log_addressing = FALSE;
+ ffd->revprop_prefix = 0;
+ ffd->flush_to_disk = TRUE;
fs->vtable = &fs_vtable;
fs->fsap_data = ffd;
@@ -304,18 +316,18 @@ static svn_error_t *
fs_create(svn_fs_t *fs,
const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool)
{
SVN_ERR(svn_fs__check_fs(fs, FALSE));
SVN_ERR(initialize_fs_struct(fs));
- SVN_ERR(svn_fs_fs__create(fs, path, pool));
+ SVN_ERR(svn_fs_fs__create(fs, path, scratch_pool));
- SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
+ SVN_ERR(svn_fs_fs__initialize_caches(fs, scratch_pool));
SVN_MUTEX__WITH_LOCK(common_pool_lock,
- fs_serialized_init(fs, common_pool, pool));
+ fs_serialized_init(fs, common_pool, scratch_pool));
return SVN_NO_ERROR;
}
@@ -333,10 +345,10 @@ static svn_error_t *
fs_open(svn_fs_t *fs,
const char *path,
svn_mutex__t *common_pool_lock,
- apr_pool_t *pool,
+ apr_pool_t *scratch_pool,
apr_pool_t *common_pool)
{
- apr_pool_t *subpool = svn_pool_create(pool);
+ apr_pool_t *subpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_fs__check_fs(fs, FALSE));
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/fs.h Fri Apr 29 18:38:53 2016
@@ -351,6 +351,15 @@ typedef struct fs_fs_data_t
rep key (revision/offset) to svn_stringbuf_t. */
svn_cache__t *fulltext_cache;
+ /* The current prefix to be used for revprop cache entries.
+ If this is 0, a new unique prefix must be chosen. */
+ apr_uint64_t revprop_prefix;
+
+ /* Revision property cache. Maps from (rev,prefix) to apr_hash_t.
+ Unparsed svn_string_t representations of the serialized hash
+ will be written to the cache but the getter returns apr_hash_t. */
+ svn_cache__t *revprop_cache;
+
/* Node properties cache. Maps from rep key to apr_hash_t. */
svn_cache__t *properties_cache;
@@ -467,6 +476,9 @@ typedef struct fs_fs_data_t
or dump / load cycles). */
const char *instance_id;
+ /* Ensure that all filesystem changes are written to disk. */
+ svn_boolean_t flush_to_disk;
+
/* Pointer to svn_fs_open. */
svn_error_t *(*svn_fs_open_)(svn_fs_t **, const char *, apr_hash_t *,
apr_pool_t *, apr_pool_t *);
@@ -476,10 +488,6 @@ typedef struct fs_fs_data_t
/*** Filesystem Transaction ***/
typedef struct transaction_t
{
- /* property list (const char * name, svn_string_t * value).
- may be NULL if there are no properties. */
- apr_hash_t *proplist;
-
/* node revision id of the root node. */
const svn_fs_id_t *root_id;
@@ -541,13 +549,7 @@ typedef struct representation_t
/* For rep-sharing, we need a way of uniquifying node-revs which share the
same representation (see svn_fs_fs__noderev_same_rep_key() ). So, we
store the original txn of the node rev (not the rep!), along with some
- intra-node uniqification content.
-
- This is no longer used by the 1.9 code but we have to keep
- reading and writing it for old formats to remain compatible with
- 1.8, and earlier, that require it. We also read/write it in
- format 7 even though it is not currently required by any code
- that handles that format. */
+ intra-node uniqification content. */
struct
{
/* unique context, i.e. txn ID, in which the noderev (!) got created */
@@ -583,8 +585,8 @@ typedef struct node_revision_t
svn_revnum_t copyroot_rev;
const char *copyroot_path;
- /* number of predecessors this node revision has (recursively), or
- -1 if not known (for backward compatibility). */
+ /* Number of predecessors this node revision has (recursively).
+ A difference from the BDB backend is that it cannot be -1. */
int predecessor_count;
/* representation key for this node's properties. may be NULL if
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.c Fri Apr 29 18:38:53 2016
@@ -492,6 +492,7 @@ read_format(int *pformat,
svn_error_clear(err);
*pformat = 1;
*max_files_per_dir = 0;
+ *use_log_addressing = FALSE;
return SVN_NO_ERROR;
}
@@ -623,7 +624,8 @@ svn_fs_fs__write_format(svn_fs_t *fs,
else
{
SVN_ERR(svn_io_write_atomic2(path, sb->data, sb->len,
- NULL /* copy_perms_path */, TRUE, pool));
+ NULL /* copy_perms_path */,
+ ffd->flush_to_disk, pool));
}
/* And set the perms to make it read only */
@@ -754,8 +756,8 @@ read_config(fs_fs_data_t *ffd,
CONFIG_SECTION_PACKED_REVPROPS,
CONFIG_OPTION_REVPROP_PACK_SIZE,
ffd->compress_packed_revprops
- ? 0x10
- : 0x4));
+ ? 0x40
+ : 0x10));
ffd->revprop_pack_size *= 1024;
}
@@ -962,9 +964,9 @@ write_config(svn_fs_t *fs,
"### latency and CPU usage reading and changing individual revprops." NL
"### Values smaller than 4 kByte will not improve latency any further and " NL
"### quickly render revprop packing ineffective." NL
-"### revprop-pack-size is 4 kBytes by default for non-compressed revprop" NL
-"### pack files and 16 kBytes when compression has been enabled." NL
-"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 4" NL
+"### revprop-pack-size is 16 kBytes by default for non-compressed revprop" NL
+"### pack files and 64 kBytes when compression has been enabled." NL
+"# " CONFIG_OPTION_REVPROP_PACK_SIZE " = 16" NL
"###" NL
"### To save disk space, packed revprop files may be compressed. Standard" NL
"### revprops tend to allow for very effective compression. Reading and" NL
@@ -1031,13 +1033,12 @@ read_global_config(svn_fs_t *fs)
{
fs_fs_data_t *ffd = fs->fsap_data;
- /* Providing a config hash is optional. */
- if (fs->config)
- ffd->use_block_read = svn_hash__get_bool(fs->config,
- SVN_FS_CONFIG_FSFS_BLOCK_READ,
- FALSE);
- else
- ffd->use_block_read = FALSE;
+ ffd->use_block_read = svn_hash__get_bool(fs->config,
+ SVN_FS_CONFIG_FSFS_BLOCK_READ,
+ FALSE);
+ ffd->flush_to_disk = !svn_hash__get_bool(fs->config,
+ SVN_FS_CONFIG_NO_FLUSH_TO_DISK,
+ FALSE);
/* Ignore the user-specified larger block size if we don't use block-read.
Defaulting to 4k gives us the same access granularity in format 7 as in
@@ -1387,12 +1388,30 @@ svn_fs_fs__file_length(svn_filesize_t *l
return SVN_NO_ERROR;
}
+svn_boolean_t
+svn_fs_fs__noderev_same_rep_key(representation_t *a,
+ representation_t *b)
+{
+ if (a == b)
+ return TRUE;
+
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ if (a->item_index != b->item_index)
+ return FALSE;
+
+ if (a->revision != b->revision)
+ return FALSE;
+
+ return memcmp(&a->uniquifier, &b->uniquifier, sizeof(a->uniquifier)) == 0;
+}
+
svn_error_t *
svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal,
svn_fs_t *fs,
node_revision_t *a,
node_revision_t *b,
- svn_boolean_t strict,
apr_pool_t *scratch_pool)
{
svn_stream_t *contents_a, *contents_b;
@@ -1437,19 +1456,6 @@ svn_fs_fs__file_text_rep_equal(svn_boole
return SVN_NO_ERROR;
}
- /* Old repositories may not have the SHA1 checksum handy.
- This check becomes expensive. Skip it unless explicitly required.
-
- We already have seen that the ID is different, so produce a likely
- false negative as allowed by the API description - even though the
- MD5 matched, there is an extremely slim chance that the SHA1 wouldn't.
- */
- if (!strict)
- {
- *equal = FALSE;
- return SVN_NO_ERROR;
- }
-
SVN_ERR(svn_fs_fs__get_contents(&contents_a, fs, rep_a, TRUE,
scratch_pool));
SVN_ERR(svn_fs_fs__get_contents(&contents_b, fs, rep_b, TRUE,
@@ -1465,7 +1471,6 @@ svn_fs_fs__prop_rep_equal(svn_boolean_t
svn_fs_t *fs,
node_revision_t *a,
node_revision_t *b,
- svn_boolean_t strict,
apr_pool_t *scratch_pool)
{
representation_t *rep_a = a->prop_rep;
@@ -1512,14 +1517,6 @@ svn_fs_fs__prop_rep_equal(svn_boolean_t
return SVN_NO_ERROR;
}
- /* Skip the expensive bits unless we are in strict mode.
- Simply assume that there is a difference. */
- if (!strict)
- {
- *equal = FALSE;
- return SVN_NO_ERROR;
- }
-
/* At least one of the reps has been modified in a txn.
Fetch and compare them. */
SVN_ERR(svn_fs_fs__get_proplist(&proplist_a, fs, a, scratch_pool));
@@ -1872,7 +1869,7 @@ svn_fs_fs__set_uuid(svn_fs_t *fs,
file does not exist during repository creation. */
SVN_ERR(svn_io_write_atomic2(uuid_path, contents->data, contents->len,
svn_fs_fs__path_current(fs, pool) /* perms */,
- TRUE, pool));
+ ffd->flush_to_disk, pool));
fs->uuid = apr_pstrdup(fs->pool, uuid);
@@ -2058,14 +2055,17 @@ svn_fs_fs__revision_prop(svn_string_t **
svn_fs_t *fs,
svn_revnum_t rev,
const char *propname,
- apr_pool_t *pool)
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
apr_hash_t *table;
SVN_ERR(svn_fs__check_fs(fs, TRUE));
- SVN_ERR(svn_fs_fs__get_revision_proplist(&table, fs, rev, pool));
+ SVN_ERR(svn_fs_fs__get_revision_proplist(&table, fs, rev, refresh,
+ scratch_pool, scratch_pool));
- *value_p = svn_hash_gets(table, propname);
+ *value_p = svn_string_dup(svn_hash_gets(table, propname), result_pool);
return SVN_NO_ERROR;
}
@@ -2090,7 +2090,10 @@ change_rev_prop_body(void *baton, apr_po
apr_hash_t *table;
const svn_string_t *present_value;
- SVN_ERR(svn_fs_fs__get_revision_proplist(&table, cb->fs, cb->rev, pool));
+ /* We always need to read the current revprops from disk.
+ * Hence, always "refresh" here. */
+ SVN_ERR(svn_fs_fs__get_revision_proplist(&table, cb->fs, cb->rev, TRUE,
+ pool, pool));
present_value = svn_hash_gets(table, cb->name);
if (cb->old_value_p)
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/fs_fs.h Fri Apr 29 18:38:53 2016
@@ -90,28 +90,29 @@ svn_error_t *svn_fs_fs__file_length(svn_
node_revision_t *noderev,
apr_pool_t *pool);
+/* Return TRUE if the representation keys in A and B both point to the
+ same representation, else return FALSE. */
+svn_boolean_t svn_fs_fs__noderev_same_rep_key(representation_t *a,
+ representation_t *b);
+
/* Set *EQUAL to TRUE if the text representations in A and B within FS
- have equal contents, else set it to FALSE. If STRICT is not set, allow
- for false negatives.
+ have equal contents, else set it to FALSE.
Use SCRATCH_POOL for temporary allocations. */
svn_error_t *
svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal,
svn_fs_t *fs,
node_revision_t *a,
node_revision_t *b,
- svn_boolean_t strict,
apr_pool_t *scratch_pool);
/* Set *EQUAL to TRUE if the property representations in A and B within FS
- have equal contents, else set it to FALSE. If STRICT is not set, allow
- for false negatives.
+ have equal contents, else set it to FALSE.
Use SCRATCH_POOL for temporary allocations. */
svn_error_t *
svn_fs_fs__prop_rep_equal(svn_boolean_t *equal,
svn_fs_t *fs,
node_revision_t *a,
node_revision_t *b,
- svn_boolean_t strict,
apr_pool_t *scratch_pool);
@@ -224,13 +225,16 @@ svn_fs_fs__with_all_locks(svn_fs_t *fs,
void *baton,
apr_pool_t *pool);
-/* Find the value of the property named PROPNAME in transaction TXN.
+/* Find the value of the property named PROPNAME in revision REV.
Return the contents in *VALUE_P. The contents will be allocated
- from POOL. */
+ from RESULT_POOL and SCRATCH_POOL is used for temporaries.
+ Invalidate any revprop cache is REFRESH is set. */
svn_error_t *svn_fs_fs__revision_prop(svn_string_t **value_p, svn_fs_t *fs,
svn_revnum_t rev,
const char *propname,
- apr_pool_t *pool);
+ svn_boolean_t refresh,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* Change, add, or delete a property on a revision REV in filesystem
FS. NAME gives the name of the property, and value, if non-NULL,
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/hotcopy.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/hotcopy.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/hotcopy.c Fri Apr 29 18:38:53 2016
@@ -795,7 +795,7 @@ struct hotcopy_body_baton {
* An incremental hotcopy copies only changed or new files to the destination,
* and removes files from the destination no longer present in the source.
* While the incremental hotcopy is running, readers should still be able
- * to access the destintation repository without error and should not see
+ * to access the destination repository without error and should not see
* revisions currently in progress of being copied. Readers are able to see
* new fully copied revisions even if the entire incremental hotcopy procedure
* has not yet completed.
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/id.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/id.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/id.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/id.c Fri Apr 29 18:38:53 2016
@@ -82,9 +82,11 @@ locale_independent_strtol(long *result_p
next = result * 10 + c;
- /* Overflow check. In case of an overflow, NEXT is 0..9.
- * In the non-overflow case, RESULT is either >= 10 or RESULT and NEXT
- * are both 0. */
+ /* Overflow check. In case of an overflow, NEXT is 0..9 and RESULT
+ * is much larger than 10. We will then return FALSE.
+ *
+ * In the non-overflow case, NEXT is >= 10 * RESULT but never smaller.
+ * We will continue the loop in that case. */
if (next < result)
return FALSE;
Modified: subversion/branches/authzperf/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_fs/index.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_fs_fs/index.c Fri Apr 29 18:38:53 2016
@@ -231,7 +231,7 @@ stream_error_create(svn_fs_fs__packed_nu
apr_off_t offset;
SVN_ERR(svn_io_file_name_get(&file_name, stream->file,
stream->pool));
- SVN_ERR(svn_fs_fs__get_file_offset(&offset, stream->file, stream->pool));
+ SVN_ERR(svn_io_file_get_offset(&offset, stream->file, stream->pool));
return svn_error_createf(err, NULL, message, file_name,
apr_psprintf(stream->pool,
@@ -1736,7 +1736,7 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
apr_uint64_t item_count;
apr_size_t first_page_index, last_page_index;
- if (revision >= header->first_revision + header->revision_count)
+ if (revision - header->first_revision >= header->revision_count)
{
/* need to read the next index. Clear up memory used for the
* previous one. Note that intermittent pack runs do not change
@@ -2422,6 +2422,13 @@ read_entry(svn_fs_fs__packed_number_stre
return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
_("Empty regions must have item number 0 and checksum 0"));
+ /* Corrupted SIZE values might cause arithmetic overflow.
+ * The same can happen if you copy a repository from a system with 63 bit
+ * file lengths to one with 31 bit file lengths. */
+ if ((apr_uint64_t)entry.offset + (apr_uint64_t)entry.size > off_t_max)
+ return svn_error_create(SVN_ERR_FS_INDEX_OVERFLOW , NULL,
+ _("P2L index entry size overflow."));
+
APR_ARRAY_PUSH(result, svn_fs_fs__p2l_entry_t) = entry;
*item_offset += entry.size;