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/07/25 16:43:45 UTC

svn commit: r1506992 [2/3] - in /subversion/branches/fsfs-format7/subversion: include/ libsvn_fs_fs/

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.c Thu Jul 25 14:43:44 2013
@@ -156,6 +156,303 @@ svn_fs_fs__unparse_revision_trailer(apr_
                                changes_offset);
 }
 
+
+/* Read the next entry in the changes record from file FILE and store
+   the resulting change in *CHANGE_P.  If there is no next record,
+   store NULL there.  Perform all allocations from POOL. */
+static svn_error_t *
+read_change(change_t **change_p,
+            svn_stream_t *stream,
+            apr_pool_t *pool)
+{
+  svn_stringbuf_t *line;
+  svn_boolean_t eof = TRUE;
+  change_t *change;
+  char *str, *last_str, *kind_str;
+  svn_fs_path_change2_t *info;
+
+  /* Default return value. */
+  *change_p = NULL;
+
+  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, pool));
+
+  /* Check for a blank line. */
+  if (eof || (line->len == 0))
+    return SVN_NO_ERROR;
+
+  change = apr_pcalloc(pool, sizeof(*change));
+  info = &change->info;
+  last_str = line->data;
+
+  /* Get the node-id of the change. */
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (str == NULL)
+    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Invalid changes line in rev-file"));
+
+  info->node_rev_id = svn_fs_fs__id_parse(str, strlen(str), pool);
+  if (info->node_rev_id == NULL)
+    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Invalid changes line in rev-file"));
+
+  /* Get the change type. */
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (str == NULL)
+    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Invalid changes line in rev-file"));
+
+  /* Don't bother to check the format number before looking for
+   * node-kinds: just read them if you find them. */
+  info->node_kind = svn_node_unknown;
+  kind_str = strchr(str, '-');
+  if (kind_str)
+    {
+      /* Cap off the end of "str" (the action). */
+      *kind_str = '\0';
+      kind_str++;
+      if (strcmp(kind_str, SVN_FS_FS__KIND_FILE) == 0)
+        info->node_kind = svn_node_file;
+      else if (strcmp(kind_str, SVN_FS_FS__KIND_DIR) == 0)
+        info->node_kind = svn_node_dir;
+      else
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Invalid changes line in rev-file"));
+    }
+
+  if (strcmp(str, ACTION_MODIFY) == 0)
+    {
+      info->change_kind = svn_fs_path_change_modify;
+    }
+  else if (strcmp(str, ACTION_ADD) == 0)
+    {
+      info->change_kind = svn_fs_path_change_add;
+    }
+  else if (strcmp(str, ACTION_DELETE) == 0)
+    {
+      info->change_kind = svn_fs_path_change_delete;
+    }
+  else if (strcmp(str, ACTION_REPLACE) == 0)
+    {
+      info->change_kind = svn_fs_path_change_replace;
+    }
+  else if (strcmp(str, ACTION_RESET) == 0)
+    {
+      info->change_kind = svn_fs_path_change_reset;
+    }
+  else
+    {
+      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                              _("Invalid change kind in rev file"));
+    }
+
+  /* Get the text-mod flag. */
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (str == NULL)
+    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Invalid changes line in rev-file"));
+
+  if (strcmp(str, FLAG_TRUE) == 0)
+    {
+      info->text_mod = TRUE;
+    }
+  else if (strcmp(str, FLAG_FALSE) == 0)
+    {
+      info->text_mod = FALSE;
+    }
+  else
+    {
+      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                              _("Invalid text-mod flag in rev-file"));
+    }
+
+  /* Get the prop-mod flag. */
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (str == NULL)
+    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                            _("Invalid changes line in rev-file"));
+
+  if (strcmp(str, FLAG_TRUE) == 0)
+    {
+      info->prop_mod = TRUE;
+    }
+  else if (strcmp(str, FLAG_FALSE) == 0)
+    {
+      info->prop_mod = FALSE;
+    }
+  else
+    {
+      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                              _("Invalid prop-mod flag in rev-file"));
+    }
+
+  /* Get the changed path. */
+  change->path.len = strlen(last_str);
+  change->path.data = apr_pstrmemdup(pool, last_str, change->path.len);
+
+  /* Read the next line, the copyfrom line. */
+  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, pool));
+  info->copyfrom_known = TRUE;
+  if (eof || line->len == 0)
+    {
+      info->copyfrom_rev = SVN_INVALID_REVNUM;
+      info->copyfrom_path = NULL;
+    }
+  else
+    {
+      last_str = line->data;
+      str = svn_cstring_tokenize(" ", &last_str);
+      if (! str)
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Invalid changes line in rev-file"));
+      info->copyfrom_rev = SVN_STR_TO_REV(str);
+
+      if (! last_str)
+        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                                _("Invalid changes line in rev-file"));
+
+      info->copyfrom_path = apr_pstrdup(pool, last_str);
+    }
+
+  *change_p = change;
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__read_changes(apr_array_header_t **changes,
+                        svn_stream_t *stream,
+                        apr_pool_t *pool)
+{
+  change_t *change;
+
+  /* pre-allocate enough room for most change lists
+     (will be auto-expanded as necessary) */
+  *changes = apr_array_make(pool, 30, sizeof(change_t *));
+
+  SVN_ERR(read_change(&change, stream, pool));
+  while (change)
+    {
+      APR_ARRAY_PUSH(*changes, change_t*) = change;
+      SVN_ERR(read_change(&change, stream, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Write a single change entry, path PATH, change CHANGE, and copyfrom
+   string COPYFROM, into the file specified by FILE.  Only include the
+   node kind field if INCLUDE_NODE_KIND is true.  All temporary
+   allocations are in POOL. */
+static svn_error_t *
+write_change_entry(svn_stream_t *stream,
+                   const char *path,
+                   svn_fs_path_change2_t *change,
+                   svn_boolean_t include_node_kind,
+                   apr_pool_t *pool)
+{
+  const char *idstr, *buf;
+  const char *change_string = NULL;
+  const char *kind_string = "";
+
+  switch (change->change_kind)
+    {
+    case svn_fs_path_change_modify:
+      change_string = ACTION_MODIFY;
+      break;
+    case svn_fs_path_change_add:
+      change_string = ACTION_ADD;
+      break;
+    case svn_fs_path_change_delete:
+      change_string = ACTION_DELETE;
+      break;
+    case svn_fs_path_change_replace:
+      change_string = ACTION_REPLACE;
+      break;
+    case svn_fs_path_change_reset:
+      change_string = ACTION_RESET;
+      break;
+    default:
+      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                               _("Invalid change type %d"),
+                               change->change_kind);
+    }
+
+  if (change->node_rev_id)
+    idstr = svn_fs_fs__id_unparse(change->node_rev_id, pool)->data;
+  else
+    idstr = ACTION_RESET;
+
+  if (include_node_kind)
+    {
+      SVN_ERR_ASSERT(change->node_kind == svn_node_dir
+                     || change->node_kind == svn_node_file);
+      kind_string = apr_psprintf(pool, "-%s",
+                                 change->node_kind == svn_node_dir
+                                 ? SVN_FS_FS__KIND_DIR
+                                  : SVN_FS_FS__KIND_FILE);
+    }
+  buf = apr_psprintf(pool, "%s %s%s %s %s %s\n",
+                     idstr, change_string, kind_string,
+                     change->text_mod ? FLAG_TRUE : FLAG_FALSE,
+                     change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
+                     path);
+
+  SVN_ERR(svn_stream_puts(stream, buf));
+
+  if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
+    {
+      buf = apr_psprintf(pool, "%ld %s", change->copyfrom_rev,
+                         change->copyfrom_path);
+      SVN_ERR(svn_stream_puts(stream, buf));
+    }
+
+  return svn_error_trace(svn_stream_puts(stream, "\n"));
+}
+
+svn_error_t *
+svn_fs_fs__write_changes(svn_stream_t *stream,
+                         svn_fs_t *fs,
+                         apr_hash_t *changes,
+                         svn_boolean_t terminate_list,
+                         apr_pool_t *pool)
+{
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  fs_fs_data_t *ffd = fs->fsap_data;
+  svn_boolean_t include_node_kinds =
+      ffd->format >= SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT;
+  apr_array_header_t *sorted_changed_paths;
+  int i;
+
+  /* For the sake of the repository administrator sort the changes so
+     that the final file is deterministic and repeatable, however the
+     rest of the FSFS code doesn't require any particular order here. */
+  sorted_changed_paths = svn_sort__hash(changes,
+                                        svn_sort_compare_items_lexically, pool);
+
+  /* Write all items to disk in the new order. */
+  for (i = 0; i < sorted_changed_paths->nelts; ++i)
+    {
+      svn_fs_path_change2_t *change;
+      const char *path;
+
+      svn_pool_clear(iterpool);
+
+      change = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).value;
+      path = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).key;
+
+      /* Write out the new entry into the final rev-file. */
+      SVN_ERR(write_change_entry(stream, path, change, include_node_kinds,
+                                 iterpool));
+    }
+
+  if (terminate_list)
+    svn_stream_puts(stream, "\n");
+
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
 /* Given a revision file FILE that has been pre-positioned at the
    beginning of a Node-Rev header block, read in that header block and
    store it in the apr_hash_t HEADERS.  All allocations will be from
@@ -236,7 +533,6 @@ svn_fs_fs__parse_representation(represen
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-
   rep->revision = SVN_STR_TO_REV(str);
 
   /* initialize transaction info (never stored) */
@@ -248,7 +544,7 @@ svn_fs_fs__parse_representation(represen
     {
       if (rep->revision == SVN_INVALID_REVNUM)
         return SVN_NO_ERROR;
-    
+
       return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                               _("Malformed text representation offset line in node-rev"));
     }
@@ -313,8 +609,8 @@ svn_fs_fs__parse_representation(represen
   return SVN_NO_ERROR;
 }
 
-/* Wrap read_rep_offsets_body(), extracting its TXN_ID from our NODEREV_ID,
-   and adding an error message. */
+/* Wrap svn_fs_fs__parse_representation(), extracting its TXN_ID from our
+   NODEREV_ID, and adding an error message. */
 static svn_error_t *
 read_rep_offsets(representation_t **rep_p,
                  char *string,
@@ -538,7 +834,7 @@ svn_fs_fs__unparse_representation(repres
   svn__ui64tobase36(buffer, rep->uniquifier.number);
   return svn_stringbuf_createf
           (pool, "%ld %" APR_OFF_T_FMT " %" SVN_FILESIZE_T_FMT
-           " %" SVN_FILESIZE_T_FMT " %s %s %s/%s",
+           " %" SVN_FILESIZE_T_FMT " %s %s %s/_%s",
            rep->revision, rep->offset, rep->size,
            rep->expanded_size,
            format_digest(rep->md5_digest, svn_checksum_md5, FALSE, pool),
@@ -567,440 +863,143 @@ svn_fs_fs__write_noderev(svn_stream_t *o
                             (noderev->kind == svn_node_file) ?
                             SVN_FS_FS__KIND_FILE : SVN_FS_FS__KIND_DIR));
 
-  if (noderev->predecessor_id)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PRED ": %s\n",
-                              svn_fs_fs__id_unparse(noderev->predecessor_id,
-                                                    pool)->data));
-
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COUNT ": %d\n",
-                            noderev->predecessor_count));
-
-  if (noderev->data_rep)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_TEXT ": %s\n",
-                              svn_fs_fs__unparse_representation
-                                (noderev->data_rep,
-                                 format,
-                                 noderev->kind == svn_node_dir,
-                                 pool)->data));
-
-  if (noderev->prop_rep)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PROPS ": %s\n",
-                              svn_fs_fs__unparse_representation
-                                (noderev->prop_rep, format,
-                                 TRUE, pool)->data));
-
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_CPATH ": %s\n",
-                            noderev->created_path));
-
-  if (noderev->copyfrom_path)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYFROM ": %ld"
-                              " %s\n",
-                              noderev->copyfrom_rev,
-                              noderev->copyfrom_path));
-
-  if ((noderev->copyroot_rev != svn_fs_fs__id_rev(noderev->id)) ||
-      (strcmp(noderev->copyroot_path, noderev->created_path) != 0))
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYROOT ": %ld"
-                              " %s\n",
-                              noderev->copyroot_rev,
-                              noderev->copyroot_path));
-
-  if (noderev->is_fresh_txn_root)
-    SVN_ERR(svn_stream_puts(outfile, HEADER_FRESHTXNRT ": y\n"));
-
-  if (include_mergeinfo)
-    {
-      if (noderev->mergeinfo_count > 0)
-        SVN_ERR(svn_stream_printf(outfile, pool, HEADER_MINFO_CNT ": %"
-                                  APR_INT64_T_FMT "\n",
-                                  noderev->mergeinfo_count));
-
-      if (noderev->has_mergeinfo)
-        SVN_ERR(svn_stream_puts(outfile, HEADER_MINFO_HERE ": y\n"));
-    }
-
-  return svn_stream_puts(outfile, "\n");
-}
-
-svn_error_t *
-svn_fs_fs__read_rep_header(svn_fs_fs__rep_header_t **header,
-                           svn_stream_t *stream,
-                           apr_pool_t *pool)
-{
-  svn_stringbuf_t *buffer;
-  char *str, *last_str;
-  apr_int64_t val;
-  svn_boolean_t eol = FALSE;
-
-  SVN_ERR(svn_stream_readline(stream, &buffer, "\n", &eol, pool));
-
-  *header = apr_pcalloc(pool, sizeof(**header));
-  (*header)->header_size = buffer->len + 1;
-  if (strcmp(buffer->data, REP_PLAIN) == 0)
-    {
-      (*header)->type = svn_fs_fs__rep_plain;
-      return SVN_NO_ERROR;
-    }
-
-  if (strcmp(buffer->data, REP_DELTA) == 0)
-    {
-      /* This is a delta against the empty stream. */
-      (*header)->type = svn_fs_fs__rep_self_delta;
-      return SVN_NO_ERROR;
-    }
-
-  (*header)->type = svn_fs_fs__rep_delta;
-
-  /* We have hopefully a DELTA vs. a non-empty base revision. */
-  last_str = buffer->data;
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (! str || (strcmp(str, REP_DELTA) != 0))
-    goto error;
-
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (! str)
-    goto error;
-  (*header)->base_revision = SVN_STR_TO_REV(str);
-
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (! str)
-    goto error;
-  SVN_ERR(svn_cstring_atoi64(&val, str));
-  (*header)->base_offset = (apr_off_t)val;
-
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (! str)
-    goto error;
-  SVN_ERR(svn_cstring_atoi64(&val, str));
-  (*header)->base_length = (svn_filesize_t)val;
-
-  return SVN_NO_ERROR;
-
- error:
-  return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                           _("Malformed representation header"));
-}
-
-svn_error_t *
-svn_fs_fs__write_rep_header(svn_fs_fs__rep_header_t *header,
-                            svn_stream_t *stream,
-                            apr_pool_t *pool)
-{
-  const char *text;
-  
-  switch (header->type)
-    {
-      case svn_fs_fs__rep_plain:
-        text = REP_PLAIN "\n";
-        break;
-
-      case svn_fs_fs__rep_self_delta:
-        text = REP_DELTA "\n";
-        break;
-
-      default:
-        text = apr_psprintf(pool, REP_DELTA " %ld %" APR_OFF_T_FMT " %"
-                            SVN_FILESIZE_T_FMT "\n",
-                            header->base_revision, header->base_offset,
-                            header->base_length);
-    }
-
-  return svn_error_trace(svn_stream_puts(stream, text));
-}
-
-/* Read the next entry in the changes record from file FILE and store
-   the resulting change in *CHANGE_P.  If there is no next record,
-   store NULL there.  Perform all allocations from POOL. */
-static svn_error_t *
-read_change(change_t **change_p,
-            svn_stream_t *stream,
-            apr_pool_t *pool)
-{
-  svn_stringbuf_t *line;
-  svn_boolean_t eof = TRUE;
-  change_t *change;
-  char *str, *last_str, *kind_str;
-  svn_fs_path_change2_t *info;
-
-  /* Default return value. */
-  *change_p = NULL;
-
-  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, pool));
-
-  /* Check for a blank line. */
-  if (eof || (line->len == 0))
-    return SVN_NO_ERROR;
-
-  change = apr_pcalloc(pool, sizeof(*change));
-  info = &change->info;
-  last_str = line->data;
-
-  /* Get the node-id of the change. */
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  info->node_rev_id = svn_fs_fs__id_parse(str, strlen(str), pool);
-  if (info->node_rev_id == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  /* Get the change type. */
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  /* Don't bother to check the format number before looking for
-   * node-kinds: just read them if you find them. */
-  info->node_kind = svn_node_unknown;
-  kind_str = strchr(str, '-');
-  if (kind_str)
-    {
-      /* Cap off the end of "str" (the action). */
-      *kind_str = '\0';
-      kind_str++;
-      if (strcmp(kind_str, SVN_FS_FS__KIND_FILE) == 0)
-        info->node_kind = svn_node_file;
-      else if (strcmp(kind_str, SVN_FS_FS__KIND_DIR) == 0)
-        info->node_kind = svn_node_dir;
-      else
-        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                                _("Invalid changes line in rev-file"));
-    }
-
-  if (strcmp(str, ACTION_MODIFY) == 0)
-    {
-      info->change_kind = svn_fs_path_change_modify;
-    }
-  else if (strcmp(str, ACTION_ADD) == 0)
-    {
-      info->change_kind = svn_fs_path_change_add;
-    }
-  else if (strcmp(str, ACTION_DELETE) == 0)
-    {
-      info->change_kind = svn_fs_path_change_delete;
-    }
-  else if (strcmp(str, ACTION_REPLACE) == 0)
-    {
-      info->change_kind = svn_fs_path_change_replace;
-    }
-  else if (strcmp(str, ACTION_RESET) == 0)
-    {
-      info->change_kind = svn_fs_path_change_reset;
-    }
-  else
-    {
-      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                              _("Invalid change kind in rev file"));
-    }
-
-  /* Get the text-mod flag. */
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  if (strcmp(str, FLAG_TRUE) == 0)
-    {
-      info->text_mod = TRUE;
-    }
-  else if (strcmp(str, FLAG_FALSE) == 0)
-    {
-      info->text_mod = FALSE;
-    }
-  else
-    {
-      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                              _("Invalid text-mod flag in rev-file"));
-    }
-
-  /* Get the prop-mod flag. */
-  str = svn_cstring_tokenize(" ", &last_str);
-  if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid changes line in rev-file"));
-
-  if (strcmp(str, FLAG_TRUE) == 0)
-    {
-      info->prop_mod = TRUE;
-    }
-  else if (strcmp(str, FLAG_FALSE) == 0)
-    {
-      info->prop_mod = FALSE;
-    }
-  else
-    {
-      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                              _("Invalid prop-mod flag in rev-file"));
-    }
+  if (noderev->predecessor_id)
+    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PRED ": %s\n",
+                              svn_fs_fs__id_unparse(noderev->predecessor_id,
+                                                    pool)->data));
 
-  /* Get the changed path. */
-  change->path.len = strlen(last_str);
-  change->path.data = apr_pstrmemdup(pool, last_str, change->path.len);
+  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COUNT ": %d\n",
+                            noderev->predecessor_count));
 
-  /* Read the next line, the copyfrom line. */
-  SVN_ERR(svn_stream_readline(stream, &line, "\n", &eof, pool));
-  info->copyfrom_known = TRUE;
-  if (eof || line->len == 0)
-    {
-      info->copyfrom_rev = SVN_INVALID_REVNUM;
-      info->copyfrom_path = NULL;
-    }
-  else
-    {
-      last_str = line->data;
-      str = svn_cstring_tokenize(" ", &last_str);
-      if (! str)
-        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                                _("Invalid changes line in rev-file"));
-      info->copyfrom_rev = SVN_STR_TO_REV(str);
+  if (noderev->data_rep)
+    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_TEXT ": %s\n",
+                              svn_fs_fs__unparse_representation
+                                (noderev->data_rep,
+                                 format,
+                                 noderev->kind == svn_node_dir,
+                                 pool)->data));
 
-      if (! last_str)
-        return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                                _("Invalid changes line in rev-file"));
+  if (noderev->prop_rep)
+    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PROPS ": %s\n",
+                              svn_fs_fs__unparse_representation
+                                (noderev->prop_rep, format,
+                                 TRUE, pool)->data));
 
-      info->copyfrom_path = apr_pstrdup(pool, last_str);
-    }
+  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_CPATH ": %s\n",
+                            noderev->created_path));
 
-  *change_p = change;
+  if (noderev->copyfrom_path)
+    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYFROM ": %ld"
+                              " %s\n",
+                              noderev->copyfrom_rev,
+                              noderev->copyfrom_path));
 
-  return SVN_NO_ERROR;
-}
+  if ((noderev->copyroot_rev != svn_fs_fs__id_rev(noderev->id)) ||
+      (strcmp(noderev->copyroot_path, noderev->created_path) != 0))
+    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYROOT ": %ld"
+                              " %s\n",
+                              noderev->copyroot_rev,
+                              noderev->copyroot_path));
 
-svn_error_t *
-svn_fs_fs__read_changes(apr_array_header_t **changes,
-                        svn_stream_t *stream,
-                        apr_pool_t *pool)
-{
-  change_t *change;
+  if (noderev->is_fresh_txn_root)
+    SVN_ERR(svn_stream_puts(outfile, HEADER_FRESHTXNRT ": y\n"));
 
-  /* pre-allocate enough room for most change lists
-     (will be auto-expanded as necessary) */
-  *changes = apr_array_make(pool, 30, sizeof(change_t *));
-  
-  SVN_ERR(read_change(&change, stream, pool));
-  while (change)
+  if (include_mergeinfo)
     {
-      APR_ARRAY_PUSH(*changes, change_t*) = change;
-      SVN_ERR(read_change(&change, stream, pool));
+      if (noderev->mergeinfo_count > 0)
+        SVN_ERR(svn_stream_printf(outfile, pool, HEADER_MINFO_CNT ": %"
+                                  APR_INT64_T_FMT "\n",
+                                  noderev->mergeinfo_count));
+
+      if (noderev->has_mergeinfo)
+        SVN_ERR(svn_stream_puts(outfile, HEADER_MINFO_HERE ": y\n"));
     }
 
-  return SVN_NO_ERROR;
+  return svn_stream_puts(outfile, "\n");
 }
 
-/* Write a single change entry, path PATH, change CHANGE, and copyfrom
-   string COPYFROM, into the file specified by FILE.  Only include the
-   node kind field if INCLUDE_NODE_KIND is true.  All temporary
-   allocations are in POOL. */
-static svn_error_t *
-write_change_entry(svn_stream_t *stream,
-                   const char *path,
-                   svn_fs_path_change2_t *change,
-                   svn_boolean_t include_node_kind,
-                   apr_pool_t *pool)
+svn_error_t *
+svn_fs_fs__read_rep_header(svn_fs_fs__rep_header_t **header,
+                           svn_stream_t *stream,
+                           apr_pool_t *pool)
 {
-  const char *idstr, *buf;
-  const char *change_string = NULL;
-  const char *kind_string = "";
+  svn_stringbuf_t *buffer;
+  char *str, *last_str;
+  apr_int64_t val;
+  svn_boolean_t eol = FALSE;
 
-  switch (change->change_kind)
+  SVN_ERR(svn_stream_readline(stream, &buffer, "\n", &eol, pool));
+
+  *header = apr_pcalloc(pool, sizeof(**header));
+  (*header)->header_size = buffer->len + 1;
+  if (strcmp(buffer->data, REP_PLAIN) == 0)
     {
-    case svn_fs_path_change_modify:
-      change_string = ACTION_MODIFY;
-      break;
-    case svn_fs_path_change_add:
-      change_string = ACTION_ADD;
-      break;
-    case svn_fs_path_change_delete:
-      change_string = ACTION_DELETE;
-      break;
-    case svn_fs_path_change_replace:
-      change_string = ACTION_REPLACE;
-      break;
-    case svn_fs_path_change_reset:
-      change_string = ACTION_RESET;
-      break;
-    default:
-      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
-                               _("Invalid change type %d"),
-                               change->change_kind);
+      (*header)->type = svn_fs_fs__rep_plain;
+      return SVN_NO_ERROR;
     }
 
-  if (change->node_rev_id)
-    idstr = svn_fs_fs__id_unparse(change->node_rev_id, pool)->data;
-  else
-    idstr = ACTION_RESET;
-
-  if (include_node_kind)
+  if (strcmp(buffer->data, REP_DELTA) == 0)
     {
-      SVN_ERR_ASSERT(change->node_kind == svn_node_dir
-                     || change->node_kind == svn_node_file);
-      kind_string = apr_psprintf(pool, "-%s",
-                                 change->node_kind == svn_node_dir
-                                 ? SVN_FS_FS__KIND_DIR
-                                  : SVN_FS_FS__KIND_FILE);
+      /* This is a delta against the empty stream. */
+      (*header)->type = svn_fs_fs__rep_self_delta;
+      return SVN_NO_ERROR;
     }
-  buf = apr_psprintf(pool, "%s %s%s %s %s %s\n",
-                     idstr, change_string, kind_string,
-                     change->text_mod ? FLAG_TRUE : FLAG_FALSE,
-                     change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
-                     path);
 
-  SVN_ERR(svn_stream_puts(stream, buf));
+  (*header)->type = svn_fs_fs__rep_delta;
 
-  if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
-    {
-      buf = apr_psprintf(pool, "%ld %s", change->copyfrom_rev,
-                         change->copyfrom_path);
-      SVN_ERR(svn_stream_puts(stream, buf));
-    }
+  /* We have hopefully a DELTA vs. a non-empty base revision. */
+  last_str = buffer->data;
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (! str || (strcmp(str, REP_DELTA) != 0))
+    goto error;
 
-  return svn_error_trace(svn_stream_puts(stream, "\n"));
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (! str)
+    goto error;
+  (*header)->base_revision = SVN_STR_TO_REV(str);
+
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (! str)
+    goto error;
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  (*header)->base_offset = (apr_off_t)val;
+
+  str = svn_cstring_tokenize(" ", &last_str);
+  if (! str)
+    goto error;
+  SVN_ERR(svn_cstring_atoi64(&val, str));
+  (*header)->base_length = (svn_filesize_t)val;
+
+  return SVN_NO_ERROR;
+
+ error:
+  return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                           _("Malformed representation header"));
 }
 
 svn_error_t *
-svn_fs_fs__write_changes(svn_stream_t *stream,
-                         svn_fs_t *fs,
-                         apr_hash_t *changes,
-                         svn_boolean_t terminate_list,
-                         apr_pool_t *pool)
+svn_fs_fs__write_rep_header(svn_fs_fs__rep_header_t *header,
+                            svn_stream_t *stream,
+                            apr_pool_t *pool)
 {
-  apr_pool_t *iterpool = svn_pool_create(pool);
-  fs_fs_data_t *ffd = fs->fsap_data;
-  svn_boolean_t include_node_kinds =
-      ffd->format >= SVN_FS_FS__MIN_KIND_IN_CHANGED_FORMAT;
-  apr_array_header_t *sorted_changed_paths;
-  int i;
-
-  /* For the sake of the repository administrator sort the changes so
-     that the final file is deterministic and repeatable, however the
-     rest of the FSFS code doesn't require any particular order here. */
-  sorted_changed_paths = svn_sort__hash(changes,
-                                        svn_sort_compare_items_lexically, pool);
-
-  /* Write all items to disk in the new order. */
-  for (i = 0; i < sorted_changed_paths->nelts; ++i)
+  const char *text;
+  
+  switch (header->type)
     {
-      svn_fs_path_change2_t *change;
-      const char *path;
-
-      svn_pool_clear(iterpool);
+      case svn_fs_fs__rep_plain:
+        text = REP_PLAIN "\n";
+        break;
 
-      change = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).value;
-      path = APR_ARRAY_IDX(sorted_changed_paths, i, svn_sort__item_t).key;
+      case svn_fs_fs__rep_self_delta:
+        text = REP_DELTA "\n";
+        break;
 
-      /* Write out the new entry into the final rev-file. */
-      SVN_ERR(write_change_entry(stream, path, change, include_node_kinds,
-                                 iterpool));
+      default:
+        text = apr_psprintf(pool, REP_DELTA " %ld %" APR_OFF_T_FMT " %"
+                            SVN_FILESIZE_T_FMT "\n",
+                            header->base_revision, header->base_offset,
+                            header->base_length);
     }
 
-  if (terminate_list)
-    svn_stream_puts(stream, "\n");
-  
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
+  return svn_error_trace(svn_stream_puts(stream, text));
 }
-

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/low_level.h Thu Jul 25 14:43:44 2013
@@ -29,6 +29,15 @@
 #define SVN_FS_FS__KIND_FILE          "file"
 #define SVN_FS_FS__KIND_DIR           "dir"
 
+/* The functions are grouped as follows:
+ *
+ * - revision trailer
+ * - changed path list
+ * - node revision
+ * - representation (as in "text:" and "props:" lines)
+ * - representation header ("PLAIN" and "DELTA" lines)
+ */
+
 /* Given the last "few" bytes (should be at least 40) of revision REV in
  * TRAILER,  parse the last line and return the offset of the root noderev
  * in *ROOT_OFFSET and the offset of the changed paths list in
@@ -52,24 +61,25 @@ svn_fs_fs__unparse_revision_trailer(apr_
                                     apr_off_t changes_offset,
                                     apr_pool_t *pool);
 
-/* Parse the description of a representation from TEXT and store it
-   into *REP_P.  Allocate *REP_P in POOL. */
+/* Read all the changes from STREAM and store them in *CHANGES.  Do all
+   allocations in POOL. */
 svn_error_t *
-svn_fs_fs__parse_representation(representation_t **rep_p,
-                                svn_stringbuf_t *text,
-                                apr_pool_t *pool);
+svn_fs_fs__read_changes(apr_array_header_t **changes,
+                        svn_stream_t *stream,
+                        apr_pool_t *pool);
 
-/* Return a formatted string, compatible with filesystem format FORMAT,
-   that represents the location of representation REP.  If
-   MUTABLE_REP_TRUNCATED is given, the rep is for props or dir contents,
-   and only a "-1" revision number will be given for a mutable rep.
-   If MAY_BE_CORRUPT is true, guard for NULL when constructing the string.
-   Perform the allocation from POOL.  */
-svn_stringbuf_t *
-svn_fs_fs__unparse_representation(representation_t *rep,
-                                  int format,
-                                  svn_boolean_t mutable_rep_truncated,
-                                  apr_pool_t *pool);
+/* Write the changed path info from CHANGES in filesystem FS to the
+   output stream STREAM.  You may call this function multiple time on
+   the same stream but the last call should set TERMINATE_LIST to write
+   an extra empty line that marks the end of the changed paths list.
+   Perform temporary allocations in POOL.
+ */
+svn_error_t *
+svn_fs_fs__write_changes(svn_stream_t *stream,
+                         svn_fs_t *fs,
+                         apr_hash_t *changes,
+                         svn_boolean_t terminate_list,
+                         apr_pool_t *pool);
 
 /* Read a node-revision from STREAM. Set *NODEREV to the new structure,
    allocated in POOL. */
@@ -88,6 +98,25 @@ svn_fs_fs__write_noderev(svn_stream_t *o
                          svn_boolean_t include_mergeinfo,
                          apr_pool_t *pool);
 
+/* Parse the description of a representation from TEXT and store it
+   into *REP_P.  Allocate *REP_P in POOL. */
+svn_error_t *
+svn_fs_fs__parse_representation(representation_t **rep_p,
+                                svn_stringbuf_t *text,
+                                apr_pool_t *pool);
+
+/* Return a formatted string, compatible with filesystem format FORMAT,
+   that represents the location of representation REP.  If
+   MUTABLE_REP_TRUNCATED is given, the rep is for props or dir contents,
+   and only a "-1" revision number will be given for a mutable rep.
+   If MAY_BE_CORRUPT is true, guard for NULL when constructing the string.
+   Perform the allocation from POOL.  */
+svn_stringbuf_t *
+svn_fs_fs__unparse_representation(representation_t *rep,
+                                  int format,
+                                  svn_boolean_t mutable_rep_truncated,
+                                  apr_pool_t *pool);
+
 /* This type enumerates all forms of representations that we support. */
 typedef enum svn_fs_fs__rep_type_t
 {
@@ -98,10 +127,7 @@ typedef enum svn_fs_fs__rep_type_t
   svn_fs_fs__rep_self_delta,
 
   /* this is a DELTA representation against some base representation */
-  svn_fs_fs__rep_delta,
-
-  /* this is a representation in a star-delta container */
-  svn_fs_fs__rep_container
+  svn_fs_fs__rep_delta
 } svn_fs_fs__rep_type_t;
 
 /* This structure is used to hold the information stored in a representation
@@ -143,24 +169,3 @@ svn_error_t *
 svn_fs_fs__write_rep_header(svn_fs_fs__rep_header_t *header,
                             svn_stream_t *stream,
                             apr_pool_t *pool);
-
-/* Read all the changes from STREAM and store them in *CHANGES.  Do all
-   allocations in POOL. */
-svn_error_t *
-svn_fs_fs__read_changes(apr_array_header_t **changes,
-                        svn_stream_t *stream,
-                        apr_pool_t *pool);
-
-/* Write the changed path info from CHANGES in filesystem FS to the
-   output stream STREAM.  You may call this function multiple time on
-   the same stream but the last call should set TERMINATE_LIST to write
-   an extra empty line that marks the end of the changed paths list.
-   Perform temporary allocations in POOL.
- */
-svn_error_t *
-svn_fs_fs__write_changes(svn_stream_t *stream,
-                         svn_fs_t *fs,
-                         apr_hash_t *changes,
-                         svn_boolean_t terminate_list,
-                         apr_pool_t *pool);
-

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=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c Thu Jul 25 14:43:44 2013
@@ -31,11 +31,10 @@
 #include "fs_fs.h"
 #include "pack.h"
 #include "util.h"
+#include "id.h"
+#include "low_level.h"
 #include "revprops.h"
 #include "transaction.h"
-#include "index.h"
-#include "low_level.h"
-#include "cached_data.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -52,8 +51,10 @@ compare_dir_entries_format6(const svn_so
   const svn_fs_dirent_t *lhs = (const svn_fs_dirent_t *) a->value;
   const svn_fs_dirent_t *rhs = (const svn_fs_dirent_t *) b->value;
 
-  const svn_fs_fs__id_part_t *lhs_rev_item = svn_fs_fs__id_rev_item(lhs->id);
-  const svn_fs_fs__id_part_t *rhs_rev_item = svn_fs_fs__id_rev_item(rhs->id);
+  const svn_fs_fs__id_part_t *lhs_rev_item
+    = svn_fs_fs__id_rev_offset(lhs->id);
+  const svn_fs_fs__id_part_t *rhs_rev_item
+    = svn_fs_fs__id_rev_offset(rhs->id);
 
   /* decreasing ("reverse") order on revs */
   if (lhs_rev_item->revision != rhs_rev_item->revision)
@@ -118,8 +119,10 @@ svn_fs_fs__get_packed_offset(apr_off_t *
 
   /* Open the manifest file. */
   SVN_ERR(svn_stream_open_readonly(&manifest_stream,
-                 svn_fs_fs__path_rev_packed(fs, rev, PATH_MANIFEST, pool),
-                 pool, pool));
+                                   svn_fs_fs__path_rev_packed(fs, rev,
+                                                              PATH_MANIFEST,
+                                                              pool),
+                                   pool, pool));
 
   /* While we're here, let's just read the entire manifest file into an array,
      so we can cache the entire thing. */
@@ -331,17 +334,19 @@ pack_shard(const char *revs_dir,
                            apr_psprintf(pool, "%" APR_INT64_T_FMT, shard),
                            pool);
 
-      SVN_ERR(pack_revprops_shard(revprops_pack_file_dir, revprops_shard_path,
-                                  shard, max_files_per_dir,
-                                  (int)(0.9 * max_pack_size),
-                                  compression_level,
-                                  cancel_func, cancel_baton, pool));
+      SVN_ERR(svn_fs_fs__pack_revprops_shard(revprops_pack_file_dir,
+                                             revprops_shard_path,
+                                             shard, max_files_per_dir,
+                                             (int)(0.9 * max_pack_size),
+                                             compression_level,
+                                             cancel_func, cancel_baton,
+                                             pool));
     }
 
   /* Update the min-unpacked-rev file to reflect our newly packed shard. */
   SVN_ERR(svn_fs_fs__write_revnum_file(fs,
-                            (svn_revnum_t)((shard + 1) * max_files_per_dir),
-                            pool));
+                          (svn_revnum_t)((shard + 1) * max_files_per_dir),
+                          pool));
   ffd->min_unpacked_rev = (svn_revnum_t)((shard + 1) * max_files_per_dir);
 
   /* Finally, remove the existing shard directories.
@@ -355,9 +360,12 @@ pack_shard(const char *revs_dir,
       apr_int64_t to_cleanup = shard;
       do
         {
-          SVN_ERR(delete_revprops_shard(revprops_shard_path,
-                                        to_cleanup, max_files_per_dir,
-                                        cancel_func, cancel_baton, pool));
+          SVN_ERR(svn_fs_fs__delete_revprops_shard(revprops_shard_path,
+                                                   to_cleanup,
+                                                   max_files_per_dir,
+                                                   cancel_func,
+                                                   cancel_baton,
+                                                   pool));
 
           /* If the previous shard exists, clean it up as well.
              Don't try to clean up shard 0 as it we can't tell quickly
@@ -399,7 +407,7 @@ struct pack_baton
      extension, on not having to use a retry when calling
      svn_fs_fs__path_rev_absolute() and friends).  If you add a call
      to this function, consider whether you have to call
-     update_min_unpacked_rev().
+     svn_fs_fs__update_min_unpacked_rev().
      See this thread: http://thread.gmane.org/1291206765.3782.3309.camel@edith
  */
 static svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.h Thu Jul 25 14:43:44 2013
@@ -27,6 +27,7 @@
 
 /* Possibly pack the repository at PATH.  This just take full shards, and
    combines all the revision files into a single one, with a manifest header.
+   If given, NOTIFY_FUNC will be called with NOTIFY_BATON to report progress.
    Use optional CANCEL_FUNC/CANCEL_BATON for cancellation support.
 
    Existing filesystem references need not change.  */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/recovery.c Thu Jul 25 14:43:44 2013
@@ -29,10 +29,8 @@
 #include "low_level.h"
 #include "rep-cache.h"
 #include "revprops.h"
-#include "transaction.h"
 #include "util.h"
 #include "cached_data.h"
-#include "index.h"
 
 #include "../libsvn_fs/fs-loader.h"
 
@@ -109,7 +107,7 @@ struct recover_read_from_file_baton
 {
   svn_stream_t *stream;
   apr_pool_t *pool;
-  apr_size_t remaining;
+  apr_off_t remaining;
 };
 
 /* A stream read handler used by recover_find_max_ids() below.
@@ -128,8 +126,8 @@ read_handler_recover(void *baton, char *
       return SVN_NO_ERROR;
     }
 
-  if (bytes_to_read > b->remaining)
-    bytes_to_read = b->remaining;
+  if ((apr_int64_t)bytes_to_read > (apr_int64_t)b->remaining)
+    bytes_to_read = (apr_size_t)b->remaining;
   b->remaining -= bytes_to_read;
 
   return svn_stream_read(b->stream, buffer, &bytes_to_read);
@@ -146,8 +144,10 @@ read_handler_recover(void *baton, char *
 
    Perform temporary allocation in POOL. */
 static svn_error_t *
-recover_find_max_ids(svn_fs_t *fs, svn_revnum_t rev,
-                     apr_file_t *rev_file, apr_off_t offset,
+recover_find_max_ids(svn_fs_t *fs,
+                     svn_revnum_t rev,
+                     apr_file_t *rev_file,
+                     apr_off_t offset,
                      apr_uint64_t *max_node_id,
                      apr_uint64_t *max_copy_id,
                      apr_pool_t *pool)
@@ -159,13 +159,10 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
   apr_hash_index_t *hi;
   apr_pool_t *iterpool;
   node_revision_t *noderev;
-  apr_uint32_t sub_item;
 
+  baton.stream = svn_stream_from_aprfile2(rev_file, TRUE, pool);
   SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, pool));
-  SVN_ERR(svn_fs_fs__read_noderev(&noderev,
-                                  svn_stream_from_aprfile2(rev_file, TRUE,
-                                                           pool),
-                                  pool));
+  SVN_ERR(svn_fs_fs__read_noderev(&noderev, baton.stream, pool));
 
   /* Check that this is a directory.  It should be. */
   if (noderev->kind != svn_node_dir)
@@ -185,12 +182,8 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
 
   /* We could use get_dir_contents(), but this is much cheaper.  It does
      rely on directory entries being stored as PLAIN reps, though. */
-  SVN_ERR(svn_fs_fs__item_offset(&offset, &sub_item, fs, rev, NULL,
-                                 noderev->data_rep->offset, pool));
-  SVN_ERR_ASSERT(sub_item == 0);
+  offset = noderev->data_rep->offset;
   SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, pool));
-
-  baton.stream = svn_stream_from_aprfile2(rev_file, TRUE, pool);
   SVN_ERR(svn_fs_fs__read_rep_header(&header, baton.stream, pool));
   if (header->type != svn_fs_fs__rep_plain)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -200,7 +193,7 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
   /* Now create a stream that's allowed to read only as much data as is
      stored in the representation. */
   baton.pool = pool;
-  baton.remaining = (apr_size_t) noderev->data_rep->expanded_size;
+  baton.remaining = noderev->data_rep->expanded_size;
   stream = svn_stream_create(&baton, pool);
   svn_stream_set_read(stream, read_handler_recover);
 
@@ -218,7 +211,7 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
       char *str;
       svn_node_kind_t kind;
       svn_fs_id_t *id;
-      const svn_fs_fs__id_part_t *rev_item;
+      const svn_fs_fs__id_part_t *rev_offset;
       apr_uint64_t node_id, copy_id;
       apr_off_t child_dir_offset;
       const svn_string_t *path = svn__apr_hash_index_val(hi);
@@ -249,8 +242,8 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
 
       id = svn_fs_fs__id_parse(str, strlen(str), iterpool);
 
-      rev_item = svn_fs_fs__id_rev_item(id);
-      if (rev_item->revision != rev)
+      rev_offset = svn_fs_fs__id_rev_offset(id);
+      if (rev_offset->revision != rev)
         {
           /* If the node wasn't modified in this revision, we've already
              checked the node and copy id. */
@@ -268,14 +261,7 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
       if (kind == svn_node_file)
         continue;
 
-      SVN_ERR(svn_fs_fs__item_offset(&child_dir_offset,
-                                     &sub_item,
-                                     fs,
-                                     rev_item->revision,
-                                     NULL,
-                                     rev_item->number,
-                                     iterpool));
-      SVN_ERR_ASSERT(sub_item == 0);
+      child_dir_offset = rev_offset->number;
       SVN_ERR(recover_find_max_ids(fs, rev, rev_file, child_dir_offset,
                                    max_node_id, max_copy_id, iterpool));
     }
@@ -285,14 +271,14 @@ recover_find_max_ids(svn_fs_t *fs, svn_r
 }
 
 svn_error_t *
-svn_fs_fs__find_max_ids(svn_fs_t *fs, svn_revnum_t youngest,
+svn_fs_fs__find_max_ids(svn_fs_t *fs,
+                        svn_revnum_t youngest,
                         apr_uint64_t *max_node_id,
                         apr_uint64_t *max_copy_id,
                         apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   apr_off_t root_offset;
-  apr_uint32_t sub_item;
   apr_file_t *rev_file;
   svn_fs_id_t *root_id;
 
@@ -300,12 +286,7 @@ svn_fs_fs__find_max_ids(svn_fs_t *fs, sv
   SVN_ERR_ASSERT(ffd->format < SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT);
 
   SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, youngest, pool));
-  SVN_ERR(svn_fs_fs__item_offset(&root_offset, &sub_item, fs,
-                                 svn_fs_fs__id_rev(root_id),
-                                 NULL,
-                                 svn_fs_fs__id_item(root_id),
-                                 pool));
-  SVN_ERR_ASSERT(sub_item == 0);
+  root_offset = svn_fs_fs__id_offset(root_id);
 
   SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, youngest, pool));
   SVN_ERR(recover_find_max_ids(fs, youngest, rev_file, root_offset,
@@ -338,7 +319,7 @@ recover_body(void *baton, apr_pool_t *po
   svn_node_kind_t youngest_revprops_kind;
 
   /* Lose potentially corrupted data in temp files */
-  SVN_ERR(cleanup_revprop_namespace(fs));
+  SVN_ERR(svn_fs_fs__cleanup_revprop_namespace(fs));
 
   /* We need to know the largest revision in the filesystem. */
   SVN_ERR(recover_get_largest_revision(fs, &max_rev, pool));
@@ -419,7 +400,7 @@ recover_body(void *baton, apr_pool_t *po
   if (youngest_revprops_kind == svn_node_none)
     {
       svn_boolean_t missing = TRUE;
-      if (!packed_revprop_available(&missing, fs, max_rev, pool))
+      if (!svn_fs_fs__packed_revprop_available(&missing, fs, max_rev, pool))
         {
           if (missing)
             {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/rep-cache-db.sql
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/rep-cache-db.sql (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/rep-cache-db.sql Thu Jul 25 14:43:44 2013
@@ -22,8 +22,6 @@
  */
 
 -- STMT_CREATE_SCHEMA
-PRAGMA PAGE_SIZE = 4096;
-
 /* A table mapping representation hashes to locations in a rev file. */
 CREATE TABLE rep_cache (
   hash TEXT NOT NULL PRIMARY KEY,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c Thu Jul 25 14:43:44 2013
@@ -29,7 +29,6 @@
 #include "fs_fs.h"
 #include "revprops.h"
 #include "util.h"
-#include "transaction.h"
 
 #include "private/svn_subr_private.h"
 #include "private/svn_string_private.h"
@@ -49,12 +48,12 @@
 #define ATOMIC_REVPROP_NAMESPACE  "rev-prop-atomics"
 
 svn_error_t *
-upgrade_pack_revprops(svn_fs_t *fs,
-                      svn_fs_upgrade_notify_t notify_func,
-                      void *notify_baton,
-                      svn_cancel_func_t cancel_func,
-                      void *cancel_baton,
-                      apr_pool_t *scratch_pool)
+svn_fs_fs__upgrade_pack_revprops(svn_fs_t *fs,
+                                 svn_fs_upgrade_notify_t notify_func,
+                                 void *notify_baton,
+                                 svn_cancel_func_t cancel_func,
+                                 void *cancel_baton,
+                                 apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   const char *revprops_shard_path;
@@ -82,11 +81,13 @@ upgrade_pack_revprops(svn_fs_t *fs,
                        apr_psprintf(iterpool, "%" APR_INT64_T_FMT, shard),
                        iterpool);
 
-      SVN_ERR(pack_revprops_shard(revprops_pack_file_dir, revprops_shard_path,
-                                  shard, ffd->max_files_per_dir,
-                                  (int)(0.9 * ffd->revprop_pack_size),
-                                  compression_level,
-                                  cancel_func, cancel_baton, iterpool));
+      SVN_ERR(svn_fs_fs__pack_revprops_shard(revprops_pack_file_dir,
+                                             revprops_shard_path,
+                                             shard, ffd->max_files_per_dir,
+                                             (int)(0.9 * ffd->revprop_pack_size),
+                                             compression_level,
+                                             cancel_func, cancel_baton,
+                                             iterpool));
       if (notify_func)
         SVN_ERR(notify_func(notify_baton, shard,
                             svn_fs_upgrade_pack_revprops, iterpool));
@@ -100,12 +101,12 @@ upgrade_pack_revprops(svn_fs_t *fs,
 }
 
 svn_error_t *
-upgrade_cleanup_pack_revprops(svn_fs_t *fs,
-                              svn_fs_upgrade_notify_t notify_func,
-                              void *notify_baton,
-                              svn_cancel_func_t cancel_func,
-                              void *cancel_baton,
-                              apr_pool_t *scratch_pool)
+svn_fs_fs__upgrade_cleanup_pack_revprops(svn_fs_t *fs,
+                                         svn_fs_upgrade_notify_t notify_func,
+                                         void *notify_baton,
+                                         svn_cancel_func_t cancel_func,
+                                         void *cancel_baton,
+                                         apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   const char *revprops_shard_path;
@@ -123,9 +124,11 @@ upgrade_cleanup_pack_revprops(svn_fs_t *
       revprops_shard_path = svn_dirent_join(revsprops_dir,
                        apr_psprintf(iterpool, "%" APR_INT64_T_FMT, shard),
                        iterpool);
-      SVN_ERR(delete_revprops_shard(revprops_shard_path,
-                                    shard, ffd->max_files_per_dir,
-                                    cancel_func, cancel_baton, iterpool));
+      SVN_ERR(svn_fs_fs__delete_revprops_shard(revprops_shard_path,
+                                               shard,
+                                               ffd->max_files_per_dir,
+                                               cancel_func, cancel_baton,
+                                               iterpool));
       if (notify_func)
         SVN_ERR(notify_func(notify_baton, shard,
                             svn_fs_upgrade_cleanup_revprops, iterpool));
@@ -231,9 +234,9 @@ read_revprop_generation_file(apr_int64_t
 /* Write the CURRENT revprop generation to disk for repository FS.
  */
 svn_error_t *
-write_revprop_generation_file(svn_fs_t *fs,
-                              apr_int64_t current,
-                              apr_pool_t *pool)
+svn_fs_fs__write_revprop_generation_file(svn_fs_t *fs,
+                                         apr_int64_t current,
+                                         apr_pool_t *pool)
 {
   char buf[SVN_INT64_BUFFER_SIZE];
   apr_size_t len = svn__i64toa(buf, current);
@@ -261,9 +264,8 @@ ensure_revprop_namespace(svn_fs_t *fs)
     : SVN_NO_ERROR;
 }
 
-/* Make sure the revprop_namespace member in FS is set. */
 svn_error_t *
-cleanup_revprop_namespace(svn_fs_t *fs)
+svn_fs_fs__cleanup_revprop_namespace(svn_fs_t *fs)
 {
   const char *name = svn_dirent_join(fs->path,
                                      ATOMIC_REVPROP_NAMESPACE,
@@ -533,7 +535,7 @@ end_revprop_change(svn_fs_t *fs, apr_poo
    * state such that we can be sure the be the only ones to write that
    * file.
    */
-  return write_revprop_generation_file(fs, current, pool);
+  return svn_fs_fs__write_revprop_generation_file(fs, current, pool);
 }
 
 /* Container for all data required to access the packed revprop file
@@ -643,14 +645,14 @@ read_non_packed_revprop(apr_hash_t **pro
 
   for (i = 0;
        i < SVN_FS_FS__RECOVERABLE_RETRY_COUNT && !missing && !content;
-  ++i)
+       ++i)
     {
       svn_pool_clear(iterpool);
       SVN_ERR(svn_fs_fs__try_stringbuf_from_file(&content,
-                               &missing,
-                               svn_fs_fs__path_revprops(fs, rev, iterpool),
-                               i + 1 < SVN_FS_FS__RECOVERABLE_RETRY_COUNT,
-                               iterpool));
+                              &missing,
+                              svn_fs_fs__path_revprops(fs, rev, iterpool),
+                              i + 1 < SVN_FS_FS__RECOVERABLE_RETRY_COUNT ,
+                              iterpool));
     }
 
   if (content)
@@ -680,7 +682,8 @@ get_revprop_packname(svn_fs_t *fs,
   /* read content of the manifest file */
   revprops->folder
     = svn_fs_fs__path_revprops_pack_shard(fs, revprops->revision, pool);
-  manifest_file_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
+  manifest_file_path
+    = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
 
   SVN_ERR(svn_fs_fs__read_content(&content, manifest_file_path, pool));
 
@@ -901,10 +904,10 @@ read_pack_revprop(packed_revprops_t **re
  * Allocations will be done in POOL.
  */
 svn_error_t *
-get_revision_proplist(apr_hash_t **proplist_p,
-                      svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_pool_t *pool)
+svn_fs_fs__get_revision_proplist(apr_hash_t **proplist_p,
+                                 svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   apr_int64_t generation = 0;
@@ -1366,10 +1369,10 @@ write_packed_revprop(const char **final_
 /* Set the revision property list of revision REV in filesystem FS to
    PROPLIST.  Use POOL for temporary allocations. */
 svn_error_t *
-set_revision_proplist(svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_hash_t *proplist,
-                      apr_pool_t *pool)
+svn_fs_fs__set_revision_proplist(svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_hash_t *proplist,
+                                 apr_pool_t *pool)
 {
   svn_boolean_t is_packed;
   svn_boolean_t bump_generation = FALSE;
@@ -1395,7 +1398,8 @@ set_revision_proplist(svn_fs_t *fs,
         {
           svn_node_kind_t kind;
           SVN_ERR(svn_io_check_path(svn_fs_fs__path_revprops(fs, rev, pool),
-                                    &kind, pool));
+                                    &kind,
+                                    pool));
           bump_generation = kind != svn_node_none;
         }
     }
@@ -1427,10 +1431,10 @@ set_revision_proplist(svn_fs_t *fs,
  * Set *MISSING, if the reason is a missing manifest or pack file.
  */
 svn_boolean_t
-packed_revprop_available(svn_boolean_t *missing,
-                         svn_fs_t *fs,
-                         svn_revnum_t revision,
-                         apr_pool_t *pool)
+svn_fs_fs__packed_revprop_available(svn_boolean_t *missing,
+                                    svn_fs_t *fs,
+                                    svn_revnum_t revision,
+                                    apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
   svn_stringbuf_t *content = NULL;
@@ -1497,34 +1501,18 @@ packed_revprop_available(svn_boolean_t *
 
 /****** Packing FSFS shards *********/
 
-/* Copy revprop files for revisions [START_REV, END_REV) from SHARD_PATH
- * to the pack file at PACK_FILE_NAME in PACK_FILE_DIR.
- *
- * The file sizes have already been determined and written to SIZES.
- * Please note that this function will be executed while the filesystem
- * has been locked and that revprops files will therefore not be modified
- * while the pack is in progress.
- *
- * COMPRESSION_LEVEL defines how well the resulting pack file shall be
- * compressed or whether is shall be compressed at all.  TOTAL_SIZE is
- * a hint on which initial buffer size we should use to hold the pack file
- * content.
- *
- * CANCEL_FUNC and CANCEL_BATON are used as usual. Temporary allocations
- * are done in SCRATCH_POOL.
- */
 svn_error_t *
-copy_revprops(const char *pack_file_dir,
-              const char *pack_filename,
-              const char *shard_path,
-              svn_revnum_t start_rev,
-              svn_revnum_t end_rev,
-              apr_array_header_t *sizes,
-              apr_size_t total_size,
-              int compression_level,
-              svn_cancel_func_t cancel_func,
-              void *cancel_baton,
-              apr_pool_t *scratch_pool)
+svn_fs_fs__copy_revprops(const char *pack_file_dir,
+                         const char *pack_filename,
+                         const char *shard_path,
+                         svn_revnum_t start_rev,
+                         svn_revnum_t end_rev,
+                         apr_array_header_t *sizes,
+                         apr_size_t total_size,
+                         int compression_level,
+                         svn_cancel_func_t cancel_func,
+                         void *cancel_baton,
+                         apr_pool_t *scratch_pool)
 {
   svn_stream_t *pack_stream;
   apr_file_t *pack_file;
@@ -1584,27 +1572,16 @@ copy_revprops(const char *pack_file_dir,
   return SVN_NO_ERROR;
 }
 
-/* For the revprop SHARD at SHARD_PATH with exactly MAX_FILES_PER_DIR
- * revprop files in it, create a packed shared at PACK_FILE_DIR.
- *
- * COMPRESSION_LEVEL defines how well the resulting pack file shall be
- * compressed or whether is shall be compressed at all.  Individual pack
- * file containing more than one revision will be limited to a size of
- * MAX_PACK_SIZE bytes before compression.
- *
- * CANCEL_FUNC and CANCEL_BATON are used in the usual way.  Temporary
- * allocations are done in SCRATCH_POOL.
- */
 svn_error_t *
-pack_revprops_shard(const char *pack_file_dir,
-                    const char *shard_path,
-                    apr_int64_t shard,
-                    int max_files_per_dir,
-                    apr_off_t max_pack_size,
-                    int compression_level,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool)
+svn_fs_fs__pack_revprops_shard(const char *pack_file_dir,
+                               const char *shard_path,
+                               apr_int64_t shard,
+                               int max_files_per_dir,
+                               apr_off_t max_pack_size,
+                               int compression_level,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               apr_pool_t *scratch_pool)
 {
   const char *manifest_file_path, *pack_filename = NULL;
   svn_stream_t *manifest_stream;
@@ -1658,10 +1635,11 @@ pack_revprops_shard(const char *pack_fil
       if (sizes->nelts != 0 &&
           total_size + SVN_INT64_BUFFER_SIZE + finfo.size > max_pack_size)
         {
-          SVN_ERR(copy_revprops(pack_file_dir, pack_filename, shard_path,
-                                start_rev, rev-1, sizes, (apr_size_t)total_size,
-                                compression_level, cancel_func, cancel_baton,
-                                iterpool));
+          SVN_ERR(svn_fs_fs__copy_revprops(pack_file_dir, pack_filename,
+                                           shard_path, start_rev, rev-1,
+                                           sizes, (apr_size_t)total_size,
+                                           compression_level, cancel_func,
+                                           cancel_baton, iterpool));
 
           /* next pack file starts empty again */
           apr_array_clear(sizes);
@@ -1684,10 +1662,11 @@ pack_revprops_shard(const char *pack_fil
 
   /* write the last pack file */
   if (sizes->nelts != 0)
-    SVN_ERR(copy_revprops(pack_file_dir, pack_filename, shard_path,
-                          start_rev, rev-1, sizes, (apr_size_t)total_size,
-                          compression_level, cancel_func, cancel_baton,
-                          iterpool));
+    SVN_ERR(svn_fs_fs__copy_revprops(pack_file_dir, pack_filename,
+                                     shard_path, start_rev, rev-1,
+                                     sizes, (apr_size_t)total_size,
+                                     compression_level, cancel_func,
+                                     cancel_baton, iterpool));
 
   /* flush the manifest file and update permissions */
   SVN_ERR(svn_stream_close(manifest_stream));
@@ -1698,20 +1677,13 @@ pack_revprops_shard(const char *pack_fil
   return SVN_NO_ERROR;
 }
 
-/* Delete the non-packed revprop SHARD at SHARD_PATH with exactly
- * MAX_FILES_PER_DIR revprop files in it.  If this is shard 0, keep the
- * revprop file for revision 0.
- *
- * CANCEL_FUNC and CANCEL_BATON are used in the usual way.  Temporary
- * allocations are done in SCRATCH_POOL.
- */
 svn_error_t *
-delete_revprops_shard(const char *shard_path,
-                      apr_int64_t shard,
-                      int max_files_per_dir,
-                      svn_cancel_func_t cancel_func,
-                      void *cancel_baton,
-                      apr_pool_t *scratch_pool)
+svn_fs_fs__delete_revprops_shard(const char *shard_path,
+                                 apr_int64_t shard,
+                                 int max_files_per_dir,
+                                 svn_cancel_func_t cancel_func,
+                                 void *cancel_baton,
+                                 apr_pool_t *scratch_pool)
 {
   if (shard == 0)
     {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h Thu Jul 25 14:43:44 2013
@@ -25,13 +25,13 @@
 /* Write the CURRENT revprop generation to disk for repository FS.
  */
 svn_error_t *
-write_revprop_generation_file(svn_fs_t *fs,
-                              apr_int64_t current,
-                              apr_pool_t *pool);
+svn_fs_fs__write_revprop_generation_file(svn_fs_t *fs,
+                                         apr_int64_t current,
+                                         apr_pool_t *pool);
 
 /* Make sure the revprop_namespace member in FS is set. */
 svn_error_t *
-cleanup_revprop_namespace(svn_fs_t *fs);
+svn_fs_fs__cleanup_revprop_namespace(svn_fs_t *fs);
 
 /* In the filesystem FS, pack all revprop shards up to min_unpacked_rev.
  * 
@@ -44,12 +44,12 @@ cleanup_revprop_namespace(svn_fs_t *fs);
  * used in the usual way.  Temporary allocations are done in SCRATCH_POOL.
  */
 svn_error_t *
-upgrade_pack_revprops(svn_fs_t *fs,
-                      svn_fs_upgrade_notify_t notify_func,
-                      void *notify_baton,
-                      svn_cancel_func_t cancel_func,
-                      void *cancel_baton,
-                      apr_pool_t *scratch_pool);
+svn_fs_fs__upgrade_pack_revprops(svn_fs_t *fs,
+                                 svn_fs_upgrade_notify_t notify_func,
+                                 void *notify_baton,
+                                 svn_cancel_func_t cancel_func,
+                                 void *cancel_baton,
+                                 apr_pool_t *scratch_pool);
 
 /* In the filesystem FS, remove all non-packed revprop shards up to
  * min_unpacked_rev.  Temporary allocations are done in SCRATCH_POOL.
@@ -62,30 +62,30 @@ upgrade_pack_revprops(svn_fs_t *fs,
  * See upgrade_pack_revprops for more info.
  */
 svn_error_t *
-upgrade_cleanup_pack_revprops(svn_fs_t *fs,
-                              svn_fs_upgrade_notify_t notify_func,
-                              void *notify_baton,
-                              svn_cancel_func_t cancel_func,
-                              void *cancel_baton,
-                              apr_pool_t *scratch_pool);
+svn_fs_fs__upgrade_cleanup_pack_revprops(svn_fs_t *fs,
+                                         svn_fs_upgrade_notify_t notify_func,
+                                         void *notify_baton,
+                                         svn_cancel_func_t cancel_func,
+                                         void *cancel_baton,
+                                         apr_pool_t *scratch_pool);
 
 /* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
  *
  * Allocations will be done in POOL.
  */
 svn_error_t *
-get_revision_proplist(apr_hash_t **proplist_p,
-                      svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_pool_t *pool);
+svn_fs_fs__get_revision_proplist(apr_hash_t **proplist_p,
+                                 svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_pool_t *pool);
 
 /* Set the revision property list of revision REV in filesystem FS to
    PROPLIST.  Use POOL for temporary allocations. */
 svn_error_t *
-set_revision_proplist(svn_fs_t *fs,
-                      svn_revnum_t rev,
-                      apr_hash_t *proplist,
-                      apr_pool_t *pool);
+svn_fs_fs__set_revision_proplist(svn_fs_t *fs,
+                                 svn_revnum_t rev,
+                                 apr_hash_t *proplist,
+                                 apr_pool_t *pool);
 
 
 /* Return TRUE, if for REVISION in FS, we can find the revprop pack file.
@@ -93,10 +93,10 @@ set_revision_proplist(svn_fs_t *fs,
  * Set *MISSING, if the reason is a missing manifest or pack file. 
  */
 svn_boolean_t
-packed_revprop_available(svn_boolean_t *missing,
-                         svn_fs_t *fs,
-                         svn_revnum_t revision,
-                         apr_pool_t *pool);
+svn_fs_fs__packed_revprop_available(svn_boolean_t *missing,
+                                    svn_fs_t *fs,
+                                    svn_revnum_t revision,
+                                    apr_pool_t *pool);
 
 
 /****** Packing FSFS shards *********/
@@ -118,51 +118,53 @@ packed_revprop_available(svn_boolean_t *
  * are done in SCRATCH_POOL.
  */
 svn_error_t *
-copy_revprops(const char *pack_file_dir,
-              const char *pack_filename,
-              const char *shard_path,
-              svn_revnum_t start_rev,
-              svn_revnum_t end_rev,
-              apr_array_header_t *sizes,
-              apr_size_t total_size,
-              int compression_level,
-              svn_cancel_func_t cancel_func,
-              void *cancel_baton,
-              apr_pool_t *scratch_pool);
+svn_fs_fs__copy_revprops(const char *pack_file_dir,
+                         const char *pack_filename,
+                         const char *shard_path,
+                         svn_revnum_t start_rev,
+                         svn_revnum_t end_rev,
+                         apr_array_header_t *sizes,
+                         apr_size_t total_size,
+                         int compression_level,
+                         svn_cancel_func_t cancel_func,
+                         void *cancel_baton,
+                         apr_pool_t *scratch_pool);
 
-/* For the revprop SHARD at SHARD_PATH with exactly MAX_FILES_PER_DIR
- * revprop files in it, create a packed shared at PACK_FILE_DIR.
+/* In the filesystem FS, pack all revprop shards up to min_unpacked_rev.
  *
- * COMPRESSION_LEVEL defines how well the resulting pack file shall be
- * compressed or whether is shall be compressed at all.  Individual pack
- * file containing more than one revision will be limited to a size of
- * MAX_PACK_SIZE bytes before compression.
- *
- * CANCEL_FUNC and CANCEL_BATON are used in the usual way.  Temporary
- * allocations are done in SCRATCH_POOL.
- */
-svn_error_t *
-pack_revprops_shard(const char *pack_file_dir,
-                    const char *shard_path,
-                    apr_int64_t shard,
-                    int max_files_per_dir,
-                    apr_off_t max_pack_size,
-                    int compression_level,
-                    svn_cancel_func_t cancel_func,
-                    void *cancel_baton,
-                    apr_pool_t *scratch_pool);
-
-/* Delete the non-packed revprop SHARD at SHARD_PATH with exactly
- * MAX_FILES_PER_DIR revprop files in it.  If this is shard 0, keep the
- * revprop file for revision 0.
- *
- * CANCEL_FUNC and CANCEL_BATON are used in the usual way.  Temporary
- * allocations are done in SCRATCH_POOL.
- */
-svn_error_t *
-delete_revprops_shard(const char *shard_path,
-                      apr_int64_t shard,
-                      int max_files_per_dir,
-                      svn_cancel_func_t cancel_func,
-                      void *cancel_baton,
-                      apr_pool_t *scratch_pool);
+ * NOTE: Keep the old non-packed shards around until after the format bump.
+ * Otherwise, re-running upgrade will drop the packed revprop shard but
+ * have no unpacked data anymore.  Call upgrade_cleanup_pack_revprops after
+ * the bump.
+ *
+ * NOTIFY_FUNC and NOTIFY_BATON as well as CANCEL_FUNC and CANCEL_BATON are
+ * used in the usual way.  Temporary allocations are done in SCRATCH_POOL.
+ */
+svn_error_t *
+svn_fs_fs__pack_revprops_shard(const char *pack_file_dir,
+                               const char *shard_path,
+                               apr_int64_t shard,
+                               int max_files_per_dir,
+                               apr_off_t max_pack_size,
+                               int compression_level,
+                               svn_cancel_func_t cancel_func,
+                               void *cancel_baton,
+                               apr_pool_t *scratch_pool);
+
+/* In the filesystem FS, remove all non-packed revprop shards up to
+ * min_unpacked_rev.  Temporary allocations are done in SCRATCH_POOL.
+ *
+ * NOTIFY_FUNC and NOTIFY_BATON as well as CANCEL_FUNC and CANCEL_BATON are
+ * used in the usual way.  Cancellation is supported in the sense that we
+ * will cleanly abort the operation.  However, there will be remnant shards
+ * that must be removed manually.
+ *
+ * See upgrade_pack_revprops for more info.
+ */
+svn_error_t *
+svn_fs_fs__delete_revprops_shard(const char *shard_path,
+                                 apr_int64_t shard,
+                                 int max_files_per_dir,
+                                 svn_cancel_func_t cancel_func,
+                                 void *cancel_baton,
+                                 apr_pool_t *scratch_pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.c Thu Jul 25 14:43:44 2013
@@ -144,43 +144,6 @@ serialize_representation(svn_temp_serial
                                 sizeof(*rep));
 }
 
-void
-svn_fs_fs__serialize_apr_array(svn_temp_serializer__context_t *context,
-                               apr_array_header_t **a)
-{
-  const apr_array_header_t *array = *a;
-
-  /* Nothing to do for NULL string references. */
-  if (array == NULL)
-    return;
-
-  /* array header struct */
-  svn_temp_serializer__push(context,
-                            (const void * const *)a,
-                            sizeof(*array));
-
-  /* contents */
-  svn_temp_serializer__add_leaf(context,
-                                (const void * const *)&array->elts,
-                                (apr_size_t)array->nelts * array->elt_size);
-
-  /* back to the caller's nesting level */
-  svn_temp_serializer__pop(context);
-}
-
-void
-svn_fs_fs__deserialize_apr_array(void *buffer,
-                                 apr_array_header_t **array,
-                                 apr_pool_t *pool)
-{
-  svn_temp_deserializer__resolve(buffer, (void **)array);
-  if (*array == NULL)
-    return;
-
-  svn_temp_deserializer__resolve(*array, (void **)&(*array)->elts);
-  (*array)->pool = pool;
-}
-
 /* auxilliary structure representing the content of a directory hash */
 typedef struct hash_data_t
 {

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.h?rev=1506992&r1=1506991&r2=1506992&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/temp_serializer.h Thu Jul 25 14:43:44 2013
@@ -50,24 +50,6 @@ svn_fs_fs__noderev_deserialize(void *buf
                                node_revision_t **noderev_p);
 
 /**
- * Serialize APR array @a *a within the serialization @a context.
- * The elements within the array must not contain pointers.
- */
-void
-svn_fs_fs__serialize_apr_array(struct svn_temp_serializer__context_t *context,
-                               apr_array_header_t **a);
-
-/**
- * Deserialize APR @a *array within the @a buffer.  Set its pool member to
- * @a pool.  The elements within the array must not contain pointers.
- */
-void
-svn_fs_fs__deserialize_apr_array(void *buffer,
-                                 apr_array_header_t **array,
-                                 apr_pool_t *pool);
-
-
-/**
  * #svn_txdelta_window_t is not sufficient for caching the data it
  * represents because data read process needs auxilliary information.
  */
@@ -76,9 +58,6 @@ typedef struct
   /* the txdelta window information cached / to be cached */
   svn_txdelta_window_t *window;
 
-  /* the revision file read pointer position before reading the window */
-  apr_off_t start_offset;
-
   /* the revision file read pointer position right after reading the window */
   apr_off_t end_offset;
 } svn_fs_fs__txdelta_cached_window_t;