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/19 13:53:28 UTC

svn commit: r1504851 - in /subversion/branches/fsfs-improvements: notes/knobs subversion/libsvn_fs_fs/cached_data.c

Author: stefan2
Date: Fri Jul 19 11:53:27 2013
New Revision: 1504851

URL: http://svn.apache.org/r1504851
Log:
On the fsfs-improvements branch:  Add a data access logging facility.

When defining SVN_FS_FS__LOG_ACCESS, we write one line, describing
type and location of the data, to console for any data request.
Since we do this above the cache layer, this allows for easy detection
of redundant data requests from higher layers.

With logical addressing, even more detailed tracing information will
be available through this feature.

* subversion/libsvn_fs_fs/cached_data.c
  (SVN_FS_FS__ITEM_TYPE_ANY_REP,
   SVN_FS_FS__ITEM_TYPE_NODEREV,
   SVN_FS_FS__ITEM_TYPE_CHANGES): define format 6 data types
  (dgb__log_access): new function
  (rep_state_t): add revision and offset members for later logging
  (create_rep_state_body): set additional members; call logging
  (svn_fs_fs__get_node_revision,
   read_delta_window,
   svn_fs_fs__get_changes): call logging

* notes/knobs
  (SVN_FS_FS__LOG_ACCESS): new entry

Modified:
    subversion/branches/fsfs-improvements/notes/knobs
    subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/cached_data.c

Modified: subversion/branches/fsfs-improvements/notes/knobs
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/notes/knobs?rev=1504851&r1=1504850&r2=1504851&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/notes/knobs (original)
+++ subversion/branches/fsfs-improvements/notes/knobs Fri Jul 19 11:53:27 2013
@@ -68,6 +68,7 @@ SERF_VERBOSE
 SSL_VERBOSE
 SVN_DEPRECATED
 SVN_FS__TRAIL_DEBUG
+SVN_FS_FS__LOG_ACCESS
 SVN_UTF_NO_UNINITIALISED_ACCESS
 
 2.4 Test-only
@@ -395,7 +396,17 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Default:   not defined
   Suggested: defined, not defined
 
-5.14 SVN_UTF_NO_UNINITIALISED_ACCESS
+5.14 SVN_FS_FS__LOG_ACCESS
+  
+  Scope:     libsvn_fs_fs/cached_data.c
+  Purpose:   logs type and location info for any fsfs data access above the
+             cache layer to console (i.e. what data gets requested from FSFS
+             rather than disk)
+  Range:     definedness
+  Default:   not defined
+  Suggested: defined, not defined
+
+5.15 SVN_UTF_NO_UNINITIALISED_ACCESS
 
   Scope:     libsvn_subr
   Purpose:   Disables some code that triggers warnings in memory tools

Modified: subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/cached_data.c?rev=1504851&r1=1504850&r2=1504851&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/fsfs-improvements/subversion/libsvn_fs_fs/cached_data.c Fri Jul 19 11:53:27 2013
@@ -39,6 +39,116 @@
 
 #include "svn_private_config.h"
 
+/* Defined this to enable access logging via dgb__log_access
+#define SVN_FS_FS__LOG_ACCESS
+ */
+
+/* Data / item types.
+ */
+#define SVN_FS_FS__ITEM_TYPE_ANY_REP    1  /* item is a representation. */
+#define SVN_FS_FS__ITEM_TYPE_NODEREV    2  /* item is a noderev */
+#define SVN_FS_FS__ITEM_TYPE_CHANGES    3  /* item is a changed paths list */
+
+/* When SVN_FS_FS__LOG_ACCESS has been defined, write a line to console
+ * showing where REVISION, ITEM_INDEX is located in FS and use ITEM to
+ * show details on it's contents if not NULL.  To support format 6 and
+ * earlier repos, ITEM_TYPE (SVN_FS_FS__ITEM_TYPE_*) must match ITEM.
+ * Use SCRATCH_POOL for temporary allocations.
+ *
+ * For pre-format7 repos, the display will be restricted.
+ */
+static svn_error_t *
+dgb__log_access(svn_fs_t *fs,
+                svn_revnum_t revision,
+                apr_off_t offset,
+                void *item,
+                int item_type,
+                apr_pool_t *scratch_pool)
+{
+  /* no-op if this macro is not defined */
+#ifdef SVN_FS_FS__LOG_ACCESS
+  fs_fs_data_t *ffd = fs->fsap_data;
+  static const char *types[] = {"<n/a>", "rep ", "node ", "chgs "};
+  const char *description = "";
+  const char *type = types[item_type];
+  const char *pack = "";
+  apr_off_t offset_in_rev = offset;
+
+  /* determine rev / pack file offset */
+  if (svn_fs_fs__is_packed_rev(fs, revision))
+    {
+      apr_off_t rev_offset;
+      SVN_ERR(svn_fs_fs__get_packed_offset(&rev_offset, fs, revision,
+                                           scratch_pool));
+      offset += rev_offset;
+    }
+
+  /* constructing the pack file description */
+  if (revision < ffd->min_unpacked_rev)
+    pack = apr_psprintf(scratch_pool, "%4ld|",
+                        revision / ffd->max_files_per_dir);
+
+  /* construct description if possible */
+  if (item_type == SVN_FS_FS__ITEM_TYPE_NODEREV && item != NULL)
+    {
+      node_revision_t *node = item;
+      const char *data_rep
+        = node->data_rep
+        ? apr_psprintf(scratch_pool, " d=%ld/%" APR_UINT64_T_FMT,
+                       node->data_rep->revision,
+                       node->data_rep->offset)
+        : "";
+      const char *prop_rep
+        = node->prop_rep
+        ? apr_psprintf(scratch_pool, " p=%ld/%" APR_UINT64_T_FMT,
+                       node->prop_rep->revision,
+                       node->prop_rep->offset)
+        : "";
+      description = apr_psprintf(scratch_pool, "%s   (pc=%d%s%s)",
+                                 node->created_path,
+                                 node->predecessor_count,
+                                 data_rep,
+                                 prop_rep);
+    }
+  else if (item_type == SVN_FS_FS__ITEM_TYPE_ANY_REP)
+    {
+      svn_fs_fs__rep_header_t *header = item;
+      if (header == NULL)
+        description = "  (txdelta window)";
+      else if (header->type == svn_fs_fs__rep_plain)
+        description = "  PLAIN";
+      else if (header->type == svn_fs_fs__rep_self_delta)
+        description = "  DELTA";
+      else
+        description = apr_psprintf(scratch_pool,
+                                   "  DELTA against %ld/%" APR_UINT64_T_FMT,
+                                   header->base_revision,
+                                   header->base_offset);
+    }
+  else if (item_type == SVN_FS_FS__ITEM_TYPE_CHANGES && item != NULL)
+    {
+      apr_array_header_t *changes = item;
+      switch (changes->nelts)
+        {
+          case 0:  description = "  no change";
+                   break;
+          case 1:  description = "  1 change";
+                   break;
+          default: description = apr_psprintf(scratch_pool, "  %d changes",
+                                              changes->nelts);
+        }
+    }
+
+  printf("%5s%10" APR_UINT64_T_HEX_FMT " %s %7ld %7" APR_UINT64_T_FMT \
+          "   %s\n",
+          pack, (apr_uint64_t)(offset), type, revision, offset_in_rev,
+          description);
+
+#endif
+
+  return SVN_NO_ERROR;
+}
+
 /* Convenience wrapper around svn_io_file_aligned_seek. */
 static svn_error_t *
 aligned_seek(apr_file_t *file,
@@ -264,6 +374,14 @@ svn_fs_fs__get_node_revision(node_revisi
                                "Corrupt node-revision '%s'",
                                id_string->data);
     }
+
+  SVN_ERR(dgb__log_access(fs,
+                          svn_fs_fs__id_rev(id),
+                          svn_fs_fs__id_offset(id),
+                          *noderev_p,
+                          SVN_FS_FS__ITEM_TYPE_NODEREV,
+                          pool));
+
   return svn_error_trace(err);
 }
 
@@ -450,6 +568,10 @@ typedef struct rep_state_t
   svn_cache__t *window_cache;
                     /* Caches un-deltified windows. May be NULL. */
   svn_cache__t *combined_cache;
+                    /* revision containing the representation */
+  svn_revnum_t revision;
+                    /* representation's offset in REVISION */
+  apr_uint64_t offset;
   apr_off_t start;  /* The starting offset for the raw
                        svndiff/plaintext data minus header. */
   apr_off_t current;/* The current offset relative to START. */
@@ -490,6 +612,8 @@ create_rep_state_body(rep_state_t **rep_
 
   /* continue constructing RS and RA */
   rs->size = rep->size;
+  rs->revision = rep->revision;
+  rs->offset = rep->offset;
   rs->window_cache = ffd->txdelta_window_cache;
   rs->combined_cache = ffd->combined_window_cache;
   rs->ver = -1;
@@ -524,6 +648,9 @@ create_rep_state_body(rep_state_t **rep_
         *shared_file = file;
     }
 
+  SVN_ERR(dgb__log_access(fs, rep->revision, rep->offset, rh,
+                          SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+
   SVN_ERR(svn_fs_fs__read_rep_header(&rh, rs->file->stream, pool));
   SVN_ERR(svn_fs_fs__get_file_offset(&rs->start, rs->file->file, pool));
 
@@ -1045,6 +1172,9 @@ read_delta_window(svn_txdelta_window_t *
   apr_off_t end_offset;
   SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
 
+  SVN_ERR(dgb__log_access(rs->file->fs, rs->revision, rs->offset,
+                          NULL, SVN_FS_FS__ITEM_TYPE_ANY_REP, pool));
+
   /* someone has to actually read the data from file */
   SVN_ERR(auto_read_diff_version(rs, pool));
 
@@ -1881,6 +2011,9 @@ svn_fs_fs__get_changes(apr_array_header_
   if (ffd->changes_cache)
     SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool));
 
+  SVN_ERR(dgb__log_access(fs, rev, changes_offset, *changes,
+                          SVN_FS_FS__ITEM_TYPE_CHANGES, pool));
+
   return SVN_NO_ERROR;
 }