You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gs...@apache.org on 2010/04/21 10:23:57 UTC
svn commit: r936199 - in /subversion/trunk/subversion:
libsvn_wc/old-and-busted.c tests/libsvn_wc/entries-compat.c
Author: gstein
Date: Wed Apr 21 08:23:56 2010
New Revision: 936199
URL: http://svn.apache.org/viewvc?rev=936199&view=rev
Log:
Revamp the old svn_wc_entry() to get entries from the cached hash of
entries, in order to follow the docstring. The (replaced) algorithm using
svn_wc__get_entry() will soon follow different pool lifetime guides which
will not use the entries cache. Thus, it would break svn_wc_entry's
guarantees about pool usage.
Add a new test to track these lifetime guarantees and baton usage.
* subversion/libsvn_wc/old-and-busted.:
(svn_wc_entry): rebuild this similar to the logic used by 1.6.x, but
using some wc-ng stuffs to reach access batons.
* subversion/tests/libsvn_wc/entries-compat.c:
(M_TESTING_DATA): our new test requires a second .svn metadata area, and
this content will be loaded.
(make_one_db): new function comprised of the guts of create_fake_wc.
(create_fake_wc): shift content out to make_one_db, and then use that to
create two metadata areas for the tests.
(test_stubs): new testing function to verify interaction of the access
batons, the entries hash, and the svn_wc_entry() return values.
(test_funcs): add new test
Modified:
subversion/trunk/subversion/libsvn_wc/old-and-busted.c
subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c
Modified: subversion/trunk/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/old-and-busted.c?rev=936199&r1=936198&r2=936199&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/trunk/subversion/libsvn_wc/old-and-busted.c Wed Apr 21 08:23:56 2010
@@ -1301,48 +1301,47 @@ svn_wc_entry(const svn_wc_entry_t **entr
svn_boolean_t show_hidden,
apr_pool_t *pool)
{
+ svn_wc__db_t *db = svn_wc__adm_get_db(adm_access);
const char *local_abspath;
- svn_error_t *err;
+ svn_wc_adm_access_t *dir_access;
+ const char *entry_name;
+ apr_hash_t *entries;
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path, pool));
- err = svn_wc__get_entry(entry,
- svn_wc__adm_get_db(adm_access),
- local_abspath,
- TRUE /* allow_unversioned */,
- svn_node_unknown,
- FALSE /* need_parent_stub */,
- svn_wc_adm_access_pool(adm_access), pool);
- if (err)
+ /* Does the provided path refer to a directory with an associated
+ access baton? */
+ dir_access = svn_wc__adm_retrieve_internal2(db, local_abspath, pool);
+ if (dir_access == NULL)
{
- if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
- {
- /* Even though we said ALLOW_UNVERSIONED == TRUE, this error can
- happen when the requested node is a directory, but that
- directory is not found. We'll go ahead and return the stub.
-
- So: fall through to clear the error. */
- }
- else if (err->apr_err == SVN_ERR_WC_MISSING)
- {
- /* This can happen when we ask about a subdir's node, but both
- the subdirectory and its parent are missing metadata. This
- can happen during (say) the diff process against the repository
- where a node *does* exist, and it looks for the same locally.
-
- See diff_tests 36 -- diff_added_subtree()
-
- We'll just say the entry does not exist, and fall through to
- clear this error. */
- *entry = NULL;
- }
- else if (err->apr_err != SVN_ERR_NODE_UNEXPECTED_KIND)
- return svn_error_return(err);
+ /* Damn. Okay. Assume the path is to a child, and let's look for
+ a baton associated with its parent. */
- /* We got the parent stub instead of the real entry. Fine. */
- svn_error_clear(err);
+ const char *dir_abspath;
+
+ svn_dirent_split(local_abspath, &dir_abspath, &entry_name, pool);
+
+ dir_access = svn_wc__adm_retrieve_internal2(db, dir_abspath, pool);
+ }
+ else
+ {
+ /* Woo! Got one. Look for "this dir" in the entries hash. */
+ entry_name = "";
}
+ if (dir_access == NULL)
+ {
+ /* Early exit. */
+ *entry = NULL;
+ return SVN_NO_ERROR;
+ }
+
+ /* Load an entries hash, and cache it into DIR_ACCESS. Go ahead and
+ fetch all entries here (optimization) since we know how to filter
+ out a "hidden" node. */
+ SVN_ERR(svn_wc_entries_read(&entries, dir_access, TRUE, pool));
+ *entry = apr_hash_get(entries, entry_name, APR_HASH_KEY_STRING);
+
if (!show_hidden && *entry != NULL)
{
svn_boolean_t hidden;
Modified: subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c?rev=936199&r1=936198&r2=936199&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/entries-compat.c Wed Apr 21 08:23:56 2010
@@ -309,23 +309,38 @@ static const char * const TESTING_DATA =
" null, null, null, 0, null, null, '()', 0); "
);
+
+static const char * const M_TESTING_DATA = (
+ /* Load our test data.
+
+ Note: do not use named-column insertions. This allows us to test
+ the column count in the schema matches our expectation here. */
+
+ "insert into repository values (1, '" ROOT_ONE "', '" UUID_ONE "'); "
+ "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
+ "insert into wcroot values (1, null); "
+
+ "insert into base_node values ("
+ " 1, '', 1, 'M', null, 'normal', 'dir', "
+ " 1, null, null, "
+ " 1, " TIME_1s ", '" AUTHOR_1 "', 'infinity', null, null, '()', null, 0, "
+ " null); "
+ );
+
WC_QUERIES_SQL_DECLARE_STATEMENTS(statements);
static svn_error_t *
-create_fake_wc(const char *subdir, int format, apr_pool_t *scratch_pool)
+make_one_db(const char *dirpath,
+ const char * const my_statements[],
+ apr_pool_t *scratch_pool)
{
- const char *dirpath = svn_dirent_join_many(scratch_pool,
- "fake-wc", subdir, ".svn", NULL);
const char *dbpath = svn_dirent_join(dirpath, "wc.db", scratch_pool);
svn_sqlite__db_t *sdb;
- const char * const my_statements[] = {
- statements[STMT_CREATE_SCHEMA],
- TESTING_DATA,
- NULL
- };
+ /* Create fake-wc/SUBDIR/.svn/ for placing the metadata. */
SVN_ERR(svn_io_make_dir_recursively(dirpath, scratch_pool));
+
svn_error_clear(svn_io_remove_file(dbpath, scratch_pool));
SVN_ERR(svn_sqlite__open(&sdb, dbpath, svn_sqlite__mode_rwcreate,
my_statements,
@@ -343,6 +358,33 @@ create_fake_wc(const char *subdir, int f
static svn_error_t *
+create_fake_wc(const char *subdir, int format, apr_pool_t *scratch_pool)
+{
+ const char *dirpath;
+ const char * const my_statements[] = {
+ statements[STMT_CREATE_SCHEMA],
+ TESTING_DATA,
+ NULL
+ };
+ const char * const M_statements[] = {
+ statements[STMT_CREATE_SCHEMA],
+ M_TESTING_DATA,
+ NULL
+ };
+
+ dirpath = svn_dirent_join_many(scratch_pool,
+ "fake-wc", subdir, ".svn", NULL);
+ SVN_ERR(make_one_db(dirpath, my_statements, scratch_pool));
+
+ dirpath = svn_dirent_join_many(scratch_pool,
+ "fake-wc", subdir, "M", ".svn", NULL);
+ SVN_ERR(make_one_db(dirpath, M_statements, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+
+static svn_error_t *
create_open(svn_wc__db_t **db,
const char **local_abspath,
const char *subdir,
@@ -410,10 +452,85 @@ test_entries_alloc(apr_pool_t *pool)
}
+static svn_error_t *
+test_stubs(apr_pool_t *pool)
+{
+ svn_wc__db_t *db;
+ const char *local_abspath;
+ const char *local_relpath;
+ svn_wc_adm_access_t *adm_access;
+ svn_wc_adm_access_t *subdir_access;
+ const svn_wc_entry_t *stub_entry;
+ const svn_wc_entry_t *entry;
+ const svn_wc_entry_t *test_entry;
+ apr_hash_t *entries;
+
+#undef WC_NAME
+#define WC_NAME "test_stubs"
+
+ SVN_ERR(create_open(&db, &local_abspath, WC_NAME, pool));
+
+ /* The "M" entry is a subdir. Let's ensure we can reach its stub,
+ and the actual contents. */
+ local_relpath = svn_dirent_join_many(pool,
+ "fake-wc",
+ WC_NAME,
+ "M",
+ NULL);
+
+ SVN_ERR(svn_wc_adm_open3(&adm_access,
+ NULL /* associated */,
+ svn_dirent_join("fake-wc", WC_NAME, pool),
+ FALSE /* write_lock */,
+ 0 /* levels_to_lock */,
+ NULL /* cancel_func */,
+ NULL /* cancel_baton */,
+ pool));
+
+ /* Ensure we get the stub. NOTE: do this before we have associated the
+ subdir baton with ADM_ACCESS. */
+ SVN_ERR(svn_wc_entry(&stub_entry, local_relpath, adm_access, TRUE, pool));
+ SVN_TEST_STRING_ASSERT(stub_entry->name, "M");
+
+ SVN_ERR(svn_wc_adm_open3(&subdir_access,
+ adm_access,
+ local_relpath,
+ FALSE /* write_lock */,
+ 0 /* levels_to_lock */,
+ NULL /* cancel_func */,
+ NULL /* cancel_baton */,
+ pool));
+
+ /* Ensure we get the real entry. */
+ SVN_ERR(svn_wc_entry(&entry, local_relpath, subdir_access, TRUE, pool));
+ SVN_TEST_STRING_ASSERT(entry->name, "");
+
+ /* Ensure that we get the SAME entry, even using the parent baton. */
+ SVN_ERR(svn_wc_entry(&test_entry, local_relpath, adm_access, TRUE, pool));
+ SVN_TEST_ASSERT(test_entry == entry);
+
+ /* Ensure we get the stub when reading entries with ADM_ACCESS. */
+ SVN_ERR(svn_wc_entries_read(&entries, adm_access, TRUE /* show_hidden */,
+ pool));
+ SVN_TEST_ASSERT(stub_entry
+ == apr_hash_get(entries, "M", APR_HASH_KEY_STRING));
+
+ /* Ensure we get the real entry when reading entries with SUBDIR_ACCESS. */
+ SVN_ERR(svn_wc_entries_read(&entries, subdir_access, TRUE /* show_hidden */,
+ pool));
+ SVN_TEST_ASSERT(entry
+ == apr_hash_get(entries, "", APR_HASH_KEY_STRING));
+
+ return SVN_NO_ERROR;
+}
+
+
struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_entries_alloc,
"entries are allocated in access baton"),
+ SVN_TEST_PASS2(test_stubs,
+ "access baton mojo can return stubs"),
SVN_TEST_NULL
};