Author: stefan2
Date: Thu Aug  1 17:36:42 2013
New Revision: 1509342

URL: http://svn.apache.org/r1509342
Log:
On the log-addressing branch:  Bump FSFS format number and introduce
the new "addressing" option to fsfs format files.  Make that available
to our internal code through the new svn_fs_fs__use_log_addressing API.
IOW, we support mixed addressing repos from the beginning.

* subversion/libsvn_fs_fs/fs.h
  (SVN_FS_FS__FORMAT_NUMBER): bump to 7
  (SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT): declare new feature level
  (fs_fs_data_t): add start rev for logical addressing

* subversion/libsvn_fs_fs/fs_fs.c
  (read_format,
   svn_fs_fs__write_format): read / write the new addressing option
  (svn_fs_fs__open): update caller
  (upgrade_body): ditto; enable log addressing for the next shard, if any
  (svn_fs_fs__create): handle the generic compatibility option that 
                       will be introduced with FSX;
                       init addressing option depending on it
  (svn_fs_fs__info_format): update to accept f7

* subversion/libsvn_fs_fs/util.h
  (svn_fs_fs__use_log_addressing): declare new private API

* subversion/libsvn_fs_fs/util.c
  (svn_fs_fs__use_log_addressing): implement

Modified:
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs.h
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs.h?rev=1509342&r1=1509341&r2=1509342&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs.h Thu Aug  1 
17:36:42 2013
@@ -105,7 +105,7 @@ extern "C" {
 /* The format number of this filesystem.
    This is independent of the repository format number, and
    independent of any other FS back ends. */
-#define SVN_FS_FS__FORMAT_NUMBER   6
+#define SVN_FS_FS__FORMAT_NUMBER   7
 
 /* The minimum format number that supports svndiff version 1.  */
 #define SVN_FS_FS__MIN_SVNDIFF1_FORMAT 2
@@ -148,6 +148,9 @@ extern "C" {
 /* The minimum format number that supports packed revprops. */
 #define SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT 6
 
+/* The minimum format number that supports packed revprops. */
+#define SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT 7
+
 /* The minimum format number that supports a configuration file (fsfs.conf) */
 #define SVN_FS_FS__MIN_CONFIG_FILE 4
 
@@ -264,10 +267,17 @@ typedef struct fs_fs_data_t
 {
   /* The format number of this FS. */
   int format;
+
   /* The maximum number of files to store per directory (for sharded
      layouts) or zero (for linear layouts). */
   int max_files_per_dir;
 
+  /* The first revision that uses logical addressing.  SVN_INVALID_REVNUM
+     if there is no such revision (pre-f7 or non-sharded).  May be a
+     future revision if the current shard started with physical addressing
+     and is not complete, yet. */
+  svn_revnum_t min_log_addressing_rev;
+
   /* The revision that was youngest, last time we checked. */
   svn_revnum_t youngest_rev_cache;
 

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs_fs.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs_fs.c?rev=1509342&r1=1509341&r2=1509342&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs_fs.c 
(original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/fs_fs.c Thu Aug  
1 17:36:42 2013
@@ -246,16 +246,21 @@ check_format_file_buffer_numeric(const c
 }
 
 /* Read the format number and maximum number of files per directory
-   from PATH and return them in *PFORMAT and *MAX_FILES_PER_DIR
-   respectively.
+   from PATH and return them in *PFORMAT, *MAX_FILES_PER_DIR and
+   MIN_LOG_ADDRESSING_REV respectively.
 
    *MAX_FILES_PER_DIR is obtained from the 'layout' format option, and
    will be set to zero if a linear scheme should be used.
+   *MIN_LOG_ADDRESSING_REV is obtained from the 'addressing' format option,
+   and will be set to SVN_INVALID_REVNUM for physical addressing.
 
    Use POOL for temporary allocation. */
 static svn_error_t *
-read_format(int *pformat, int *max_files_per_dir,
-            const char *path, apr_pool_t *pool)
+read_format(int *pformat,
+            int *max_files_per_dir,
+            svn_revnum_t *min_log_addressing_rev,
+            const char *path,
+            apr_pool_t *pool)
 {
   svn_error_t *err;
   svn_stream_t *stream;
@@ -297,6 +302,7 @@ read_format(int *pformat, int *max_files
 
   /* Set the default values for anything that can be set via an option. */
   *max_files_per_dir = 0;
+  *min_log_addressing_rev = SVN_INVALID_REVNUM;
 
   /* Read any options. */
   while (!eos)
@@ -323,17 +329,42 @@ read_format(int *pformat, int *max_files
             }
         }
 
+      if (*pformat >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT &&
+          strncmp(buf->data, "addressing ", 11) == 0)
+        {
+          if (strcmp(buf->data + 11, "physical") == 0)
+            {
+              *min_log_addressing_rev = SVN_INVALID_REVNUM;
+              continue;
+            }
+
+          if (strncmp(buf->data + 11, "logical ", 8) == 0)
+            {
+              int value;
+
+              /* Check that the argument is numeric. */
+              SVN_ERR(check_format_file_buffer_numeric(buf->data, 19, path, 
pool));
+              SVN_ERR(svn_cstring_atoi(&value, buf->data + 19));
+              *min_log_addressing_rev = value;
+              continue;
+            }
+        }
+
       return svn_error_createf(SVN_ERR_BAD_VERSION_FILE_FORMAT, NULL,
          _("'%s' contains invalid filesystem format option '%s'"),
          svn_dirent_local_style(path, pool), buf->data);
     }
 
+  /* non-shared repositories never use logical addressing */
+  if (!*max_files_per_dir)
+    *min_log_addressing_rev = SVN_INVALID_REVNUM;
+
   return SVN_NO_ERROR;
 }
 
-/* Write the format number and maximum number of files per directory
-   to a new format file in PATH, possibly expecting to overwrite a
-   previously existing file.
+/* Write the format number, maximum number of files per directory and
+   the addressing scheme to a new format file in PATH, possibly expecting
+   to overwrite a previously existing file.
 
    Use POOL for temporary allocation. */
 svn_error_t *
@@ -359,6 +390,17 @@ svn_fs_fs__write_format(svn_fs_t *fs,
         svn_stringbuf_appendcstr(sb, "layout linear\n");
     }
 
+  if (ffd->format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+    {
+      if (ffd->min_log_addressing_rev == SVN_INVALID_REVNUM)
+        svn_stringbuf_appendcstr(sb, "addressing physical\n");
+      else
+        svn_stringbuf_appendcstr(sb,
+                                 apr_psprintf(pool,
+                                              "addressing logical %ld\n",
+                                              ffd->min_log_addressing_rev));
+    }
+
   /* svn_io_write_version_file() does a load of magic to allow it to
      replace version files that already exist.  We only need to do
      that when we're allowed to overwrite an existing file. */
@@ -625,13 +667,14 @@ svn_fs_fs__open(svn_fs_t *fs, const char
   fs_fs_data_t *ffd = fs->fsap_data;
   apr_file_t *uuid_file;
   int format, max_files_per_dir;
+  svn_revnum_t min_log_addressing_rev;
   char buf[APR_UUID_FORMATTED_LENGTH + 2];
   apr_size_t limit;
 
   fs->path = apr_pstrdup(fs->pool, path);
 
   /* Read the FS format number. */
-  SVN_ERR(read_format(&format, &max_files_per_dir,
+  SVN_ERR(read_format(&format, &max_files_per_dir, &min_log_addressing_rev,
                       path_format(fs, pool), pool));
   SVN_ERR(check_format(format));
 
@@ -692,12 +735,14 @@ upgrade_body(void *baton, apr_pool_t *po
   svn_fs_t *fs = upgrade_baton->fs;
   fs_fs_data_t *ffd = fs->fsap_data;
   int format, max_files_per_dir;
+  svn_revnum_t min_log_addressing_rev;
   const char *format_path = path_format(fs, pool);
   svn_node_kind_t kind;
   svn_boolean_t needs_revprop_shard_cleanup = FALSE;
 
   /* Read the FS format number and max-files-per-dir setting. */
-  SVN_ERR(read_format(&format, &max_files_per_dir, format_path, pool));
+  SVN_ERR(read_format(&format, &max_files_per_dir, &min_log_addressing_rev,
+                      format_path, pool));
   SVN_ERR(check_format(format));
 
   /* If the config file does not exist, create one. */
@@ -766,9 +811,19 @@ upgrade_body(void *baton, apr_pool_t *po
                                                pool));
     }
 
+  if (   format < SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT
+      && max_files_per_dir > 0)
+    {
+      min_log_addressing_rev
+        = (ffd->youngest_rev_cache % max_files_per_dir + 1)
+        * max_files_per_dir;
+    }
+
   /* Bump the format file. */
   ffd->format = SVN_FS_FS__FORMAT_NUMBER;
   ffd->max_files_per_dir = max_files_per_dir;
+  ffd->min_log_addressing_rev = min_log_addressing_rev;
+
   SVN_ERR(svn_fs_fs__write_format(fs, TRUE, pool));
   if (upgrade_baton->notify_func)
     SVN_ERR(upgrade_baton->notify_func(upgrade_baton->notify_baton,
@@ -987,14 +1042,59 @@ svn_fs_fs__create(svn_fs_t *fs,
   /* See if compatibility with older versions was explicitly requested. */
   if (fs->config)
     {
+      svn_version_t *compatible_version;
+      const char *compatible;
+
+      /* This will cause a compiler warning as soon as we merge with
+         the FSX branch.  Remove this when it happens. */
+#define SVN_FS_CONFIG_COMPATIBLE_VERSION ""
+      /* TODO: move this code to fs_utils */
+      
+      /* set compatible version according to generic option */
+      compatible = svn_hash_gets(fs->config, SVN_FS_CONFIG_COMPATIBLE_VERSION);
+      if (compatible)
+        SVN_ERR(svn_version__parse_version_string(&compatible_version,
+                                                  compatible, pool));
+      else
+        compatible_version = apr_pmemdup(pool, svn_subr_version(),
+                                         sizeof(*compatible_version));
+
+      /* we handle SVN 1.x only */
+      SVN_ERR_ASSERT(compatible_version->major == 1);
+
+      /* specific options take precedence */
       if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_4_COMPATIBLE))
-        format = 1;
+        compatible_version->minor = 3;
       else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_5_COMPATIBLE))
-        format = 2;
+        compatible_version->minor = 4;
       else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_6_COMPATIBLE))
-        format = 3;
+        compatible_version->minor = 5;
       else if (svn_hash_gets(fs->config, SVN_FS_CONFIG_PRE_1_8_COMPATIBLE))
-        format = 4;
+        compatible_version->minor = 7;
+
+      /* select format number */
+      switch(compatible_version->minor)
+        {
+          case 1:
+          case 2:
+          case 3: format = 1;
+                  break;
+
+          case 4: format = 2;
+                  break;
+
+          case 5: format = 3;
+                  break;
+
+          case 6:
+          case 7: format = 4;
+                  break;
+
+          case 8: format = 5;
+                  break;
+
+          default:format = SVN_FS_FS__FORMAT_NUMBER;
+        }
     }
   ffd->format = format;
 
@@ -1002,6 +1102,12 @@ svn_fs_fs__create(svn_fs_t *fs,
   if (format >= SVN_FS_FS__MIN_LAYOUT_FORMAT_OPTION_FORMAT)
     ffd->max_files_per_dir = SVN_FS_FS_DEFAULT_MAX_FILES_PER_DIR;
 
+  /* Select the addressing mode depending on the format. */
+  if (format >= SVN_FS_FS__MIN_LOG_ADDRESSING_FORMAT)
+    ffd->min_log_addressing_rev = 0;
+  else
+    ffd->min_log_addressing_rev = SVN_INVALID_REVNUM;
+
   /* Create the revision data directories. */
   if (ffd->max_files_per_dir)
     SVN_ERR(svn_io_make_dir_recursively(svn_fs_fs__path_rev_shard(fs, 0,
@@ -1378,8 +1484,11 @@ svn_fs_fs__info_format(int *fs_format,
     case 6:
       (*supports_version)->minor = 8;
       break;
+    case 7:
+      (*supports_version)->minor = 9;
+      break;
 #ifdef SVN_DEBUG
-# if SVN_FS_FS__FORMAT_NUMBER != 6
+# if SVN_FS_FS__FORMAT_NUMBER != 7
 #  error "Need to add a 'case' statement here"
 # endif
 #endif

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c?rev=1509342&r1=1509341&r2=1509342&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.c Thu Aug  
1 17:36:42 2013
@@ -619,6 +619,15 @@ svn_fs_fs__open_pack_or_rev_file(apr_fil
   return svn_error_trace(err);
 }
 
+svn_boolean_t
+svn_fs_fs__use_log_addressing(svn_fs_t *fs,
+                              svn_revnum_t rev)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  return ffd->min_log_addressing_rev != SVN_INVALID_REVNUM
+      && ffd->min_log_addressing_rev <= rev;
+}
+
 svn_error_t *
 svn_fs_fs__item_offset(apr_off_t *absolute_position,
                        svn_fs_t *fs,

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h?rev=1509342&r1=1509341&r2=1509342&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/util.h Thu Aug  
1 17:36:42 2013
@@ -354,6 +354,11 @@ svn_fs_fs__open_pack_or_rev_file(apr_fil
                                  svn_revnum_t rev,
                                  apr_pool_t *pool);
 
+/* Return TRUE, iff revision REV in FS requires logical addressing. */
+svn_boolean_t
+svn_fs_fs__use_log_addressing(svn_fs_t *fs,
+                              svn_revnum_t rev);
+
 /* For OFFSET within REV in FS, return the position in the respective rev
    or pack file in *ABSOLUTE_POSITION.  Use POOL for allocations. */
 svn_error_t *


Reply via email to