Пример #1
0
/* Return a memcache in *MEMCACHE_P for FS if it's configured to use
   memcached, or NULL otherwise.  Also, sets *FAIL_STOP to a boolean
   indicating whether cache errors should be returned to the caller or
   just passed to the FS warning handler.  Use FS->pool for allocating
   the memcache, and POOL for temporary allocations. */
static svn_error_t *
read_config(svn_memcache_t **memcache_p,
            svn_boolean_t *fail_stop,
            svn_boolean_t *cache_txdeltas,
            svn_boolean_t *cache_fulltexts,
            svn_fs_t *fs,
            apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;

  SVN_ERR(svn_cache__make_memcache_from_config(memcache_p, ffd->config,
                                              fs->pool));

  /* don't cache text deltas by default.
   * Once we reconstructed the fulltexts from the deltas,
   * these deltas are rarely re-used. Therefore, only tools
   * like svnadmin will activate this to speed up operations
   * dump and verify.
   */
  *cache_txdeltas
    = svn_hash__get_bool(fs->config,
                         SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
                         FALSE);
  /* by default, cache fulltexts.
   * Most SVN tools care about reconstructed file content.
   * Thus, this is a reasonable default.
   * SVN admin tools may set that to FALSE because fulltexts
   * won't be re-used rendering the cache less effective
   * by squeezing wanted data out.
   */
  *cache_fulltexts
    = svn_hash__get_bool(fs->config,
                         SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
                         TRUE);

  return svn_config_get_bool(ffd->config, fail_stop,
                             CONFIG_SECTION_CACHES, CONFIG_OPTION_FAIL_STOP,
                             FALSE);
}
Пример #2
0
/* Return a memcache in *MEMCACHE_P for FS if it's configured to use
   memcached, or NULL otherwise.  Also, sets *FAIL_STOP to a boolean
   indicating whether cache errors should be returned to the caller or
   just passed to the FS warning handler.

   *CACHE_TXDELTAS, *CACHE_FULLTEXTS and *CACHE_REVPROPS flags will be set
   according to FS->CONFIG.  *CACHE_NAMESPACE receives the cache prefix
   to use.

   Use FS->pool for allocating the memcache and CACHE_NAMESPACE, and POOL
   for temporary allocations. */
static svn_error_t *
read_config(svn_memcache_t **memcache_p,
            svn_boolean_t *fail_stop,
            const char **cache_namespace,
            svn_boolean_t *cache_txdeltas,
            svn_boolean_t *cache_fulltexts,
            svn_boolean_t *cache_revprops,
            svn_fs_t *fs,
            apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;

  SVN_ERR(svn_cache__make_memcache_from_config(memcache_p, ffd->config,
                                              fs->pool));

  /* No cache namespace by default.  I.e. all FS instances share the
   * cached data.  If you specify different namespaces, the data will
   * share / compete for the same cache memory but keys will not match
   * across namespaces and, thus, cached data will not be shared between
   * namespaces.
   *
   * Since the namespace will be concatenated with other elements to form
   * the complete key prefix, we must make sure that the resulting string
   * is unique and cannot be created by any other combination of elements.
   */
  *cache_namespace
    = normalize_key_part(svn_hash__get_cstring(fs->config,
                                               SVN_FS_CONFIG_FSFS_CACHE_NS,
                                               ""),
                         pool);

  /* don't cache text deltas by default.
   * Once we reconstructed the fulltexts from the deltas,
   * these deltas are rarely re-used. Therefore, only tools
   * like svnadmin will activate this to speed up operations
   * dump and verify.
   */
  *cache_txdeltas
    = svn_hash__get_bool(fs->config,
                         SVN_FS_CONFIG_FSFS_CACHE_DELTAS,
                         FALSE);
  /* by default, cache fulltexts.
   * Most SVN tools care about reconstructed file content.
   * Thus, this is a reasonable default.
   * SVN admin tools may set that to FALSE because fulltexts
   * won't be re-used rendering the cache less effective
   * by squeezing wanted data out.
   */
  *cache_fulltexts
    = svn_hash__get_bool(fs->config,
                         SVN_FS_CONFIG_FSFS_CACHE_FULLTEXTS,
                         TRUE);

  /* don't cache revprops by default.
   * Revprop caching significantly speeds up operations like
   * svn ls -v. However, it requires synchronization that may
   * not be available or efficient in the current server setup.
   *
   * If the caller chose option "2", enable revprop caching if
   * the required API support is there to make it efficient.
   */
  if (strcmp(svn_hash__get_cstring(fs->config,
                                   SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                                   ""), "2"))
    *cache_revprops
      = svn_hash__get_bool(fs->config,
                          SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                          FALSE);
  else
    *cache_revprops = svn_named_atomic__is_efficient();

  return svn_config_get_bool(ffd->config, fail_stop,
                             CONFIG_SECTION_CACHES, CONFIG_OPTION_FAIL_STOP,
                             FALSE);
}
Пример #3
0
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
item_closed(svn_ra_serf__xml_estate_t *xes,
            void *baton,
            int leaving_state,
            const svn_string_t *cdata,
            apr_hash_t *attrs,
            apr_pool_t *scratch_pool)
{
  list_context_t *list_ctx = baton;

  if (leaving_state == AUTHOR)
    {
      /* For compatibility with liveprops, current servers will not use
       * base64-encoding for "binary" user names bu simply drop the
       * offending control chars.
       *
       * We might want to switch to revprop-style encoding, though,
       * and this is the code to do that. */
      const char *encoding = svn_hash_gets(attrs, "encoding");
      if (encoding)
        {
          /* Check for a known encoding type.  This is easy -- there's
             only one.  */
          if (strcmp(encoding, "base64") != 0)
            {
              return svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
                                       _("Unsupported encoding '%s'"),
                                       encoding);
            }

          cdata = svn_base64_decode_string(cdata, scratch_pool);
        }

      /* Remember until the next ITEM closing tag. */
      svn_stringbuf_set(list_ctx->author_buf, cdata->data);
      list_ctx->author = list_ctx->author_buf->data;
    }
  else if (leaving_state == ITEM)
    {
      const char *dirent_path = cdata->data;
      const char *kind_word, *date, *crev, *size;
      svn_dirent_t dirent = { 0 };

      kind_word = svn_hash_gets(attrs, "node-kind");
      size = svn_hash_gets(attrs, "size");

      dirent.has_props = svn_hash__get_bool(attrs, "has-props", FALSE);
      crev = svn_hash_gets(attrs, "created-rev");
      date = svn_hash_gets(attrs, "date");

      /* Convert data. */
      dirent.kind = svn_node_kind_from_word(kind_word);

      if (size)
        SVN_ERR(svn_cstring_atoi64(&dirent.size, size));
      else
        dirent.size = SVN_INVALID_FILESIZE;

      if (crev)
        SVN_ERR(svn_revnum_parse(&dirent.created_rev, crev, NULL));
      else
        dirent.created_rev = SVN_INVALID_REVNUM;

      if (date)
        SVN_ERR(svn_time_from_cstring(&dirent.time, date, scratch_pool));

      if (list_ctx->author)
        dirent.last_author = list_ctx->author;

      /* Invoke RECEIVER */
      SVN_ERR(list_ctx->receiver(dirent_path, &dirent,
                                 list_ctx->receiver_baton, scratch_pool));

      /* Reset buffered info. */
      list_ctx->author = NULL;
    }

  return SVN_NO_ERROR;
}
Пример #4
0
/* Conforms to svn_ra_serf__xml_closed_t  */
static svn_error_t *
log_closed(svn_ra_serf__xml_estate_t *xes,
           void *baton,
           int leaving_state,
           const svn_string_t *cdata,
           apr_hash_t *attrs,
           apr_pool_t *scratch_pool)
{
  log_context_t *log_ctx = baton;

  if (leaving_state == ITEM)
    {
      svn_log_entry_t *log_entry;
      const char *rev_str;

      if (log_ctx->limit && (log_ctx->nest_level == 0)
          && (++log_ctx->count > log_ctx->limit))
        {
          return SVN_NO_ERROR;
        }

      log_entry = svn_log_entry_create(scratch_pool);

      /* Pick up the paths from the context. These have the same lifetime
         as this state. That is long enough for us to pass the paths to
         the receiver callback.  */
      if (apr_hash_count(log_ctx->collect_paths) > 0)
        {
          log_entry->changed_paths = log_ctx->collect_paths;
          log_entry->changed_paths2 = log_ctx->collect_paths;
        }

      /* ... and same story for the collected revprops.  */
      log_entry->revprops = log_ctx->collect_revprops;

      log_entry->has_children = svn_hash__get_bool(attrs,
                                                   "has-children",
                                                   FALSE);
      log_entry->subtractive_merge = svn_hash__get_bool(attrs,
                                                        "subtractive-merge",
                                                        FALSE);

      rev_str = apr_hash_get(attrs, "revision", APR_HASH_KEY_STRING);
      if (rev_str)
        log_entry->revision = SVN_STR_TO_REV(rev_str);
      else
        log_entry->revision = SVN_INVALID_REVNUM;

      /* Give the info to the reporter */
      SVN_ERR(log_ctx->receiver(log_ctx->receiver_baton,
                                log_entry,
                                scratch_pool));

      if (log_entry->has_children)
        {
          log_ctx->nest_level++;
        }
      if (! SVN_IS_VALID_REVNUM(log_entry->revision))
        {
          SVN_ERR_ASSERT(log_ctx->nest_level);
          log_ctx->nest_level--;
        }

      /* These hash tables are going to be unusable once this state's
         pool is destroyed. But let's not leave stale pointers in
         structures that have a longer life.  */
      log_ctx->collect_revprops = NULL;
      log_ctx->collect_paths = NULL;
    }
  else if (leaving_state == VERSION)
    {
      svn_ra_serf__xml_note(xes, ITEM, "revision", cdata->data);
    }
  else if (leaving_state == CREATOR)
    {
      if (log_ctx->want_author)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_AUTHOR,
                                  cdata,
                                  apr_hash_get(attrs, "encoding",
                                               APR_HASH_KEY_STRING)));
        }
    }
  else if (leaving_state == DATE)
    {
      if (log_ctx->want_date)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_DATE,
                                  cdata,
                                  apr_hash_get(attrs, "encoding",
                                               APR_HASH_KEY_STRING)));
        }
    }
  else if (leaving_state == COMMENT)
    {
      if (log_ctx->want_message)
        {
          SVN_ERR(collect_revprop(log_ctx->collect_revprops,
                                  SVN_PROP_REVISION_LOG,
                                  cdata,
                                  apr_hash_get(attrs, "encoding",
                                               APR_HASH_KEY_STRING)));
        }
    }
  else if (leaving_state == REVPROP)
    {
      apr_pool_t *result_pool = apr_hash_pool_get(log_ctx->collect_revprops);

      SVN_ERR(collect_revprop(
                log_ctx->collect_revprops,
                apr_pstrdup(result_pool,
                            apr_hash_get(attrs, "name", APR_HASH_KEY_STRING)),
                cdata,
                apr_hash_get(attrs, "encoding", APR_HASH_KEY_STRING)
                ));
    }
  else if (leaving_state == HAS_CHILDREN)
    {
      svn_ra_serf__xml_note(xes, ITEM, "has-children", "yes");
    }
  else if (leaving_state == SUBTRACTIVE_MERGE)
    {
      svn_ra_serf__xml_note(xes, ITEM, "subtractive-merge", "yes");
    }
  else
    {
      char action;

      if (leaving_state == ADDED_PATH)
        action = 'A';
      else if (leaving_state == REPLACED_PATH)
        action = 'R';
      else if (leaving_state == DELETED_PATH)
        action = 'D';
      else
        {
          SVN_ERR_ASSERT(leaving_state == MODIFIED_PATH);
          action = 'M';
        }

      SVN_ERR(collect_path(log_ctx->collect_paths, action, cdata, attrs));
    }

  return SVN_NO_ERROR;
}