On 03/17/2011 03:43 PM, Greg Stein wrote: > Dude. If you want to delete *one* prop from the dav_cache, then just torch > them all (ie. set to null). HTTPv2 does not use them. HTTPv1 only uses the > vsn URL. And it is a cache. > > So don't be tricky. Blast the entire dav_cache rather than tweak it.
Yes, the more I examined real-world usage, the more I decided that full cache invalidation would be fine. But sometimes, it's good exercise to force yourself to dive into an API you've never looked at before and try something new. I managed to successfully implement the functionality I set out to implement, and that's intellectually satisfying. I'm sure you know and can appreciate this feeling. I've attached the patch here in case someone else wants to model similar functionality on it later. (Philip has a similar patch for another bit of unrelated functionality.) But, yeah, it's a full dav_cache purge that I'll be committing. -- C. Michael Pilato <cmpil...@collab.net> CollabNet <> www.collab.net <> Distributed Development On Demand
Use an application-provided SQLite function (SVN_PROPDEL) to purge a particular dav_cache property from all the nodes at or under a specified path. * subversion/libsvn_subr/sqlite.c (appfunc_svn_propdel): New app-definited SQLite function implementation. (svn_sqlite__open): Register the new appfunc_svn_propdel() function with the database context. * subversion/include/private/svn_wc_private.h, * subversion/libsvn_wc/props.c (svn_wc__node_remove_davcache_prop_recursive): New function. * subversion/libsvn_wc/wc-queries.sql (STMT_DELETE_NODE_DAVCACHE_PROP): New query for clearing one named dav_cache property. * subversion/libsvn_wc/wc_db.h, * subversion/libsvn_wc/wc_db.c (svn_wc__db_remove_prop_from_davcache_recursively): New function. * subversion/libsvn_client/ra.c (struct invalidate_wcprop_walk_baton, invalidate_wcprop_for_node): Remove as unused. (invalidate_wc_props): Use svn_wc__node_remove_davcache_prop_recursive() rather than crawling nodes. --This line, and those below, will be ignored-- Index: subversion/libsvn_subr/sqlite.c =================================================================== --- subversion/libsvn_subr/sqlite.c (revision 1082680) +++ subversion/libsvn_subr/sqlite.c (working copy) @@ -869,12 +869,72 @@ return APR_SUCCESS; } +/* An SQLite application-defined scalar function, for use with + sqlite3_create_function(). + + Allows SQL queries to use: + + svn_propdel(PROPERTY_NAME, PROPERTY_BLOB) + + Userdata is a SCRATCH_POOL, which this function clears after use. + Return a BLOB containing the skel-marshaled version of + PROPERTY_BLOB with its PROPERTY_NAME property removed. */ +static void +appfunc_svn_propdel(sqlite3_context *context, + int argc, + sqlite3_value **argv) +{ + svn_error_t *err; + int value_len; + const char *value, *propname; + apr_hash_t *props; + svn_skel_t *props_skel; + svn_stringbuf_t *props_buf; + apr_pool_t *scratch_pool = (apr_pool_t *)sqlite3_user_data(context); + + /* Validate function parameters. */ + SVN_ERR_ASSERT_NO_RETURN(argc == 2); + SVN_ERR_ASSERT_NO_RETURN(sqlite3_value_type(argv[0]) == SQLITE_TEXT); + SVN_ERR_ASSERT_NO_RETURN((sqlite3_value_type(argv[1]) == SQLITE_BLOB) || + (sqlite3_value_type(argv[1]) == SQLITE_NULL)); + + /* No propeties? Nothing to do. */ + if (sqlite3_value_type(argv[1]) == SQLITE_NULL) + { + sqlite3_result_null(context); + return; + } + + /* Parse the properties skel from argv[1] ... */ + propname = (const char *)sqlite3_value_text(argv[0]); + value_len = sqlite3_value_bytes(argv[1]); + value = (const char *)sqlite3_value_blob(argv[1]); + props_skel = svn_skel__parse(value, value_len, scratch_pool); + err = svn_skel__parse_proplist(&props, props_skel, scratch_pool); + SVN_ERR_ASSERT_NO_RETURN(err == SVN_NO_ERROR); + + /* ... remove the specified property from the resulting hash ... */ + apr_hash_set(props, propname, APR_HASH_KEY_STRING, NULL); + + /* ... unparse the resulting property hash ... */ + err = svn_skel__unparse_proplist(&props_skel, props, scratch_pool); + SVN_ERR_ASSERT_NO_RETURN(err == SVN_NO_ERROR); + props_buf = svn_skel__unparse(props_skel, scratch_pool); + + /* ... and return the result. */ + sqlite3_result_blob(context, props_buf->data, props_buf->len, + SQLITE_TRANSIENT); + svn_pool_clear(scratch_pool); +} + svn_error_t * svn_sqlite__open(svn_sqlite__db_t **db, const char *path, svn_sqlite__mode_t mode, const char * const statements[], int latest_schema, const char * const *upgrade_sql, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { + apr_pool_t *custom_func_scratch_pool = svn_pool_create(result_pool); + SVN_ERR(svn_atomic__init_once(&sqlite_init_state, init_sqlite, NULL, scratch_pool)); @@ -925,6 +985,11 @@ if (upgrade_sql != NULL) SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool)); + /* Register custom SVNPROPDEL SQLite function. */ + SQLITE_ERR(sqlite3_create_function((*db)->db3, "svn_propdel", 2, SQLITE_UTF8, + (void *)custom_func_scratch_pool, + &appfunc_svn_propdel, NULL, NULL), *db); + /* Store the provided statements. */ if (statements) { Index: subversion/include/private/svn_wc_private.h =================================================================== --- subversion/include/private/svn_wc_private.h (revision 1082680) +++ subversion/include/private/svn_wc_private.h (working copy) @@ -777,6 +777,13 @@ apr_pool_t *scratch_pool); +svn_error_t * +svn_wc__node_remove_davcache_prop_recursive(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + apr_pool_t *scratch_pool); + + /** * For use by entries.c and entries-dump.c to read old-format working copies. */ Index: subversion/libsvn_wc/props.c =================================================================== --- subversion/libsvn_wc/props.c (revision 1082680) +++ subversion/libsvn_wc/props.c (working copy) @@ -2729,3 +2729,15 @@ } return FALSE; } + +svn_error_t * +svn_wc__node_remove_davcache_prop_recursive(svn_wc_context_t *wc_ctx, + const char *local_abspath, + const char *propname, + apr_pool_t *scratch_pool) +{ + return svn_wc__db_remove_prop_from_davcache_recursively(wc_ctx->db, + local_abspath, + propname, + scratch_pool); +} Index: subversion/libsvn_wc/wc-queries.sql =================================================================== --- subversion/libsvn_wc/wc-queries.sql (revision 1082680) +++ subversion/libsvn_wc/wc-queries.sql (working copy) @@ -219,6 +219,10 @@ UPDATE actual_node SET properties = ?3 WHERE wc_id = ?1 AND local_relpath = ?2 +-- STMT_DELETE_NODE_DAVCACHE_PROP +UPDATE nodes SET dav_cache = SVN_PROPDEL(?4, dav_cache) +WHERE wc_id = ?1 AND (local_relpath = ?2 OR local_relpath LIKE ?3 ESCAPE '#'); + -- STMT_INSERT_ACTUAL_PROPS INSERT INTO actual_node (wc_id, local_relpath, parent_relpath, properties) VALUES (?1, ?2, ?3, ?4) Index: subversion/libsvn_wc/wc_db.c =================================================================== --- subversion/libsvn_wc/wc_db.c (revision 1082680) +++ subversion/libsvn_wc/wc_db.c (working copy) @@ -9865,3 +9865,29 @@ revision_status_txn, &rsb, scratch_pool)); } + + +svn_error_t * +svn_wc__db_remove_prop_from_davcache_recursively(svn_wc__db_t *db, + const char *local_abspath, + const char *propname, + apr_pool_t *scratch_pool) +{ + svn_wc__db_wcroot_t *wcroot; + const char *local_relpath; + svn_sqlite__stmt_t *stmt; + + SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); + SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, + db, local_abspath, + scratch_pool, scratch_pool)); + + SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, + STMT_DELETE_NODE_DAVCACHE_PROP)); + SVN_ERR(svn_sqlite__bindf(stmt, "isss", + wcroot->wc_id, + local_relpath, + construct_like_arg(local_relpath, scratch_pool), + propname)); + return svn_error_return(svn_sqlite__step_done(stmt)); +} Index: subversion/libsvn_wc/wc_db.h =================================================================== --- subversion/libsvn_wc/wc_db.h (revision 1082680) +++ subversion/libsvn_wc/wc_db.h (working copy) @@ -2649,6 +2649,12 @@ apr_pool_t *scratch_pool); +svn_error_t * +svn_wc__db_remove_prop_from_davcache_recursively(svn_wc__db_t *db, + const char *local_abspath, + const char *propname, + apr_pool_t *scratch_pool); + /* @} */ Index: subversion/libsvn_client/ra.c =================================================================== --- subversion/libsvn_client/ra.c (revision 1082680) +++ subversion/libsvn_client/ra.c (working copy) @@ -254,12 +254,9 @@ local_abspath = svn_dirent_join(cb->base_dir_abspath, path, pool); - return svn_error_return( - svn_wc__node_walk_children(cb->ctx->wc_ctx, local_abspath, FALSE, - invalidate_wcprop_for_node, &wb, - svn_depth_infinity, - cb->ctx->cancel_func, cb->ctx->cancel_baton, - pool)); + return svn_error_return(svn_wc__node_remove_davcache_prop_recursive( + cb->ctx->wc_ctx, local_abspath, + prop_name, pool)); }
signature.asc
Description: OpenPGP digital signature