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/20 21:31:21 UTC

svn commit: r936039 - in /subversion/trunk/subversion/libsvn_wc: entries.c wc_db.c wc_db.h

Author: gstein
Date: Tue Apr 20 19:31:20 2010
New Revision: 936039

URL: http://svn.apache.org/viewvc?rev=936039&view=rev
Log:
Factor the core of the entries reading loop out to a function that reads a
single entry from wc_db.

Alter how entries.c borrows an SDB reference from wc_db.

* subversion/libsvn_wc/entries.c:
  (read_entries_new): renamed into ...
  (read_one_entry): ... this. the parameters have been adjusted for
    single-entry reading, and the lead-in setup for iterating over
    children has been removed. a few localvars have been created to
    "rename" parameters according to the names the original code used, to
    minimize all impact on that code. some of the setup at the start of
    the core block (assigning entry->name and parent_entry) have been
    altered in favor of the new params. move the SDB borrowing down to the
    innermost block where it is used. remove a "continue" and put in an
    SVN_ERR_MALFUNCTION because that shouldn't have ever been reached.
    return the new entry, rather than shoving it into a hash.
  (read_entries_new): resuscitated from the original. it is now just the
    loop setup, initializing the PARENT_ENTRY localvar (and inserting into
    the hash), and gutting the loop to use the new read_one_entry. we
    don't need the SDB here, nor any monkeying of the CHILDREN array. we
    can also toss HANDLE_POOL since we'll be borrowing SDB references
    instead of allocating them ourself. wrap up the function with
    inserting the entries into the hash, and returning the hash.
  (write_one_entry): adjust how SDB references are borrowed.

* subversion/libsvn_wc/wc_db.h:
  (svn_wc__db_temp_get_sdb): renamed to ...
  (svn_wc__db_temp_borrow_sdb): ... this. the ALWAYS_OPEN and RESULT_POOL
    arguments are removed since we always open an SDB (or use an
    already-opened one) and all long-lasting items are allocated within
    the DB itself. added a MODE parameter to indicate readonly/write.

* subversion/libsvn_wc/wc_db.c:
  (svn_wc__db_temp_get_sdb): renamed to ...
  (svn_wc__db_temp_borrow_sdb): ... this. now we just use
    parse_local_abspath to do all the work, and return the wcroot's SDB.

Modified:
    subversion/trunk/subversion/libsvn_wc/entries.c
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/libsvn_wc/wc_db.h

Modified: subversion/trunk/subversion/libsvn_wc/entries.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/entries.c?rev=936039&r1=936038&r2=936039&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/entries.c (original)
+++ subversion/trunk/subversion/libsvn_wc/entries.c Tue Apr 20 19:31:20 2010
@@ -509,42 +509,33 @@ get_base_info_for_deleted(svn_wc_entry_t
 }
 
 
-/* Read entries for PATH/LOCAL_ABSPATH from DB (wc-1 or wc-ng). The entries
-   will be allocated in RESULT_POOL, with temporary allocations in
-   SCRATCH_POOL. The entries are returned in RESULT_ENTRIES.  */
-static svn_error_t *
-read_entries_new(apr_hash_t **result_entries,
-                 svn_wc__db_t *db,
-                 const char *local_abspath,
-                 apr_pool_t *result_pool,
-                 apr_pool_t *scratch_pool)
-{
-  svn_sqlite__db_t *sdb;
-  apr_hash_t *entries;
-  const apr_array_header_t *children;
-  apr_pool_t *handle_pool = svn_pool_create(scratch_pool);
-  apr_pool_t *iterpool = svn_pool_create(handle_pool);
-  int i;
-  const svn_wc_entry_t *parent_entry = NULL;
-  apr_uint64_t wc_id = 1;  /* ### hacky. should remove.  */
+/* Read one entry from wc_db. It will be allocated in RESULT_POOL and
+   returned in *NEW_ENTRY.
 
-  entries = apr_hash_make(result_pool);
+   DIR_ABSPATH is the name of the directory to read this entry from, and
+   it will be named NAME (use "" for "this dir").
 
-  /* ### need database to determine: incomplete, ACTUAL info.  */
-  SVN_ERR(svn_wc__db_temp_get_sdb(&sdb, db, local_abspath, FALSE,
-                                  handle_pool, iterpool));
+   DB specifies the wc_db database, and WC_ID specifies which working copy
+   this information is being read from.
 
-  SVN_ERR(svn_wc__db_read_children(&children, db,
-                                   local_abspath,
-                                   result_pool, iterpool));
+   If this node is "this dir", then PARENT_ENTRY should be NULL. Otherwise,
+   it should refer to the entry for the child's parent directory.
 
-  /* HACK: Push the directory at the end of a constant array */
-  APR_ARRAY_PUSH((apr_array_header_t *)children, const char *) = "";
+   Temporary allocations are made in SCRATCH_POOL.  */
+static svn_error_t *
+read_one_entry(const svn_wc_entry_t **new_entry,
+               svn_wc__db_t *db,
+               apr_uint64_t wc_id,
+               const char *dir_abspath,
+               const char *name,
+               const svn_wc_entry_t *parent_entry,
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
+{
+  /* Rename some parameters.  */
+  const char *local_abspath = dir_abspath;
+  apr_pool_t *iterpool = scratch_pool;
 
-  /* Note that this loop order causes "this dir" to be processed first.
-     This is necessary because we may need to access the directory's
-     entry during processing of "added" nodes.  */
-  for (i = children->nelts; i--; )
     {
       svn_wc__db_kind_t kind;
       svn_wc__db_status_t status;
@@ -559,13 +550,7 @@ read_entries_new(apr_hash_t **result_ent
       svn_boolean_t conflicted;
       svn_boolean_t base_shadowed;
 
-      svn_pool_clear(iterpool);
-
-      entry->name = APR_ARRAY_IDX(children, i, const char *);
-
-      /* If we're on THIS_DIR, then set up PARENT_ENTRY for later use.  */
-      if (*entry->name == '\0')
-        parent_entry = entry;
+      entry->name = name;
 
       entry_abspath = svn_dirent_join(local_abspath, entry->name, iterpool);
 
@@ -661,8 +646,14 @@ read_entries_new(apr_hash_t **result_ent
              instead.  */
           if (kind == svn_wc__db_kind_dir)
             {
+                svn_sqlite__db_t *sdb;
                 svn_sqlite__stmt_t *stmt;
 
+                SVN_ERR(svn_wc__db_temp_borrow_sdb(
+                          &sdb, db, local_abspath,
+                          svn_wc__db_openmode_readonly,
+                          iterpool));
+
                 SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
                                                   STMT_SELECT_NOT_PRESENT));
                 SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, entry->name));
@@ -1020,9 +1011,8 @@ read_entries_new(apr_hash_t **result_ent
         }
       else
         {
-          /* ### We aren't using this status. Yet.  */
-          SVN_ERR_ASSERT(status == svn_wc__db_status_excluded);
-          continue;
+          /* ### we should have handled all possible status values.  */
+          SVN_ERR_MALFUNCTION();
         }
 
       /* ### higher levels want repos information about deleted nodes, even
@@ -1124,10 +1114,56 @@ read_entries_new(apr_hash_t **result_ent
 
       entry->working_size = translated_size;
 
+      *new_entry = entry;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Read entries for PATH/LOCAL_ABSPATH from DB. The entries
+   will be allocated in RESULT_POOL, with temporary allocations in
+   SCRATCH_POOL. The entries are returned in RESULT_ENTRIES.  */
+static svn_error_t *
+read_entries_new(apr_hash_t **result_entries,
+                 svn_wc__db_t *db,
+                 const char *local_abspath,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  apr_hash_t *entries;
+  const apr_array_header_t *children;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  int i;
+  const svn_wc_entry_t *parent_entry;
+  apr_uint64_t wc_id = 1;  /* ### hacky. should remove.  */
+
+  entries = apr_hash_make(result_pool);
+
+  SVN_ERR(read_one_entry(&parent_entry, db, wc_id, local_abspath,
+                         "" /* name */,
+                         NULL /* parent_entry */,
+                         result_pool, iterpool));
+  apr_hash_set(entries, "", APR_HASH_KEY_STRING, parent_entry);
+
+  /* Use result_pool so that the child names (used by reference, rather
+     than copied) appear in result_pool.  */
+  SVN_ERR(svn_wc__db_read_children(&children, db,
+                                   local_abspath,
+                                   result_pool, iterpool));
+  for (i = children->nelts; i--; )
+    {
+      const char *name = APR_ARRAY_IDX(children, i, const char *);
+      const svn_wc_entry_t *entry;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(read_one_entry(&entry,
+                             db, wc_id, local_abspath, name, parent_entry,
+                             result_pool, iterpool));
       apr_hash_set(entries, entry->name, APR_HASH_KEY_STRING, entry);
     }
 
-  svn_pool_destroy(handle_pool);
+  svn_pool_destroy(iterpool);
 
   *result_entries = entries;
 
@@ -2476,8 +2512,9 @@ write_one_entry(svn_wc__db_t *db,
   svn_sqlite__db_t *sdb;
 
   /* ### need the SDB so we can jam rows directly into it.  */
-  SVN_ERR(svn_wc__db_temp_get_sdb(&sdb, db, local_abspath, FALSE,
-                                  scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_temp_borrow_sdb(&sdb, db, local_abspath,
+                                     svn_wc__db_openmode_readwrite,
+                                     scratch_pool));
   woeb.db = db;
   woeb.local_abspath = local_abspath;
   woeb.this_dir = this_dir;

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=936039&r1=936038&r2=936039&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Tue Apr 20 19:31:20 2010
@@ -879,7 +879,13 @@ open_db(svn_sqlite__db_t **sdb,
 
 /* For a given LOCAL_ABSPATH, figure out what sqlite database (PDH) to
    use and the RELPATH within that wcroot.  If a sqlite database needs
-   to be opened, then use SMODE for it. */
+   to be opened, then use SMODE for it.
+
+   *LOCAL_RELPATH will be allocated within RESULT_POOL. Temporary allocations
+   will be made in SCRATCH_POOL.
+
+   Certain internal structures will be allocated in DB->STATE_POOL.
+*/
 static svn_error_t *
 parse_local_abspath(svn_wc__db_pdh_t **pdh,
                     const char **local_relpath,
@@ -6193,32 +6199,36 @@ svn_wc__db_temp_get_all_access(svn_wc__d
 
 
 svn_error_t *
-svn_wc__db_temp_get_sdb(svn_sqlite__db_t **sdb,
-                        svn_wc__db_t *db,
-                        const char *dir_abspath,
-                        svn_boolean_t always_open,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool)
+svn_wc__db_temp_borrow_sdb(svn_sqlite__db_t **sdb,
+                           svn_wc__db_t *db,
+                           const char *local_dir_abspath,
+                           svn_wc__db_openmode_t mode,
+                           apr_pool_t *scratch_pool)
 {
-  if (!always_open)
-    {
-      svn_wc__db_pdh_t *pdh;
+  svn_wc__db_pdh_t *pdh;
+  const char *local_relpath;
+  svn_sqlite__mode_t smode;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(local_dir_abspath));
 
-      pdh = get_or_create_pdh(db, dir_abspath, FALSE, scratch_pool);
+  if (mode == svn_wc__db_openmode_readonly)
+    smode = svn_sqlite__mode_readonly;
+  else
+    smode = svn_sqlite__mode_readwrite;
 
-      if (pdh != NULL &&
-          pdh->wcroot != NULL &&
-          pdh->wcroot->sdb != NULL &&
-          strcmp(pdh->wcroot->abspath, dir_abspath) == 0)
-        {
-          *sdb = pdh->wcroot->sdb;
-          return SVN_NO_ERROR;
-        }
-    }
+  SVN_ERR(parse_local_abspath(&pdh, &local_relpath,
+                              db, local_dir_abspath, smode,
+                              scratch_pool, scratch_pool));
+  VERIFY_USABLE_PDH(pdh);
 
-  return svn_error_return(open_db(sdb, dir_abspath, SDB_FILE,
-                                  svn_sqlite__mode_readwrite,
-                                  result_pool, scratch_pool));
+  /* We better be looking at the proper wcroot for this directory.
+     If we ended up with a stub, then the subdirectory (and its SDB!)
+     are missing.  */
+  SVN_ERR_ASSERT(*local_relpath == '\0');
+
+  *sdb = pdh->wcroot->sdb;
+
+  return SVN_NO_ERROR;
 }
 
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.h?rev=936039&r1=936038&r2=936039&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.h Tue Apr 20 19:31:20 2010
@@ -2080,25 +2080,22 @@ apr_hash_t *
 svn_wc__db_temp_get_all_access(svn_wc__db_t *db,
                                apr_pool_t *result_pool);
 
-/* ### temp function to open the sqlite database to the appropriate location.
+/* ### temp function to open the sqlite database to the appropriate location,
+   ### then borrow it for a bit.
    ### The *only* reason for this function is because entries.c still
    ### manually hacks the sqlite database.
 
-   ### If ALWAYS_OPEN is FALSE, try to retrieve the existing database
-   ### handle instead of reopening.
-
    ### No matter how tempted you may be DO NOT USE THIS FUNCTION!
    ### (if you do, gstein will hunt you down and burn your knee caps off
    ### in the middle of the night)
    ### "Bet on it." --gstein
 */
 svn_error_t *
-svn_wc__db_temp_get_sdb(svn_sqlite__db_t **sdb,
-                        svn_wc__db_t *db,
-                        const char *local_dir_abspath,
-                        svn_boolean_t always_open,
-                        apr_pool_t *result_pool,
-                        apr_pool_t *scratch_pool);
+svn_wc__db_temp_borrow_sdb(svn_sqlite__db_t **sdb,
+                           svn_wc__db_t *db,
+                           const char *local_dir_abspath,
+                           svn_wc__db_openmode_t mode,
+                           apr_pool_t *scratch_pool);
 
 
 /* Return a directory in *TEMP_DIR_ABSPATH that is suitable for temporary