Author: danielsh
Date: Sat Jul  9 05:07:32 2011
New Revision: 1144593

URL: http://svn.apache.org/viewvc?rev=1144593&view=rev
Log:
On the revprop-packing branch:

Implement special-casing of r0 to never be packed.

* BRANCH-README: Remove this task.

* subversion/libsvn_fs_fs/fs_fs.c
  (REVPROP_ZERO): New macro for grepping.
  (is_packed_revprop): Return FALSE for r0.
  (svn_fs_fs__hotcopy): Run the 'unpacked revision' block for r0.
  (set_revision_proplist, revision_proplist):
    Use is_packed_revprop() instead of inline code.
  (svn_fs_fs__revision_proplist):
    No need to retry for r0.
  (recover_body): In the (very odd) case that MAX_REV is zero,
    don't assume its revprops might be packed.
  (pack_revprop_shard):
    Don't stream r0 into the pack file; leave a placeholder manifest entry.
    Don't rm r0's sharded file.

Modified:
    subversion/branches/revprop-packing/BRANCH-README
    subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs_fs.c

Modified: subversion/branches/revprop-packing/BRANCH-README
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/BRANCH-README?rev=1144593&r1=1144592&r2=1144593&view=diff
==============================================================================
--- subversion/branches/revprop-packing/BRANCH-README (original)
+++ subversion/branches/revprop-packing/BRANCH-README Sat Jul  9 05:07:32 2011
@@ -17,8 +17,6 @@ TODO:
 
 * add code catering for virus scanners during atomic move-into-place
 
-* add r0 special case
-
 * implement packed revprop editing
   + add sequence number; adjust readers accordingly
 

Modified: subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs_fs.c?rev=1144593&r1=1144592&r2=1144593&view=diff
==============================================================================
--- subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs_fs.c 
(original)
+++ subversion/branches/revprop-packing/subversion/libsvn_fs_fs/fs_fs.c Sat Jul 
 9 05:07:32 2011
@@ -165,13 +165,16 @@ is_packed_rev(svn_fs_t *fs, svn_revnum_t
   return (rev < ffd->min_unpacked_rev);
 }
 
+/* grep-friendly name for r0, whose revprop isn't packed. */
+#define REVPROP_ZERO 0
+
 /* Return TRUE is REV is packed in FS, FALSE otherwise. */
 static svn_boolean_t
 is_packed_revprop(svn_fs_t *fs, svn_revnum_t rev)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
 
-  return (rev < ffd->min_unpacked_revprop);
+  return (rev != REVPROP_ZERO) && (rev < ffd->min_unpacked_revprop);
 }
 
 static const char *
@@ -1696,6 +1699,7 @@ svn_fs_fs__hotcopy(const char *src_path,
 
   /* Then, copy non-packed shards. */
   SVN_ERR_ASSERT(rev == min_unpacked_revprop);
+  rev = REVPROP_ZERO;
   for (; rev <= youngest; rev++)
     {
       const char *src_subdir_shard = src_subdir,
@@ -1722,6 +1726,13 @@ svn_fs_fs__hotcopy(const char *src_path,
       SVN_ERR(svn_io_dir_file_copy(src_subdir_shard, dst_subdir_shard,
                                    apr_psprintf(iterpool, "%ld", rev),
                                    iterpool));
+
+      /* ### This causes the body of the 'for' loop to run
+         ### for r0 and for r<min_unpacked_revprop> through r<youngest>. */
+      if (rev == REVPROP_ZERO)
+        /* Don't run twice for r0. */
+        if (REVPROP_ZERO != min_unpacked_revprop)
+          rev = min_unpacked_revprop - 1; /* rev++ done by the loop */
     }
 
   svn_pool_destroy(iterpool);
@@ -3040,7 +3051,7 @@ set_revision_proplist(svn_fs_t *fs,
   SVN_ERR(ensure_revision_exists(fs, rev, pool));
 
   if (ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT ||
-      rev >= ffd->min_unpacked_revprop)
+      ! is_packed_revprop(fs, rev))
     {
       const char *final_path = path_revprops(fs, rev, pool);
       const char *tmp_path;
@@ -3194,7 +3205,7 @@ revision_proplist(apr_hash_t **proplist_
   SVN_ERR(ensure_revision_exists(fs, rev, pool));
 
   if (ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT ||
-      rev >= ffd->min_unpacked_revprop)
+      ! is_packed_revprop(fs, rev))
     {
       apr_file_t *revprop_file = NULL;
       svn_error_t *err = SVN_NO_ERROR;
@@ -3314,7 +3325,8 @@ svn_fs_fs__revision_proplist(apr_hash_t 
 
   err = revision_proplist(proplist_p, fs, rev, pool);
   if (err && err->apr_err == SVN_ERR_FS_NO_SUCH_REVISION
-      && ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+      && ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT
+      && rev != REVPROP_ZERO)
     {
       /* If a pack is occurring simultaneously, the min-unpacked-revprop value
          could change, so reload it and then attempt to fetch these revprops
@@ -7306,7 +7318,8 @@ recover_body(void *baton, apr_pool_t *po
 
          ### TODO: Could we check for revprops in the revprops.db?
          ###       What if rNNN legitimately has no revprops? */
-      if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+      if (ffd->format >= SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT
+          && max_rev != REVPROP_ZERO)
         {
           svn_revnum_t min_unpacked_revprop;
 
@@ -7997,6 +8010,7 @@ pack_revprop_shard(svn_fs_t *fs,
   apr_off_t next_offset;
   apr_file_t *manifest_file;
   apr_pool_t *iterpool;
+  svn_boolean_t started_at_r0 = FALSE;
 
   pack_file_dir = svn_dirent_join(revprops_dir,
                         apr_psprintf(pool, "%" APR_INT64_T_FMT ".pack", shard),
@@ -8032,6 +8046,24 @@ pack_revprop_shard(svn_fs_t *fs,
   next_offset = 0;
   iterpool = svn_pool_create(pool);
 
+  /* Special case r0. */
+  if (start_rev == REVPROP_ZERO)
+    {
+      /* Insert a placeholder manifest entry:
+         write "@@@@@@@@@@@@@@@@" for r0's manifest record.*/
+      char buf[REVPROP_MANIFEST_FIELD_WIDTH + 1];
+      memset(buf, '@', REVPROP_MANIFEST_FIELD_WIDTH);
+      buf[REVPROP_MANIFEST_FIELD_WIDTH] = '\0';
+
+      SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%s", buf));
+
+      /* Don't dump r0 in the revpack file. */
+      start_rev++;
+
+      /* Remember not to remove r0's sharded file. */
+      started_at_r0 = TRUE;
+    }
+
   /* Iterate over the revisions in this shard, squashing them together. */
   for (rev = start_rev; rev <= end_rev; rev++)
     {
@@ -8080,16 +8112,29 @@ pack_revprop_shard(svn_fs_t *fs,
   SVN_ERR(write_revnum_file(fs_path, PATH_MIN_UNPACKED_REVPROP,
                             (svn_revnum_t)((shard + 1) * max_files_per_dir),
                             iterpool));
-  svn_pool_destroy(iterpool);
 
   /* Finally, remove the existing shard directory. */
-  SVN_ERR(svn_io_remove_dir2(shard_path, TRUE, cancel_func, cancel_baton,
-                             pool));
+  if (started_at_r0)
+    {
+      SVN_ERR_ASSERT(start_rev-1 == REVPROP_ZERO);
+      for (rev = start_rev; rev <= end_rev; rev++)
+        {
+          const char *path = svn_dirent_join(shard_path,
+                                             apr_psprintf(iterpool, "%ld",
+                                                          rev),
+                                             iterpool);
+          SVN_ERR(svn_io_remove_file2(path, TRUE, iterpool));
+        }
+    }
+  else
+    SVN_ERR(svn_io_remove_dir2(shard_path, TRUE, cancel_func, cancel_baton,
+                               pool));
 
   /* Notify caller we're starting to pack this shard. */
   if (notify_func)
     SVN_ERR(notify_func(notify_baton, shard, svn_fs_pack_notify_end_revprop,
                         pool));
+  svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }


Reply via email to