Author: danielsh
Date: Wed Apr 24 20:20:51 2013
New Revision: 1471638

URL: http://svn.apache.org/r1471638
Log:
Redesign the svn_fs_info() API.

* subversion/include/svn_fs.h
  (SVN_FS_FSFS_INFO_SHARDED, SVN_FS_FSFS_INFO_REP_CACHE_PATH,
   SVN_FS_FSFS_INFO_MIN_UNPACKED_REV, svn_fs_info_t): Delete.
  (svn_fs_info, svn_fs_info_dup): Rewrite.
  (svn_fs_fsfs_info_t): New.

* subversion/libsvn_fs/fs-loader.c
  (svn_fs_info, svn_fs_info_dup): Implement as the new signature.

* subversion/libsvn_fs/fs-loader.h
  (fs_library_vtable_t.info_fsap_dup): New vtable member.
  (fs_vtable_t.info_fsap): New vtable member.

* subversion/libsvn_fs_base/fs.c
  (fs_vtable, library_vtable): Provide NULL for the new vtable members.

* subversion/libsvn_fs_fs/fs.c
  (fs_info, fs_info_dup): New functions.
  (fs_vtable, library_vtable): Pass them for the new vtable members.

* subversion/tests/libsvn_fs_fs/fs-pack-test.c
  (test_info): New test.
  (test_funcs): Run it, passing.

Modified:
    subversion/trunk/subversion/include/svn_fs.h
    subversion/trunk/subversion/libsvn_fs/fs-loader.c
    subversion/trunk/subversion/libsvn_fs/fs-loader.h
    subversion/trunk/subversion/libsvn_fs_base/fs.c
    subversion/trunk/subversion/libsvn_fs_fs/fs.c
    subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c

Modified: subversion/trunk/subversion/include/svn_fs.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Wed Apr 24 20:20:51 2013
@@ -2568,68 +2568,72 @@ svn_fs_verify_root(svn_fs_root_t *root,
 
 /**
  * A structure that provides some information about a filesystem.
- * Returned by svn_fs_info().
+ * Returned by svn_fs_info() for #SVN_FS_TYPE_FSFS filesystems.
  *
  * @note Fields may be added to the end of this structure in future
  * versions.  Therefore, users shouldn't allocate structures of this
  * type, to preserve binary compatibility.
  *
- * @since New in 1.8.
+ * @since New in 1.9.
  */
-typedef struct svn_fs_info_t {
+typedef struct svn_fs_fsfs_info_t {
 
-#if 0
-  /* Potential future feature. */
-  svn_boolean_t is_write_locked;
-#endif
-
-  /** Filesystem backend (#fs_type) -specific information.
-   * @see SVN_FS_FSFS_INFO_* */
-  apr_hash_t *fsap_info;
+  /** Filesystem backend (#fs_type), i.e., the string #SVN_FS_TYPE_FSFS. */
+  const char *fs_type;
 
-} svn_fs_info_t;
+  /** Shard size, or 0 if the filesystem is not currently sharded. */
+  int shard_size;
+
+  /** The smallest revision (as #svn_revnum_t) which is not in a pack file.
+   * @note Zero (0) if (but not iff) the format does not support packing. */
+  svn_revnum_t min_unpacked_rev;
+
+  /* ### TODO: information about fsfs.conf? rep-cache.db? write locks? */
+
+  /* If you add fields here, check whether you need to extend svn_fs_info()
+     or svn_fs_info_dup(). */
+} svn_fs_fsfs_info_t;
+
+/** @see svn_fs_info()
+ * @since New in 1.9. */
+typedef struct svn_fs_info_placeholder_t {
+  /** @see svn_fs_type() */
+  const char *fs_type;
+
+  /* Do not add new fields here, to maintain compatibility with the first
+     released version of svn_fs_fsfs_info_t. */
+} svn_fs_info_placeholder_t;
 
 /**
- * Set @a *info to an info struct describing @a fs.
+ * Set @a *fs_info to a struct describing @a fs.  The type of the
+ * struct depends on the backend: for #SVN_FS_TYPE_FSFS, the struct will be
+ * of type #svn_fs_fsfs_info_t; otherwise, the struct is guaranteed to be
+ * (compatible with) #svn_fs_info_placeholder_t.
  *
- * @see #svn_fs_info_t
+ * @see #svn_fs_fsfs_info_t
  *
- * @since New in 1.8.
+ * @since New in 1.9.
  */
 svn_error_t *
-svn_fs_info(const svn_fs_info_t **info,
+svn_fs_info(const svn_fs_info_placeholder_t **fs_info,
             svn_fs_t *fs,
             apr_pool_t *result_pool,
             apr_pool_t *scratch_pool);
 
 /**
- * Return a duplicate of @a info, allocated in @a pool. No part of the new
- * structure will be shared with @a info.
+ * Return a duplicate of @a info, allocated in @a pool. The returned struct
+ * will be of the same type as the passed-in struct, which itself must have
+ * been returned from svn_fs_info() or svn_fs_info_dup().  No part of the new
+ * structure will be shared with @a info (except static string constants).
  *
- * @since New in 1.8.
- */
-svn_fs_info_t *
-svn_fs_info_dup(const svn_fs_info_t *info,
-                apr_pool_t *result_pool);
-
-/** @name FSFS-specific #svn_fs_info_t information.
- * @since New in 1.8.
- * @{
- */
-
-/** Value: shard size (as int), or 0 if the filesystem is
- * not currently sharded. */
-#define SVN_FS_FSFS_INFO_SHARDED "sharded"
-
-/** Value: abspath to rep-cache.db, or absent if that doesn't exist.
- @note Do not modify the db schema or tables!
+ * @see #svn_fs_info_placeholder_t, #svn_fs_fsfs_info_t
+ *
+ * @since New in 1.9.
  */
-#define SVN_FS_FSFS_INFO_REP_CACHE_PATH "rep-cache-path"
-
-/** The smallest revision (as #svn_revnum_t) which is not in a pack file.
- * @note Zero (0) if (but not iff) the format does not support packing. */
-#define SVN_FS_FSFS_INFO_MIN_UNPACKED_REV "min-unpacked-rev"
-/** @} */
+void *
+svn_fs_info_dup(const void *info,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool);
 
 /** @} */
 #endif /* SVN_FS_INFO */

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Wed Apr 24 20:20:51 2013
@@ -1630,21 +1630,40 @@ svn_fs_version(void)
 #ifdef SVN_FS_INFO
 /** info **/
 svn_error_t *
-svn_fs_info(const svn_fs_info_t **info,
+svn_fs_info(const svn_fs_info_placeholder_t **info_p,
             svn_fs_t *fs,
             apr_pool_t *result_pool,
             apr_pool_t *scratch_pool)
 {
-  SVN__NOT_IMPLEMENTED();
+  if (fs->vtable->info_fsap)
+    {
+      SVN_ERR(fs->vtable->info_fsap((const void **)info_p, fs,
+                                    result_pool, scratch_pool));
+    }
+  else
+    {
+      svn_fs_info_placeholder_t *info = apr_palloc(result_pool, sizeof(*info));
+      /* ### Ask the disk(!), since svn_fs_t doesn't cache the answer. */
+      SVN_ERR(svn_fs_type(&info->fs_type, fs->path, result_pool));
+      *info_p = info;
+    }
+  return SVN_NO_ERROR;
 }
 
-svn_fs_info_t *
-svn_fs_info_dup(const svn_fs_info_t *info,
-                apr_pool_t *result_pool)
+void *
+svn_fs_info_dup(const void *info_void,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
-  /* Not implemented. */
-  SVN_ERR_MALFUNCTION_NO_RETURN();
-  return NULL;
+  const svn_fs_info_placeholder_t *info = info_void;
+  fs_library_vtable_t *vtable;
+
+  SVN_ERR(get_library_vtable(&vtable, info->fs_type, scratch_pool));
+  
+  if (vtable->info_fsap_dup)
+    return vtable->info_fsap_dup(info_void, result_pool);
+  else
+    return apr_pmemdup(result_pool, info, sizeof(*info));
 }
 #endif
 

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.h?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.h Wed Apr 24 20:20:51 2013
@@ -131,7 +131,9 @@ typedef struct fs_library_vtable_t
                                                                const char *,
                                                                apr_hash_t *,
                                                                apr_pool_t *));
-
+  /* For svn_fs_info_fsfs_dup(). */
+  void *(*info_fsap_dup)(const void *fsap_info,
+                         apr_pool_t *result_pool);
 } fs_library_vtable_t;
 
 /* This is the type of symbol an FS module defines to fetch the
@@ -221,6 +223,11 @@ typedef struct fs_vtable_t
                                     svn_fs_t *fs,
                                     apr_pool_t *result_pool,
                                     apr_pool_t *scratch_pool);
+  svn_error_t *(*info_fsap)(const void **fsap_info,
+                            svn_fs_t *fs,
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
+  /* info_fsap_dup is in the library vtable. */
   svn_error_t *(*verify_root)(svn_fs_root_t *root,
                               apr_pool_t *pool);
   svn_error_t *(*freeze)(svn_fs_t *fs,

Modified: subversion/trunk/subversion/libsvn_fs_base/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/fs.c?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/fs.c Wed Apr 24 20:20:51 2013
@@ -562,6 +562,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_base__get_locks,
   base_bdb_info_format,
   base_bdb_info_config_files,
+  NULL /* info_fsap */,
   base_bdb_verify_root,
   base_bdb_freeze,
   base_bdb_set_errcall,
@@ -1462,7 +1463,8 @@ static fs_library_vtable_t library_vtabl
   base_bdb_pack,
   base_bdb_logfiles,
   svn_fs_base__id_parse,
-  base_set_svn_fs_open
+  base_set_svn_fs_open,
+  NULL /* info_fsap_dup */
 };
 
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.c?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.c Wed Apr 24 20:20:51 2013
@@ -164,6 +164,21 @@ fs_freeze(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+fs_info(const void **fsfs_info,
+        svn_fs_t *fs,
+        apr_pool_t *result_pool,
+        apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_fs_fsfs_info_t *info = apr_palloc(result_pool, sizeof(*info));
+  info->fs_type = SVN_FS_TYPE_FSFS;
+  info->shard_size = ffd->max_files_per_dir;
+  info->min_unpacked_rev = ffd->min_unpacked_rev;
+  *fsfs_info = info;
+  return SVN_NO_ERROR;
+}
+
 
 
 /* The vtable associated with a specific open filesystem. */
@@ -186,6 +201,7 @@ static fs_vtable_t fs_vtable = {
   svn_fs_fs__get_locks,
   svn_fs_fs__info_format,
   svn_fs_fs__info_config_files,
+  fs_info,
   svn_fs_fs__verify_root,
   fs_freeze,
   fs_set_errcall
@@ -414,6 +430,15 @@ fs_set_svn_fs_open(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+static void *
+fs_info_dup(const void *fsfs_info_void,
+            apr_pool_t *result_pool)
+{
+  /* All fields are either ints or static strings. */
+  const svn_fs_fsfs_info_t *fsfs_info = fsfs_info_void;
+  return apr_pmemdup(result_pool, fsfs_info, sizeof(*fsfs_info));
+}
+
 
 /* Base FS library vtable, used by the FS loader library. */
 
@@ -431,7 +456,8 @@ static fs_library_vtable_t library_vtabl
   fs_pack,
   fs_logfiles,
   NULL /* parse_id */,
-  fs_set_svn_fs_open
+  fs_set_svn_fs_open,
+  fs_info_dup
 };
 
 svn_error_t *

Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=1471638&r1=1471637&r2=1471638&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c Wed Apr 24 
20:20:51 2013
@@ -788,6 +788,50 @@ file_hint_at_shard_boundary(const svn_te
 #undef SHARD_SIZE
 
 /* ------------------------------------------------------------------------ */
+#define REPO_NAME "test-repo-fsfs-info"
+#define SHARD_SIZE 3
+#define MAX_REV 5
+static svn_error_t *
+test_info(const svn_test_opts_t *opts,
+          apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  const svn_fs_fsfs_info_t *fsfs_info;
+  const svn_fs_info_placeholder_t *info;
+
+  SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE,
+                                   pool));
+
+  SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool));
+  SVN_ERR(svn_fs_info(&info, fs, pool, pool));
+  info = svn_fs_info_dup(info, pool, pool);
+
+  SVN_TEST_STRING_ASSERT(opts->fs_type, info->fs_type);
+
+  /* Bail (with success) on known-untestable scenarios */
+  if (strcmp(opts->fs_type, "fsfs") != 0)
+    return SVN_NO_ERROR;
+
+  fsfs_info = (void *)info;
+  if (opts->server_minor_version && (opts->server_minor_version < 6))
+    {
+      SVN_TEST_ASSERT(fsfs_info->shard_size == 0);
+      SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev == 0);
+    }
+  else
+    {
+      SVN_TEST_ASSERT(fsfs_info->shard_size == SHARD_SIZE);
+      SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev
+                      == (MAX_REV + 1) / SHARD_SIZE * SHARD_SIZE);
+    }
+
+  return SVN_NO_ERROR;
+}
+#undef REPO_NAME
+#undef SHARD_SIZE
+#undef MAX_REV
+
+/* ------------------------------------------------------------------------ */
 
 /* The test table.  */
 
@@ -812,5 +856,7 @@ struct svn_test_descriptor_t test_funcs[
                        "recover a fully packed filesystem"),
     SVN_TEST_OPTS_PASS(file_hint_at_shard_boundary,
                        "test file hint at shard boundary"),
+    SVN_TEST_OPTS_PASS(test_info,
+                       "test svn_fs_info"),
     SVN_TEST_NULL
   };


Reply via email to