On Sat, Sep 4, 2010 at 12:45 PM, Justin Erenkrantz
<justin_at_erenkrantz.com> wrote:
> I'm going to see what a quick check to retrieve just the kind and
> status will do for the query volume. I think it's unlikely we have to
> pull everything out of sqlite to answer that basic question. --
> justin
We can reduce the query volume by one (per file) as we can skip the
active table query - see quick & dirty patch below.
It does replace 2 larger queries with 2 smaller ones, but I think our
bottleneck is likely more around query volume than query complexity...
Anyway, I'll stop replying to myself and enjoy the long weekend. =) -- justin
Index: status.c
===================================================================
--- status.c (revision 992534)
+++ status.c (working copy)
@@ -1263,10 +1270,7 @@ get_dir_status(const struct walk_status_baton *wb,
svn_wc__db_status_t node_status;
svn_wc__db_kind_t node_kind;
- SVN_ERR(svn_wc__db_read_info(&node_status, &node_kind, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL,
+ SVN_ERR(svn_wc__db_read_info_exist(&node_status, &node_kind,
wb->db, node_abspath, iterpool, iterpool));
if (node_status != svn_wc__db_status_not_present
Index: wc_db.c
===================================================================
--- wc_db.c (revision 992534)
+++ wc_db.c (working copy)
@@ -51,7 +51,6 @@
#include "private/svn_wc_private.h"
#include "private/svn_token.h"
-
#define NOT_IMPLEMENTED() SVN__NOT_IMPLEMENTED()
@@ -5051,6 +5050,161 @@ svn_wc__db_temp_op_delete(svn_wc__db_t *db,
svn_error_t *
+svn_wc__db_read_info_exist(svn_wc__db_status_t *status,
+ svn_wc__db_kind_t *kind,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_pdh_t *pdh;
+ const char *local_relpath;
+ svn_sqlite__stmt_t *stmt_base;
+ svn_sqlite__stmt_t *stmt_work;
+ svn_boolean_t have_base;
+ svn_boolean_t have_work;
+ svn_error_t *err = NULL;
+
+ SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
+
+ SVN_ERR(svn_wc__db_pdh_parse_local_abspath(&pdh, &local_relpath, db,
+ local_abspath, svn_sqlite__mode_readonly,
+ scratch_pool, scratch_pool));
+ VERIFY_USABLE_PDH(pdh);
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt_base, pdh->wcroot->sdb,
+ STMT_SELECT_BASE_NODE_EXIST));
+ SVN_ERR(svn_sqlite__bindf(stmt_base, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_base, stmt_base));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt_work, pdh->wcroot->sdb,
+ STMT_SELECT_WORKING_NODE_EXIST));
+ SVN_ERR(svn_sqlite__bindf(stmt_work, "is",
+ pdh->wcroot->wc_id, local_relpath));
+ SVN_ERR(svn_sqlite__step(&have_work, stmt_work));
+
+ if (have_base || have_work)
+ {
+ svn_wc__db_kind_t node_kind;
+
+ if (have_work)
+ node_kind = svn_sqlite__column_token(stmt_work, 1, kind_map);
+ else
+ node_kind = svn_sqlite__column_token(stmt_base, 1, kind_map);
+
+ if (status)
+ {
+ if (have_base)
+ {
+ *status = svn_sqlite__column_token(stmt_base, 0, presence_map);
+
+ /* We have a presence that allows a WORKING_NODE override
+ (normal or not-present), or we don't have an override. */
+ /* ### for now, allow an override of an incomplete BASE_NODE
+ ### row. it appears possible to get rows in BASE/WORKING
+ ### both set to 'incomplete'. */
+ SVN_ERR_ASSERT((*status != svn_wc__db_status_absent
+ && *status != svn_wc__db_status_excluded
+ /* && *status != svn_wc__db_status_incomplete */)
+ || !have_work);
+
+#ifndef SVN_WC__SINGLE_DB
+ if (node_kind == svn_wc__db_kind_subdir
+ && *status == svn_wc__db_status_normal)
+ {
+ /* We should have read a row from the subdir wc.db. It
+ must be obstructed in some way.
+
+ It is also possible that a WORKING node will override
+ this value with a proper status. */
+ *status = svn_wc__db_status_obstructed;
+ }
+#endif
+ }
+
+ if (have_work)
+ {
+ svn_wc__db_status_t work_status;
+
+ work_status = svn_sqlite__column_token(stmt_work, 0,
+ presence_map);
+ SVN_ERR_ASSERT(work_status == svn_wc__db_status_normal
+ || work_status == svn_wc__db_status_not_present
+ || work_status == svn_wc__db_status_base_deleted
+ || work_status == svn_wc__db_status_incomplete
+ || work_status == svn_wc__db_status_excluded);
+
+ if (work_status == svn_wc__db_status_incomplete)
+ {
+ *status = svn_wc__db_status_incomplete;
+ }
+ else if (work_status == svn_wc__db_status_excluded)
+ {
+ *status = svn_wc__db_status_excluded;
+ }
+ else if (work_status == svn_wc__db_status_not_present
+ || work_status == svn_wc__db_status_base_deleted)
+ {
+ /* The caller should scan upwards to detect whether this
+ deletion has occurred because this node has been moved
+ away, or it is a regular deletion. Also note that the
+ deletion could be of the BASE tree, or a child of
+ something that has been copied/moved here. */
+
+#ifndef SVN_WC__SINGLE_DB
+ /* If we're looking at the data in the parent, then
+ something has obstructed the child data. Inform
+ the caller. */
+ if (node_kind == svn_wc__db_kind_subdir)
+ *status = svn_wc__db_status_obstructed_delete;
+ else
+#endif
+ *status = svn_wc__db_status_deleted;
+ }
+ else /* normal */
+ {
+ /* The caller should scan upwards to detect whether this
+ addition has occurred because of a simple addition,
+ a copy, or is the destination of a move. */
+
+#ifndef SVN_WC__SINGLE_DB
+ /* If we're looking at the data in the parent, then
+ something has obstructed the child data. Inform
+ the caller. */
+ if (node_kind == svn_wc__db_kind_subdir)
+ *status = svn_wc__db_status_obstructed_add;
+ else
+#endif
+ *status = svn_wc__db_status_added;
+ }
+ }
+ }
+ if (kind)
+ {
+#ifndef SVN_WC__SINGLE_DB
+ if (node_kind == svn_wc__db_kind_subdir)
+ *kind = svn_wc__db_kind_dir;
+ else
+#endif
+ *kind = node_kind;
+ }
+ }
+ else
+ {
+ err = svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+ _("The node '%s' was not found."),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+
+ err = svn_error_compose_create(err, svn_sqlite__reset(stmt_base));
+ SVN_ERR(svn_error_compose_create(err, svn_sqlite__reset(stmt_work)));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
svn_wc__db_read_info(svn_wc__db_status_t *status,
svn_wc__db_kind_t *kind,
svn_revnum_t *revision,
Index: wc_db.h
===================================================================
--- wc_db.h (revision 992534)
+++ wc_db.h (working copy)
@@ -1523,7 +1523,16 @@ svn_wc__db_read_info(svn_wc__db_status_t *status,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+svn_error_t *
+svn_wc__db_read_info_exist(svn_wc__db_status_t *status, /* ### derived */
+ svn_wc__db_kind_t *kind,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
/* Set *PROPVAL to the value of the property named PROPNAME of the node
LOCAL_ABSPATH in the ACTUAL tree (looking through to the WORKING or BASE
tree as required).
Index: wc-queries.sql
===================================================================
--- wc-queries.sql (revision 992534)
+++ wc-queries.sql (working copy)
@@ -43,6 +43,11 @@ left outer join lock on base_node.repos_id = lock.
and base_node.repos_relpath = lock.repos_relpath
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_SELECT_BASE_NODE_EXIST
+select presence, kind
+from base_node
+where wc_id = ?1 and local_relpath = ?2;
+
-- STMT_SELECT_WORKING_NODE
select presence, kind, checksum, translated_size,
changed_rev, changed_date, changed_author, depth, symlink_target,
@@ -51,6 +56,11 @@ select presence, kind, checksum, translated_size,
from working_node
where wc_id = ?1 and local_relpath = ?2;
+-- STMT_SELECT_WORKING_NODE_EXIST
+select presence, kind
+from working_node
+where wc_id = ?1 and local_relpath = ?2;
+
-- STMT_SELECT_ACTUAL_NODE
select prop_reject, changelist, conflict_old, conflict_new,
conflict_working, tree_conflict_data, properties
Received on 2010-09-04 22:23:13 CEST