diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-04-29 19:16:59 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-04-29 19:16:59 +0000 |
commit | c94cceea9c2262c5b2ad5f215bb9a8ae48b02764 (patch) | |
tree | dbb8174cbf6f1cc45b8de8031b18adb4030509a8 /subversion/libsvn_fs_fs | |
parent | dc5d469d6574e9fb03bdd793658bb371315b306a (diff) |
Notes
Diffstat (limited to 'subversion/libsvn_fs_fs')
-rw-r--r-- | subversion/libsvn_fs_fs/cached_data.c | 8 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/dag.c | 54 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/fs.h | 12 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/fs_fs.c | 86 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/fs_fs.h | 13 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/rep-cache-db.h | 2 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/transaction.c | 3 | ||||
-rw-r--r-- | subversion/libsvn_fs_fs/tree.c | 4 |
8 files changed, 98 insertions, 84 deletions
diff --git a/subversion/libsvn_fs_fs/cached_data.c b/subversion/libsvn_fs_fs/cached_data.c index 1618f07d40a5..948870e6be1a 100644 --- a/subversion/libsvn_fs_fs/cached_data.c +++ b/subversion/libsvn_fs_fs/cached_data.c @@ -2558,8 +2558,12 @@ svn_fs_fs__rep_contents_dir(apr_array_header_t **entries_p, SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_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 * (*entries_p)->nelts)) SVN_ERR(svn_cache__set(cache, key, *entries_p, scratch_pool)); return SVN_NO_ERROR; diff --git a/subversion/libsvn_fs_fs/dag.c b/subversion/libsvn_fs_fs/dag.c index 78d1b23e3583..d21c17c4b9aa 100644 --- a/subversion/libsvn_fs_fs/dag.c +++ b/subversion/libsvn_fs_fs/dag.c @@ -1307,34 +1307,58 @@ svn_fs_fs__dag_things_different(svn_boolean_t *props_changed, 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; diff --git a/subversion/libsvn_fs_fs/fs.h b/subversion/libsvn_fs_fs/fs.h index 221db1a17c12..c75eafbd5c09 100644 --- a/subversion/libsvn_fs_fs/fs.h +++ b/subversion/libsvn_fs_fs/fs.h @@ -478,10 +478,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; @@ -536,13 +532,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 */ diff --git a/subversion/libsvn_fs_fs/fs_fs.c b/subversion/libsvn_fs_fs/fs_fs.c index c2eaf5c04d48..1d32672b87f9 100644 --- a/subversion/libsvn_fs_fs/fs_fs.c +++ b/subversion/libsvn_fs_fs/fs_fs.c @@ -1414,19 +1414,37 @@ svn_fs_fs__file_length(svn_filesize_t *length, 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; representation_t *rep_a = a->data_rep; representation_t *rep_b = b->data_rep; - svn_boolean_t a_empty = !rep_a || rep_a->expanded_size == 0; - svn_boolean_t b_empty = !rep_b || rep_b->expanded_size == 0; + svn_boolean_t a_empty = !rep_a; + svn_boolean_t b_empty = !rep_b; /* This makes sure that neither rep will be NULL later on */ if (a_empty && b_empty) @@ -1435,28 +1453,6 @@ svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal, return SVN_NO_ERROR; } - if (a_empty != b_empty) - { - *equal = FALSE; - return SVN_NO_ERROR; - } - - /* File text representations always know their checksums - even in a txn. */ - if (memcmp(rep_a->md5_digest, rep_b->md5_digest, sizeof(rep_a->md5_digest))) - { - *equal = FALSE; - return SVN_NO_ERROR; - } - - /* Paranoia. Compare SHA1 checksums because that's the level of - confidence we require for e.g. the working copy. */ - if (rep_a->has_sha1 && rep_b->has_sha1) - { - *equal = memcmp(rep_a->sha1_digest, rep_b->sha1_digest, - sizeof(rep_a->sha1_digest)) == 0; - return SVN_NO_ERROR; - } - /* Same path in same rev or txn? */ if (svn_fs_fs__id_eq(a->id, b->id)) { @@ -1464,17 +1460,28 @@ svn_fs_fs__file_text_rep_equal(svn_boolean_t *equal, 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) + /* Beware of the combination NULL rep and possibly empty rep. + * Due to EXPANDED_SIZE not being reliable, we can't easily detect empty + * reps. So, we can only take further shortcuts if both reps are given. */ + if (!a_empty && !b_empty) { - *equal = FALSE; - return SVN_NO_ERROR; + /* File text representations always know their checksums - + * even in a txn. */ + if (memcmp(rep_a->md5_digest, rep_b->md5_digest, + sizeof(rep_a->md5_digest))) + { + *equal = FALSE; + return SVN_NO_ERROR; + } + + /* Paranoia. Compare SHA1 checksums because that's the level of + confidence we require for e.g. the working copy. */ + if (rep_a->has_sha1 && rep_b->has_sha1) + { + *equal = memcmp(rep_a->sha1_digest, rep_b->sha1_digest, + sizeof(rep_a->sha1_digest)) == 0; + return SVN_NO_ERROR; + } } SVN_ERR(svn_fs_fs__get_contents(&contents_a, fs, rep_a, TRUE, @@ -1492,7 +1499,6 @@ 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) { representation_t *rep_a = a->prop_rep; @@ -1526,14 +1532,6 @@ svn_fs_fs__prop_rep_equal(svn_boolean_t *equal, 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)); diff --git a/subversion/libsvn_fs_fs/fs_fs.h b/subversion/libsvn_fs_fs/fs_fs.h index 1be993a931bd..b6c94c7e7ff3 100644 --- a/subversion/libsvn_fs_fs/fs_fs.h +++ b/subversion/libsvn_fs_fs/fs_fs.h @@ -81,28 +81,29 @@ svn_error_t *svn_fs_fs__file_length(svn_filesize_t *length, 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); diff --git a/subversion/libsvn_fs_fs/rep-cache-db.h b/subversion/libsvn_fs_fs/rep-cache-db.h index 037585964994..56692c92e6d0 100644 --- a/subversion/libsvn_fs_fs/rep-cache-db.h +++ b/subversion/libsvn_fs_fs/rep-cache-db.h @@ -1,4 +1,4 @@ -/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.2/subversion/libsvn_fs_fs/token-map.h. +/* This file is automatically generated from rep-cache-db.sql and .dist_sandbox/subversion-1.9.4/subversion/libsvn_fs_fs/token-map.h. * Do not edit this file -- edit the source and rerun gen-make.py */ #define STMT_CREATE_SCHEMA 0 diff --git a/subversion/libsvn_fs_fs/transaction.c b/subversion/libsvn_fs_fs/transaction.c index c6b2d25c251b..3968c6fa5deb 100644 --- a/subversion/libsvn_fs_fs/transaction.c +++ b/subversion/libsvn_fs_fs/transaction.c @@ -1247,9 +1247,6 @@ svn_fs_fs__get_txn(transaction_t **txn_p, svn_fs_id_t *root_id; txn = apr_pcalloc(pool, sizeof(*txn)); - txn->proplist = apr_hash_make(pool); - - SVN_ERR(get_txn_proplist(txn->proplist, fs, txn_id, pool)); root_id = svn_fs_fs__id_txn_create_root(txn_id, pool); SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, root_id, pool, pool)); diff --git a/subversion/libsvn_fs_fs/tree.c b/subversion/libsvn_fs_fs/tree.c index 66de1f8ca313..0047bef251fc 100644 --- a/subversion/libsvn_fs_fs/tree.c +++ b/subversion/libsvn_fs_fs/tree.c @@ -1900,13 +1900,13 @@ merge(svn_stringbuf_t *conflict_p, /* Now compare the prop-keys of the skels. Note that just because the keys are different -doesn't- mean the proplists have different contents. */ - SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, src_nr, anc_nr, TRUE, pool)); + SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, src_nr, anc_nr, pool)); if (! same) return conflict_err(conflict_p, target_path); /* The directory entries got changed in the repository but the directory properties did not. */ - SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, tgt_nr, anc_nr, TRUE, pool)); + SVN_ERR(svn_fs_fs__prop_rep_equal(&same, fs, tgt_nr, anc_nr, pool)); if (! same) { /* There is an incoming prop change for this directory. |