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 2013/11/27 08:53:35 UTC
svn commit: r1545955 [7/15] - in /subversion/branches/fsfs-improvements: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/server-side/ contrib/server-side/svncutter/ notes/
subversion/bindings/javahl/native/ s...
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crashrpt.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crashrpt.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crashrpt.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crashrpt.c Wed Nov 27 07:53:29 2013
@@ -244,7 +244,7 @@ write_process_info(EXCEPTION_RECORD *exc
"Rsp=%016I64x Rbp=%016I64x Rsi=%016I64x Rdi=%016I64x\n",
context->Rsp, context->Rbp, context->Rsi, context->Rdi);
fprintf(log_file,
- "R8= %016I64x R9= %016I64x R10= %016I64x R11=%016I64x\n",
+ "R8= %016I64x R9= %016I64x R10=%016I64x R11=%016I64x\n",
context->R8, context->R9, context->R10, context->R11);
fprintf(log_file,
"R12=%016I64x R13=%016I64x R14=%016I64x R15=%016I64x\n",
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crypto.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crypto.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crypto.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_subr/win32_crypto.c Wed Nov 27 07:53:29 2013
@@ -42,6 +42,7 @@ typedef int win32_crypto__dummy;
#include "svn_user.h"
#include "svn_base64.h"
+#include "auth.h"
#include "private/svn_auth_private.h"
#include <wincrypt.h>
@@ -213,7 +214,7 @@ static const svn_auth_provider_t windows
/* Public API */
void
-svn_auth_get_windows_simple_provider(svn_auth_provider_object_t **provider,
+svn_auth__get_windows_simple_provider(svn_auth_provider_object_t **provider,
apr_pool_t *pool)
{
svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
@@ -331,7 +332,7 @@ static const svn_auth_provider_t windows
/* Public API */
void
-svn_auth_get_windows_ssl_client_cert_pw_provider
+svn_auth__get_windows_ssl_client_cert_pw_provider
(svn_auth_provider_object_t **provider,
apr_pool_t *pool)
{
@@ -482,7 +483,7 @@ static const svn_auth_provider_t windows
/* Public API */
void
-svn_auth_get_windows_ssl_server_trust_provider
+svn_auth__get_windows_ssl_server_trust_provider
(svn_auth_provider_object_t **provider, apr_pool_t *pool)
{
svn_auth_provider_object_t *po = apr_pcalloc(pool, sizeof(*po));
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/conflicts.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/conflicts.c Wed Nov 27 07:53:29 2013
@@ -2709,12 +2709,17 @@ resolve_prop_conflict_on_node(svn_boolea
* existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
*
* It is not an error if there is no tree conflict.
+ *
+ * If the conflict can't be resolved yet because another tree conflict is
+ * blocking a storage location, store the tree conflict in the RESOLVE_LATER
+ * hash.
*/
static svn_error_t *
resolve_tree_conflict_on_node(svn_boolean_t *did_resolve,
svn_wc__db_t *db,
const char *local_abspath,
svn_wc_conflict_choice_t conflict_choice,
+ apr_hash_t *resolve_later,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -2748,6 +2753,7 @@ resolve_tree_conflict_on_node(svn_boolea
if (operation == svn_wc_operation_update
|| operation == svn_wc_operation_switch)
{
+ svn_error_t *err;
if (reason == svn_wc_conflict_reason_deleted ||
reason == svn_wc_conflict_reason_replaced)
{
@@ -2766,10 +2772,26 @@ resolve_tree_conflict_on_node(svn_boolea
* this directory, and leave this directory deleted.
* The newly conflicted moved-away children will be updated
* if they are resolved with 'mine_conflict' as well. */
- SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(
+ err = svn_wc__db_resolve_delete_raise_moved_away(
db, local_abspath, notify_func, notify_baton,
- scratch_pool));
- *did_resolve = TRUE;
+ scratch_pool);
+
+ if (err)
+ {
+ const char *dup_abspath;
+ if (err && err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ dup_abspath = apr_pstrdup(apr_hash_pool_get(resolve_later),
+ local_abspath);
+
+ svn_hash_sets(resolve_later, dup_abspath, dup_abspath);
+
+ return SVN_NO_ERROR; /* Retry after other conflicts */
+ }
+ else
+ *did_resolve = TRUE;
}
else
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
@@ -2789,12 +2811,28 @@ resolve_tree_conflict_on_node(svn_boolea
* move (theirs-conflict). */
if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
{
- SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(
+ err = svn_wc__db_update_moved_away_conflict_victim(
db, local_abspath,
notify_func, notify_baton,
cancel_func, cancel_baton,
- scratch_pool));
- *did_resolve = TRUE;
+ scratch_pool);
+
+ if (err)
+ {
+ const char *dup_abspath;
+ if (err && err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ dup_abspath = apr_pstrdup(apr_hash_pool_get(resolve_later),
+ local_abspath);
+
+ svn_hash_sets(resolve_later, dup_abspath, dup_abspath);
+
+ return SVN_NO_ERROR; /* Retry after other conflicts */
+ }
+ else
+ *did_resolve = TRUE;
}
else if (conflict_choice == svn_wc_conflict_choose_merged)
{
@@ -2822,20 +2860,27 @@ resolve_tree_conflict_on_node(svn_boolea
}
}
- if (! *did_resolve && conflict_choice != svn_wc_conflict_choose_merged)
+ if (! *did_resolve)
{
- /* For other tree conflicts, there is no way to pick
- * theirs-full or mine-full, etc. Throw an error if the
- * user expects us to be smarter than we really are. */
- return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
- NULL,
- _("Tree conflict can only be "
- "resolved to 'working' state; "
- "'%s' not resolved"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
+ if (conflict_choice != svn_wc_conflict_choose_merged)
+ {
+ /* For other tree conflicts, there is no way to pick
+ * theirs-full or mine-full, etc. Throw an error if the
+ * user expects us to be smarter than we really are. */
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
+ NULL,
+ _("Tree conflict can only be "
+ "resolved to 'working' state; "
+ "'%s' not resolved"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+ else
+ *did_resolve = TRUE;
}
+ SVN_ERR_ASSERT(*did_resolve);
+
SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, FALSE, TRUE,
NULL, scratch_pool));
SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
@@ -2888,6 +2933,7 @@ struct conflict_status_walker_baton
void *cancel_baton;
svn_wc_notify_func2_t notify_func;
void *notify_baton;
+ apr_hash_t *resolve_later;
};
/* Implements svn_wc_status4_t to walk all conflicts to resolve.
@@ -2957,13 +3003,15 @@ conflict_status_walker(void *baton,
db,
local_abspath,
my_choice,
+ cswb->resolve_later,
cswb->notify_func,
cswb->notify_baton,
cswb->cancel_func,
cswb->cancel_baton,
iterpool));
- resolved = TRUE;
+ if (did_resolve)
+ resolved = TRUE;
break;
case svn_wc_conflict_kind_text:
@@ -3045,6 +3093,8 @@ svn_wc__resolve_conflicts(svn_wc_context
svn_node_kind_t kind;
svn_boolean_t conflicted;
struct conflict_status_walker_baton cswb;
+ apr_pool_t *iterpool = NULL;
+ svn_error_t *err;
/* ### the underlying code does NOT support resolving individual
### properties. bail out if the caller tries it. */
@@ -3084,6 +3134,8 @@ svn_wc__resolve_conflicts(svn_wc_context
cswb.notify_func = notify_func;
cswb.notify_baton = notify_baton;
+ cswb.resolve_later = apr_hash_make(scratch_pool);
+
if (notify_func)
notify_func(notify_baton,
svn_wc_create_notify(local_abspath,
@@ -3091,16 +3143,66 @@ svn_wc__resolve_conflicts(svn_wc_context
scratch_pool),
scratch_pool);
- SVN_ERR(svn_wc_walk_status(wc_ctx,
- local_abspath,
- depth,
- FALSE /* get_all */,
- FALSE /* no_ignore */,
- TRUE /* ignore_text_mods */,
- NULL /* ignore_patterns */,
- conflict_status_walker, &cswb,
- cancel_func, cancel_baton,
- scratch_pool));
+ err = svn_wc_walk_status(wc_ctx,
+ local_abspath,
+ depth,
+ FALSE /* get_all */,
+ FALSE /* no_ignore */,
+ TRUE /* ignore_text_mods */,
+ NULL /* ignore_patterns */,
+ conflict_status_walker, &cswb,
+ cancel_func, cancel_baton,
+ scratch_pool);
+
+ while (!err && apr_hash_count(cswb.resolve_later))
+ {
+ apr_hash_index_t *hi;
+ svn_boolean_t cleared_one = FALSE;
+ const char *tc_abspath = NULL;
+
+ if (iterpool)
+ svn_pool_clear(iterpool);
+ else
+ iterpool = svn_pool_create(scratch_pool);
+
+ for (hi = apr_hash_first(scratch_pool, cswb.resolve_later);
+ hi && !err;
+ hi = apr_hash_next(hi))
+ {
+ tc_abspath = svn__apr_hash_index_key(hi);
+ svn_pool_clear(iterpool);
+
+ svn_hash_sets(cswb.resolve_later, tc_abspath, NULL);
+
+ err = svn_wc_walk_status(wc_ctx, tc_abspath, depth, FALSE, FALSE,
+ TRUE, NULL, conflict_status_walker, &cswb,
+ cancel_func, cancel_baton,
+ iterpool);
+
+ if (!err && !svn_hash_gets(cswb.resolve_later, tc_abspath))
+ cleared_one = TRUE;
+ }
+
+ if (!cleared_one && !err)
+ {
+ /* Return the error on one of the paths: The last one. */
+ err = svn_error_createf(
+ SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("Unable to resolve pending conflict on '%s'"),
+ svn_dirent_local_style(tc_abspath, scratch_pool));
+ }
+ }
+
+ if (iterpool)
+ svn_pool_destroy(iterpool);
+
+ if (err && err->apr_err != SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
+ err = svn_error_createf(
+ SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
+ _("Unable to resolve conflicts on '%s'"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+
+ SVN_ERR(err);
if (notify_func)
notify_func(notify_baton,
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff.h?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff.h (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff.h Wed Nov 27 07:53:29 2013
@@ -38,7 +38,9 @@
extern "C" {
#endif /* __cplusplus */
-/* Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
+/* A function to diff locally added and locally copied files.
+
+ Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
PROCESSOR with as parent baton PROCESSOR_PARENT_BATON.
The node is expected to have status svn_wc__db_status_normal, or
@@ -61,7 +63,9 @@ svn_wc__diff_local_only_file(svn_wc__db_
void *cancel_baton,
apr_pool_t *scratch_pool);
-/* Reports the directory LOCAL_ABSPATH and everything below it (limited by
+/* A function to diff locally added and locally copied directories.
+
+ Reports the directory LOCAL_ABSPATH and everything below it (limited by
DEPTH) as added with relpath RELPATH to PROCESSOR with as parent baton
PROCESSOR_PARENT_BATON.
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff_local.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/diff_local.c Wed Nov 27 07:53:29 2013
@@ -115,16 +115,23 @@ ensure_state(struct diff_baton *eb,
apr_pool_t *ns_pool;
if (!eb->cur)
{
- if (!svn_dirent_is_ancestor(eb->anchor_abspath, local_abspath))
+ const char *relpath;
+
+ relpath = svn_dirent_skip_ancestor(eb->anchor_abspath, local_abspath);
+ if (! relpath)
return SVN_NO_ERROR;
- SVN_ERR(ensure_state(eb,
- svn_dirent_dirname(local_abspath,scratch_pool),
- FALSE,
- scratch_pool));
+ /* Don't recurse on the anchor, as that might loop infinately because
+ svn_dirent_dirname("/",...) -> "/"
+ svn_dirent_dirname("C:/",...) -> "C:/" (Windows) */
+ if (*relpath)
+ SVN_ERR(ensure_state(eb,
+ svn_dirent_dirname(local_abspath, scratch_pool),
+ FALSE,
+ scratch_pool));
}
else if (svn_dirent_is_child(eb->cur->local_abspath, local_abspath, NULL))
- SVN_ERR(ensure_state(eb, svn_dirent_dirname(local_abspath,scratch_pool),
+ SVN_ERR(ensure_state(eb, svn_dirent_dirname(local_abspath, scratch_pool),
FALSE,
scratch_pool));
else
@@ -390,7 +397,7 @@ diff_status_callback(void *baton,
}
}
- if (local_only)
+ if (local_only && (db_status != svn_wc__db_status_deleted))
{
if (db_kind == svn_node_file)
SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/status.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/status.c Wed Nov 27 07:53:29 2013
@@ -241,144 +241,7 @@ struct file_baton
/** Code **/
-/* Fill in *INFO with the information it would contain if it were
- obtained from svn_wc__db_read_children_info. */
-static svn_error_t *
-read_info(const struct svn_wc__db_info_t **info,
- const char *local_abspath,
- svn_wc__db_t *db,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- struct svn_wc__db_info_t *mtb = apr_pcalloc(result_pool, sizeof(*mtb));
- const svn_checksum_t *checksum;
- const char *original_repos_relpath;
-
- SVN_ERR(svn_wc__db_read_info(&mtb->status, &mtb->kind,
- &mtb->revnum, &mtb->repos_relpath,
- &mtb->repos_root_url, &mtb->repos_uuid,
- &mtb->changed_rev, &mtb->changed_date,
- &mtb->changed_author, &mtb->depth,
- &checksum, NULL, &original_repos_relpath, NULL,
- NULL, NULL, &mtb->lock, &mtb->recorded_size,
- &mtb->recorded_time, &mtb->changelist,
- &mtb->conflicted, &mtb->op_root,
- &mtb->had_props, &mtb->props_mod,
- &mtb->have_base, &mtb->have_more_work, NULL,
- db, local_abspath,
- result_pool, scratch_pool));
-
- SVN_ERR(svn_wc__db_wclocked(&mtb->locked, db, local_abspath, scratch_pool));
-
- /* Maybe we have to get some shadowed lock from BASE to make our test suite
- happy... (It might be completely unrelated, but...) */
- if (mtb->have_base
- && (mtb->status == svn_wc__db_status_added
- || mtb->status == svn_wc__db_status_deleted
- || mtb->kind == svn_node_file))
- {
- svn_boolean_t update_root;
- svn_wc__db_lock_t **lock_arg = NULL;
-
- if (mtb->status == svn_wc__db_status_added
- || mtb->status == svn_wc__db_status_deleted)
- lock_arg = &mtb->lock;
-
- SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
- lock_arg, NULL, NULL, &update_root,
- db, local_abspath,
- result_pool, scratch_pool));
-
- mtb->file_external = (update_root && mtb->kind == svn_node_file);
-
- if (mtb->status == svn_wc__db_status_deleted)
- {
- const char *moved_to_abspath;
- const char *moved_to_op_root_abspath;
-
- /* NOTE: we can't use op-root-ness as a condition here since a base
- * node can be the root of a move and still not be an explicit
- * op-root (having a working node with op_depth == pathelements).
- *
- * Both these (almost identical) situations showcase this:
- * svn mv a/b bb
- * svn del a
- * and
- * svn mv a aa
- * svn mv aa/b bb
- * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
- * node at all, as its parent 'a' is locally deleted. */
-
- SVN_ERR(svn_wc__db_scan_deletion(NULL,
- &moved_to_abspath,
- NULL,
- &moved_to_op_root_abspath,
- db, local_abspath,
- scratch_pool, scratch_pool));
- if (moved_to_abspath != NULL
- && moved_to_op_root_abspath != NULL
- && strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0)
- {
- mtb->moved_to_abspath = apr_pstrdup(result_pool,
- moved_to_abspath);
- }
- /* ### ^^^ THIS SUCKS. For at least two reasons:
- * 1) We scan the node deletion and that's technically not necessary.
- * We'd be fine to know if this is an actual root of a move.
- * 2) From the elaborately calculated results, we backwards-guess
- * whether this is a root.
- * It works ok, and this code only gets called when a node is an
- * explicit target of a 'status'. But it would be better to do this
- * differently.
- * We could return moved-to via svn_wc__db_base_get_info() (called
- * just above), but as moved-to is only intended to be returned for
- * roots of a move, that doesn't fit too well. */
- }
- }
-
- /* ### svn_wc__db_read_info() could easily return the moved-here flag. But
- * for now... (The per-dir query for recursive status is far more optimal.)
- * Note that this actually scans around to get the full path, for a bool.
- * This bool then gets returned, later is evaluated, and if true leads to
- * the same paths being scanned again. We'd want to obtain this bool here as
- * cheaply as svn_wc__db_read_children_info() does. */
- if (mtb->status == svn_wc__db_status_added)
- {
- svn_wc__db_status_t status;
-
- SVN_ERR(svn_wc__db_scan_addition(&status, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- db, local_abspath,
- result_pool, scratch_pool));
- mtb->moved_here = (status == svn_wc__db_status_moved_here);
- mtb->incomplete = (status == svn_wc__db_status_incomplete);
- }
-
- mtb->has_checksum = (checksum != NULL);
- mtb->copied = (original_repos_relpath != NULL);
-
-#ifdef HAVE_SYMLINK
- if (mtb->kind == svn_node_file
- && (mtb->had_props || mtb->props_mod))
- {
- apr_hash_t *properties;
-
- if (mtb->props_mod)
- SVN_ERR(svn_wc__db_read_props(&properties, db, local_abspath,
- scratch_pool, scratch_pool));
- else
- SVN_ERR(svn_wc__db_read_pristine_props(&properties, db, local_abspath,
- scratch_pool, scratch_pool));
-
- mtb->special = (NULL != svn_hash_gets(properties, SVN_PROP_SPECIAL));
- }
-#endif
- *info = mtb;
-
- return SVN_NO_ERROR;
-}
/* Return *REPOS_RELPATH and *REPOS_ROOT_URL for LOCAL_ABSPATH using
information in INFO if available, falling back on
@@ -492,7 +355,8 @@ assemble_status(svn_wc_status3_t **statu
if (!info)
- SVN_ERR(read_info(&info, local_abspath, db, result_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_single_info(&info, db, local_abspath,
+ result_pool, scratch_pool));
if (!info->repos_relpath || !parent_repos_relpath)
switched_p = FALSE;
@@ -712,19 +576,21 @@ assemble_status(svn_wc_status3_t **statu
&& prop_status != svn_wc_status_none)
node_status = prop_status;
- /* 5. Easy out: unless we're fetching -every- entry, don't bother
- to allocate a struct for an uninteresting entry. */
+ /* 5. Easy out: unless we're fetching -every- node, don't bother
+ to allocate a struct for an uninteresting node.
+ This filter should match the filter in is_sendable_status() */
if (! get_all)
if (((node_status == svn_wc_status_none)
|| (node_status == svn_wc_status_normal))
&& (! switched_p)
- && (! info->locked )
+ && (! info->locked)
&& (! info->lock)
&& (! repos_lock)
&& (! info->changelist)
- && (! conflicted))
+ && (! conflicted)
+ && (! info->moved_to))
{
*status = NULL;
return SVN_NO_ERROR;
@@ -798,8 +664,11 @@ assemble_status(svn_wc_status3_t **statu
stat->changelist = apr_pstrdup(result_pool, info->changelist);
stat->moved_from_abspath = moved_from_abspath;
- if (info->moved_to_abspath)
- stat->moved_to_abspath = apr_pstrdup(result_pool, info->moved_to_abspath);
+
+ /* ### TODO: Handle multiple moved_to values properly */
+ if (info->moved_to)
+ stat->moved_to_abspath = apr_pstrdup(result_pool,
+ info->moved_to->moved_to_abspath);
stat->file_external = info->file_external;
@@ -1344,8 +1213,8 @@ get_dir_status(const struct walk_status_
SVN_ERR(err);
if (!dir_info)
- SVN_ERR(read_info(&dir_info, local_abspath, wb->db,
- scratch_pool, iterpool));
+ SVN_ERR(svn_wc__db_read_single_info(&dir_info, wb->db, local_abspath,
+ scratch_pool, iterpool));
SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
&dir_repos_uuid, dir_info,
@@ -1505,8 +1374,9 @@ get_child_status(const struct walk_statu
if (dirent->kind == svn_node_none)
dirent = NULL;
- SVN_ERR(read_info(&dir_info, parent_abspath, wb->db,
- scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__db_read_single_info(&dir_info,
+ wb->db, parent_abspath,
+ scratch_pool, scratch_pool));
SVN_ERR(get_repos_root_url_relpath(&dir_repos_relpath, &dir_repos_root_url,
&dir_repos_uuid, dir_info,
@@ -1901,6 +1771,8 @@ make_file_baton(struct dir_baton *parent
* Return a boolean answer to the question "Is @a status something that
* should be reported?". @a no_ignore and @a get_all are the same as
* svn_wc_get_status_editor4().
+ *
+ * This implementation should match the filter in assemble_status()
*/
static svn_boolean_t
is_sendable_status(const svn_wc_status3_t *status,
@@ -1948,6 +1820,9 @@ is_sendable_status(const svn_wc_status3_
if (status->changelist)
return TRUE;
+ if (status->moved_to_abspath)
+ return TRUE;
+
/* Otherwise, don't send it. */
return FALSE;
}
@@ -2709,7 +2584,8 @@ svn_wc__internal_walk_status(svn_wc__db_
ignore_patterns = ignores;
}
- err = read_info(&info, local_abspath, db, scratch_pool, scratch_pool);
+ err = svn_wc__db_read_single_info(&info, db, local_abspath,
+ scratch_pool, scratch_pool);
if (err)
{
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/upgrade.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/upgrade.c Wed Nov 27 07:53:29 2013
@@ -755,13 +755,13 @@ migrate_single_tree_conflict_data(svn_sq
{
/* There is an existing ACTUAL row, so just update it. */
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_UPDATE_ACTUAL_CONFLICT_DATA));
+ STMT_UPDATE_ACTUAL_CONFLICT));
}
else
{
/* We need to insert an ACTUAL row with the tree conflict data. */
SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
- STMT_INSERT_ACTUAL_CONFLICT_DATA));
+ STMT_INSERT_ACTUAL_CONFLICT));
}
SVN_ERR(svn_sqlite__bindf(stmt, "iss", wc_id, conflict_relpath,
@@ -1959,6 +1959,10 @@ svn_wc__upgrade_sdb(int *result_format,
case SVN_WC__VERSION:
/* already upgraded */
*result_format = SVN_WC__VERSION;
+
+ SVN_SQLITE__WITH_LOCK(
+ svn_wc__db_install_schema_statistics(sdb, scratch_pool),
+ sdb);
}
#ifdef SVN_DEBUG
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-metadata.sql?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-metadata.sql Wed Nov 27 07:53:29 2013
@@ -573,6 +573,54 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED
local_relpath);
/* ------------------------------------------------------------------------- */
+/* This statement provides SQLite with the necessary information about our
+ indexes to make better decisions in the query planner.
+
+ For every interesting index this contains a number of rows where the
+ statistics ar calculated for and then for every column in the index the
+ average number of rows with the same value in all columns left of this
+ column including the column itself.
+
+ See http://www.sqlite.org/fileformat2.html#stat1tab for more details.
+
+ The important thing here is that this tells Sqlite that the wc_id column
+ of the NODES and ACTUAL_NODE table is usually a single value, so queries
+ should use more than one column for index usage.
+
+ The current hints describe NODES+ACTUAL_NODE as a working copy with
+ 8000 nodes in 1 a single working copy(=wc_id), 10 nodes per directory
+ and an average of 2 op-depth layers per node.
+
+ The number of integers must be number of index columns + 1, which is
+ verified via the test_schema_statistics() test.
+ */
+-- STMT_INSTALL_SCHEMA_STATISTICS
+ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1');
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('NODES', 'I_NODES_PARENT', '8000 8000 10 2 1');
+/* Tell a lie: We ignore that 99.9% of all moved_to values are NULL */
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('NODES', 'I_NODES_MOVED', '8000 8000 1 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('ACTUAL_NODE', 'sqlite_autoindex_ACTUAL_NODE_1', '8000 8000 1');
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('ACTUAL_NODE', 'I_ACTUAL_PARENT', '8000 8000 10 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('LOCK', 'sqlite_autoindex_LOCK_1', '100 100 1');
+
+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES
+ ('WC_LOCK', 'sqlite_autoindex_WC_LOCK_1', '100 100 1');
+
+/* sqlite_autoindex_WORK_QUEUE_1 doesn't exist because WORK_QUEUE is
+ a INTEGER PRIMARY KEY AUTOINCREMENT table */
+
+ANALYZE sqlite_master; /* Loads sqlite_stat1 data for query optimizer */
+/* ------------------------------------------------------------------------- */
/* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */
Modified: subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-queries.sql?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_wc/wc-queries.sql Wed Nov 27 07:53:29 2013
@@ -72,6 +72,12 @@ WHERE wc_id = ?1 AND local_relpath = ?2
-- STMT_SELECT_BASE_CHILDREN_INFO
SELECT local_relpath, nodes.repos_id, nodes.repos_path, presence, kind,
+ revision, depth, file_external
+FROM nodes
+WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0
+
+-- STMT_SELECT_BASE_CHILDREN_INFO_LOCK
+SELECT local_relpath, nodes.repos_id, nodes.repos_path, presence, kind,
revision, depth, file_external,
lock_token, lock_owner, lock_comment, lock_date
FROM nodes
@@ -79,6 +85,7 @@ LEFT OUTER JOIN lock ON nodes.repos_id =
AND nodes.repos_path = lock.repos_relpath
WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0
+
-- STMT_SELECT_WORKING_NODE
SELECT op_depth, presence, kind, checksum, translated_size,
changed_revision, changed_date, changed_author, depth, symlink_target,
@@ -118,8 +125,9 @@ WHERE wc_id = ?1 AND local_relpath = ?2
-- STMT_SELECT_NODE_CHILDREN_INFO
/* Getting rows in an advantageous order using
ORDER BY local_relpath, op_depth DESC
- turns out to be slower than getting rows in a random order and making the
- C code handle it. */
+ doesn't work as the index is created without the DESC keyword.
+ Using both local_relpath and op_depth descending does work without any
+ performance penalty. */
SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
checksum, translated_size, changed_revision, changed_date, changed_author,
depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
@@ -128,6 +136,7 @@ FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
AND nodes.repos_path = lock.repos_relpath AND op_depth = 0
WHERE wc_id = ?1 AND parent_relpath = ?2
+ORDER BY local_relpath DESC, op_depth DESC
-- STMT_SELECT_NODE_CHILDREN_WALKER_INFO
SELECT local_relpath, op_depth, presence, kind
@@ -191,7 +200,7 @@ WHERE wc_id = ?1
-- STMT_DELETE_NODE
DELETE
FROM NODES
-WHERE wc_id = ?1 AND local_relpath = ?2
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
-- STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE
/* The ACTUAL_NODE applies to BASE, unless there is in at least one op_depth
@@ -318,7 +327,7 @@ WHERE wc_id = ?1 AND op_depth = ?3
-- STMT_COMMIT_DESCENDANTS_TO_BASE
UPDATE NODES SET op_depth = 0,
repos_id = ?4,
- repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
+ repos_path = RELPATH_SKIP_JOIN(?2, ?5, local_relpath),
revision = ?6,
dav_cache = NULL,
moved_here = NULL,
@@ -417,25 +426,30 @@ LEFT OUTER JOIN nodes AS moved
WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
LIMIT 1
--- STMT_SELECT_OP_DEPTH_MOVED_TO
-SELECT op_depth, moved_to, repos_path, revision
+-- STMT_SELECT_MOVED_TO_NODE
+SELECT op_depth, moved_to
FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2
- AND op_depth <= (SELECT MIN(op_depth) FROM nodes
- WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
+WHERE wc_id = ?1 AND local_relpath = ?2 AND moved_to IS NOT NULL
ORDER BY op_depth DESC
+-- STMT_SELECT_OP_DEPTH_MOVED_TO
+SELECT n.op_depth, n.moved_to, p.repos_path, p.revision
+FROM nodes p
+LEFT JOIN nodes n
+ ON p.wc_id=n.wc_id AND p.local_relpath = n.local_relpath
+ AND n.op_depth = (SELECT MIN(d.op_depth)
+ FROM nodes d
+ WHERE d.wc_id = ?1
+ AND d.local_relpath = n.local_relpath
+ AND d.op_depth > ?3)
+WHERE p.wc_id = ?1 AND p.local_relpath = ?2 AND p.op_depth = ?3
+LIMIT 1
+
-- STMT_SELECT_MOVED_TO
SELECT moved_to
FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
--- STMT_SELECT_MOVED_HERE
-SELECT moved_here, presence, repos_path, revision
-FROM nodes
-WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth >= ?3
-ORDER BY op_depth
-
-- STMT_SELECT_MOVED_BACK
SELECT u.local_relpath,
u.presence, u.repos_id, u.repos_path, u.revision,
@@ -461,13 +475,6 @@ WHERE u.wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(u.local_relpath, ?2)
AND u.op_depth = ?4
--- STMT_DELETE_MOVED_BACK
-DELETE FROM nodes
-WHERE wc_id = ?1
- AND (local_relpath = ?2
- OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND op_depth = ?3
-
-- STMT_DELETE_LOCK
DELETE FROM lock
WHERE repos_id = ?1 AND repos_relpath = ?2
@@ -711,7 +718,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
AND presence = MAP_BASE_DELETED
--- STMT_DELETE_ALL_LAYERS
+-- STMT_DELETE_NODE_ALL_LAYERS
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
@@ -918,7 +925,7 @@ VALUES (?1, ?2, 0,
AND op_depth = 0))
-- STMT_INSTALL_WORKING_NODE_FOR_DELETE
-INSERT OR REPLACE INTO nodes (
+INSERT INTO nodes (
wc_id, local_relpath, op_depth,
parent_relpath, presence, kind)
VALUES(?1, ?2, ?3, ?4, MAP_BASE_DELETED, ?5)
@@ -1207,14 +1214,6 @@ VALUES (?1, ?2, ?3, ?4, ?5, ?6)
/* these are used in upgrade.c */
--- STMT_UPDATE_ACTUAL_CONFLICT_DATA
-UPDATE actual_node SET conflict_data = ?3
-WHERE wc_id = ?1 AND local_relpath = ?2
-
--- STMT_INSERT_ACTUAL_CONFLICT_DATA
-INSERT INTO actual_node (wc_id, local_relpath, conflict_data, parent_relpath)
-VALUES (?1, ?2, ?3, ?4)
-
-- STMT_SELECT_ALL_FILES
SELECT local_relpath FROM nodes_current
WHERE wc_id = ?1 AND parent_relpath = ?2 AND kind = MAP_FILE
@@ -1567,20 +1566,6 @@ UPDATE nodes SET moved_to = NULL
WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
-
-/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1,
- * where the source of the move is within the subtree rooted at path ?2, and
- * the destination of the move is outside the subtree rooted at path ?2. */
--- STMT_SELECT_MOVED_PAIR2
-SELECT local_relpath, moved_to, op_depth FROM nodes
-WHERE wc_id = ?1
- AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
- AND moved_to IS NOT NULL
- AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
- AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
- WHERE o.wc_id = ?1
- AND o.local_relpath = ?2)
-
-- STMT_SELECT_MOVED_PAIR3
SELECT local_relpath, moved_to, op_depth, kind FROM nodes
WHERE wc_id = ?1
@@ -1597,12 +1582,17 @@ WHERE wc_id = ?1
AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
-- STMT_SELECT_OP_DEPTH_MOVED_PAIR
-SELECT n.local_relpath, n.moved_to,
- (SELECT o.repos_path FROM nodes AS o
- WHERE o.wc_id = n.wc_id
- AND o.local_relpath = n.local_relpath
- AND o.op_depth < ?3 ORDER BY o.op_depth DESC LIMIT 1)
+SELECT n.local_relpath, p.kind, n.moved_to, p.repos_path
FROM nodes AS n
+JOIN (SELECT local_relpath, kind, repos_path
+ FROM nodes AS o
+ WHERE o.wc_id = ?1
+ AND o.op_depth=(SELECT MAX(d.op_depth)
+ FROM nodes AS d
+ WHERE d.wc_id = ?1
+ AND d.local_relpath = o.local_relpath
+ AND d.op_depth < ?3)) AS p
+ ON n.local_relpath = p.local_relpath
WHERE n.wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
AND n.op_depth = ?3
@@ -1624,12 +1614,8 @@ WHERE n.wc_id = ?1
AND h.moved_to IS NOT NULL
-- STMT_COMMIT_UPDATE_ORIGIN
-/* Note that the only reason this SUBSTR() trick is valid is that you
- can move neither the working copy nor the repository root.
-
- SUBSTR(local_relpath, LENGTH(?2)+1) includes the '/' of the path */
UPDATE nodes SET repos_id = ?4,
- repos_path = ?5 || SUBSTR(local_relpath, LENGTH(?2)+1),
+ repos_path = RELPATH_SKIP_JOIN(?2, ?5, local_relpath),
revision = ?6
WHERE wc_id = ?1
AND (local_relpath = ?2
@@ -1649,14 +1635,16 @@ ORDER BY local_relpath
-- STMT_SELECT_HAS_NON_FILE_CHILDREN
SELECT 1 FROM nodes
-WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0 AND kind != MAP_FILE
+WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = ?3 AND kind != MAP_FILE
+LIMIT 1
-- STMT_SELECT_HAS_GRANDCHILDREN
SELECT 1 FROM nodes
WHERE wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(parent_relpath, ?2)
- AND op_depth = 0
+ AND op_depth = ?3
AND file_external IS NULL
+LIMIT 1
/* ------------------------------------------------------------------------- */