You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/01/16 23:49:11 UTC

svn commit: r1434462 - in /subversion/branches/fsfs-format7/subversion: libsvn_fs_fs/pack.c tests/libsvn_fs_fs/fs-pack-test.c

Author: stefan2
Date: Wed Jan 16 22:49:11 2013
New Revision: 1434462

URL: http://svn.apache.org/viewvc?rev=1434462&view=rev
Log:
On the fsfs-format7 branch: Add packing support to format7.

* subversion/libsvn_fs_fs/pack.c
  (copy_indexes): new utility copying info from non-packed to packed indexes
  (pack_rev_shard): depending on the repo format, either write indexes or
   manifest files
  (pack_shard): update caller

* subversion/tests/libsvn_fs_fs/fs-pack-test.c
  (pack_filesystem): check for the right files to be present depending on
   repository format

Modified:
    subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c
    subversion/branches/fsfs-format7/subversion/tests/libsvn_fs_fs/fs-pack-test.c

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c?rev=1434462&r1=1434461&r2=1434462&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c Wed Jan 16 22:49:11 2013
@@ -28,6 +28,7 @@
 #include "util.h"
 #include "revprops.h"
 #include "transaction.h"
+#include "index.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -97,6 +98,70 @@ svn_fs_fs__get_packed_offset(apr_off_t *
   return svn_cache__set(ffd->packed_offset_cache, &shard, manifest, pool);
 }
 
+/* Copy the index information from the unpacked revision REV in FS to the
+ * PROTO_L2P_INDEX and PROTO_P2L_INDEX proto index files, respectively.
+ * Assume that the rev file will be appended to the pack file at offset
+ * PACK_OFFSET and that the unpacked rev file contains FILE_SIZE bytes.
+ * Use POOL for allocations.
+ */
+static svn_error_t *
+copy_indexes(svn_fs_t *fs,
+             apr_file_t *proto_l2p_index,
+             apr_file_t *proto_p2l_index,
+             svn_revnum_t rev,
+             apr_off_t pack_offset,
+             apr_off_t file_size,
+             apr_pool_t *pool)
+{
+  apr_off_t offset = 0;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+
+  /* mark the start of a new revision */
+  SVN_ERR(svn_fs_fs__l2p_proto_index_add_revision(proto_l2p_index, pool));
+
+  /* read the phys-to-log index file until we covered the whole rev file.
+   * That index contains enough info to build both target indexes from it. */
+  while (offset < file_size)
+    {
+      /* read one cluster */
+      int i;
+      apr_array_header_t *entries;
+      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, rev, offset,
+                                          iterpool));
+
+      for (i = 0; i < entries->nelts; ++i)
+        {
+          svn_fs_fs__p2l_entry_t *entry
+            = &APR_ARRAY_IDX(entries, i, svn_fs_fs__p2l_entry_t);
+
+          /* skip first entry if that was duplicated due crossing a
+             cluster boundary */
+          if (offset == entry->offset)
+            continue;
+
+          /* process entry while inside the rev file */
+          offset = entry->offset;
+          if (offset < file_size)
+            {
+              entry->offset += pack_offset;
+              SVN_ERR(svn_fs_fs__l2p_proto_index_add_entry(proto_l2p_index,
+                                                           entry->offset,
+                                                           entry->item_index,
+                                                           iterpool));
+              SVN_ERR(svn_fs_fs__p2l_proto_index_add_entry(proto_p2l_index,
+                                                           entry,
+                                                           iterpool));
+            }
+        }
+
+      svn_pool_clear(iterpool);
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 /* Pack the revision SHARD containing exactly MAX_FILES_PER_DIR revisions
  * from SHARD_PATH into the PACK_FILE_DIR, using POOL for allocations.
  * CANCEL_FUNC and CANCEL_BATON are what you think they are.
@@ -105,7 +170,8 @@ svn_fs_fs__get_packed_offset(apr_off_t *
  * remove the pack file and start again.
  */
 static svn_error_t *
-pack_rev_shard(const char *pack_file_dir,
+pack_rev_shard(svn_fs_t *fs,
+               const char *pack_file_dir,
                const char *shard_path,
                apr_int64_t shard,
                int max_files_per_dir,
@@ -113,27 +179,51 @@ pack_rev_shard(const char *pack_file_dir
                void *cancel_baton,
                apr_pool_t *pool)
 {
+  fs_fs_data_t *ffd = fs->fsap_data;
   const char *pack_file_path, *manifest_file_path;
+  const char *proto_l2p_index_path, *proto_p2l_index_path;
+  const char *l2p_index_path, *p2l_index_path;
   svn_stream_t *pack_stream, *manifest_stream;
   svn_revnum_t start_rev, end_rev, rev;
   apr_off_t next_offset;
   apr_pool_t *iterpool;
+  apr_file_t *proto_l2p_index, *proto_p2l_index;
 
   /* Some useful paths. */
   pack_file_path = svn_dirent_join(pack_file_dir, PATH_PACKED, pool);
   manifest_file_path = svn_dirent_join(pack_file_dir, PATH_MANIFEST, pool);
+  l2p_index_path = apr_pstrcat(pool, pack_file_path, PATH_EXT_L2P_INDEX, NULL);
+  p2l_index_path = apr_pstrcat(pool, pack_file_path, PATH_EXT_P2L_INDEX, NULL);
+  proto_l2p_index_path = svn_dirent_join(pack_file_dir,
+                                         PATH_INDEX PATH_EXT_L2P_INDEX, pool);
+  proto_p2l_index_path = svn_dirent_join(pack_file_dir,
+                                         PATH_INDEX PATH_EXT_P2L_INDEX, pool);
 
   /* Remove any existing pack file for this shard, since it is incomplete. */
   SVN_ERR(svn_io_remove_dir2(pack_file_dir, TRUE, cancel_func, cancel_baton,
                              pool));
 
-  /* Create the new directory and pack and manifest files. */
+  /* Create the new directory and pack file. */
   SVN_ERR(svn_io_dir_make(pack_file_dir, APR_OS_DEFAULT, pool));
   SVN_ERR(svn_stream_open_writable(&pack_stream, pack_file_path, pool,
                                     pool));
-  SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
-                                   pool, pool));
 
+  /* Index information files */
+  if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+    {
+      /* Create proto index files*/
+      SVN_ERR(svn_fs_fs__l2p_proto_index_open(&proto_l2p_index, 
+                                              proto_l2p_index_path, pool));
+      SVN_ERR(svn_fs_fs__p2l_proto_index_open(&proto_p2l_index,
+                                              proto_p2l_index_path, pool));
+    }
+  else
+    {
+      /* Create the manifest file. */
+      SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
+                                       pool, pool));
+    }
+  
   start_rev = (svn_revnum_t) (shard * max_files_per_dir);
   end_rev = (svn_revnum_t) ((shard + 1) * (max_files_per_dir) - 1);
   next_offset = 0;
@@ -153,9 +243,13 @@ pack_rev_shard(const char *pack_file_dir
                              iterpool);
       SVN_ERR(svn_io_stat(&finfo, path, APR_FINFO_SIZE, iterpool));
 
-      /* Update the manifest. */
-      SVN_ERR(svn_stream_printf(manifest_stream, iterpool, "%" APR_OFF_T_FMT
-                                "\n", next_offset));
+      /* build indexes / manifest */
+      if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+        SVN_ERR(copy_indexes(fs, proto_l2p_index, proto_p2l_index,
+                             rev, next_offset, finfo.size, pool));
+      else
+        SVN_ERR(svn_stream_printf(manifest_stream, iterpool,
+                                  "%" APR_OFF_T_FMT "\n", next_offset));
       next_offset += finfo.size;
 
       /* Copy all the bits from the rev file to the end of the pack file. */
@@ -165,11 +259,35 @@ pack_rev_shard(const char *pack_file_dir
                           cancel_func, cancel_baton, iterpool));
     }
 
-  SVN_ERR(svn_stream_close(manifest_stream));
+  /* Finalize Index information files */
+  if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+    {
+      /* finalize proto index files */
+      SVN_ERR(svn_io_file_close(proto_l2p_index, iterpool));
+      SVN_ERR(svn_io_file_close(proto_p2l_index, iterpool));
+      
+      /* Create the actual index files*/
+      SVN_ERR(svn_fs_fs__l2p_index_create(l2p_index_path,
+                                          proto_l2p_index_path,
+                                          start_rev, iterpool));
+      SVN_ERR(svn_fs_fs__p2l_index_create(p2l_index_path,
+                                          proto_p2l_index_path,
+                                          start_rev, iterpool));
+
+      /* remove proto index files */
+      SVN_ERR(svn_io_remove_file2(proto_l2p_index_path, FALSE, iterpool));
+      SVN_ERR(svn_io_remove_file2(proto_p2l_index_path, FALSE, iterpool));
+    }
+  else
+    {
+      /* disallow write access to the manifest file */
+      SVN_ERR(svn_stream_close(manifest_stream));
+      SVN_ERR(svn_io_set_file_read_only(manifest_file_path, FALSE, iterpool));
+    }
+
   SVN_ERR(svn_stream_close(pack_stream));
   SVN_ERR(svn_io_copy_perms(shard_path, pack_file_dir, iterpool));
   SVN_ERR(svn_io_set_file_read_only(pack_file_path, FALSE, iterpool));
-  SVN_ERR(svn_io_set_file_read_only(manifest_file_path, FALSE, iterpool));
 
   svn_pool_destroy(iterpool);
 
@@ -221,7 +339,7 @@ pack_shard(const char *revs_dir,
                            pool);
 
   /* pack the revision content */
-  SVN_ERR(pack_rev_shard(rev_pack_file_dir, rev_shard_path,
+  SVN_ERR(pack_rev_shard(fs, rev_pack_file_dir, rev_shard_path,
                          shard, max_files_per_dir,
                          cancel_func, cancel_baton, pool));
 

Modified: subversion/branches/fsfs-format7/subversion/tests/libsvn_fs_fs/fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=1434462&r1=1434461&r2=1434462&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original)
+++ subversion/branches/fsfs-format7/subversion/tests/libsvn_fs_fs/fs-pack-test.c Wed Jan 16 22:49:11 2013
@@ -311,14 +311,37 @@ pack_filesystem(const svn_test_opts_t *o
         return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
                                  "Expected pack file '%s' not found", path);
 
-      path = svn_dirent_join_many(pool, REPO_NAME, "revs",
-                                  apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
-                                  "manifest", NULL);
-      SVN_ERR(svn_io_check_path(path, &kind, pool));
-      if (kind != svn_node_file)
-        return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                                 "Expected manifest file '%s' not found",
-                                 path);
+      if (opts->server_minor_version && (opts->server_minor_version < 6))
+        {
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "manifest", NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected manifest file '%s' not found",
+                                     path);
+        }
+      else
+        {
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "pack.l2p", NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected log-to-phys index file '%s' not found",
+                                     path);
+
+          path = svn_dirent_join_many(pool, REPO_NAME, "revs",
+                                      apr_psprintf(pool, "%d.pack", i / SHARD_SIZE),
+                                      "pack.p2l", NULL);
+          SVN_ERR(svn_io_check_path(path, &kind, pool));
+          if (kind != svn_node_file)
+            return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
+                                     "Expected phys-to-log index file '%s' not found",
+                                     path);
+        }
 
       /* This directory should not exist. */
       path = svn_dirent_join_many(pool, REPO_NAME, "revs",