Julian Foad wrote on Thu, Feb 24, 2011 at 17:03:21 +0000:
> On Wed, 2011-02-23, Daniel Shahaf wrote:
> > julianf...@apache.org wrote on Tue, Feb 22, 2011 at 15:38:35 -0000:
> > > +  return SVN_NO_ERROR;
> > > +}
> > > +
> > >  svn_error_t *
> > >  svn_wc__db_pristine_read(svn_stream_t **contents,
> > >                           svn_wc__db_t *db,
> > > @@ -173,7 +226,7 @@ svn_wc__db_pristine_read(svn_stream_t **
> > >  {
> > >    svn_wc__db_pdh_t *pdh;
> > >    const char *local_relpath;
> > > -  const char *pristine_abspath;
> > > +  pristine_read_baton_t b;
> > ...
> > > +pristine_install_txn(void *baton,
> > > +                     svn_sqlite__db_t *sdb,
> > > +                     apr_pool_t *scratch_pool)
> > > +{
> > ...
> > > +  /* If this pristine text is already present in the store, just keep it:
> > > +   * delete the new one and return. */
> > > +  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_PRISTINE));
> > > +  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, b->sha1_checksum, 
> > > scratch_pool));
> > > +  SVN_ERR(svn_sqlite__step(&have_row, stmt));
> > > +  SVN_ERR(svn_sqlite__reset(stmt));
> > > +  if (have_row)
> > > +    {
> > > +      /* Remove the temp file: it's already there */
> > > +      /* ### TODO: Maybe verify the new file matches the existing one. */
> > > +      SVN_ERR(svn_io_remove_file2(b->tempfile_abspath, FALSE, 
> > > scratch_pool));
> > > +      return SVN_NO_ERROR;
> > 
> > Perhaps check (assert?) that b->PRISTINE_ABSPATH exists?
> 
> I think what I want to do here is, only if SVN_DEBUG is defined, check
> that both the old and new files exist and that they are "the same" in
> some loose sense.  For example:
> 
> #ifdef SVN_DEBUG
> /* Consistency checks.  Verify both files exist and match. */
> {

Okay.  (That's not much more expensive, and might catch some bugs.)

>   apr_finfo_t finfo1, finfo2;
>   SVN_ERR(svn_io_stat(&finfo1, b->tempfile_abspath, APR_FINFO_SIZE,
>                       scratch_pool));
>   SVN_ERR(svn_io_stat(&finfo2, b->pristine_abspath, APR_FINFO_SIZE,
>                       scratch_pool));
>   if (finfo1->size != finfo2->size)
>     return svn_error_createf(SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
>                              _("New pristine doesn't match existing "
>                                "pristine with same checksum '%s'"),
>                              svn_checksum_to_ctring_display(
>                                b->sha1_checksum, scratch_pool));
> }
> #endif
> 
> 
> > (which reduces to dropping the "if (have_row)" check)
> 
> This 'if' block deals with the valid condition where the pristine text
> that we're adding has already been added.  I want to deal with that case
> neatly.  If I were to drop this block then in this case we would
> overwrite the DB row, which would reset its ref count.
> 

Right, my bad: I didn't mean to suggest overwriting the DB row, just to
re-use the IO logic just after the end of the if().

> > > +    }
> > > +
> > > +  /* Move the file to its target location, or discard it if already 
> > > there. */
> > > +  SVN_ERR(svn_io_check_path(b->pristine_abspath, &kind, scratch_pool));
> 
> Instead, I will simplify this part.  This extra 'stat' and the following
> if-then-else block are not really important, as they only deal with the
> "orphan file" case.  It doesn't matter if we overwrite an orphan file,
> so we can unconditionally do the "rename".

> > > +pristine_remove_if_unreferenced_txn(void *baton,
> > > +                                    svn_sqlite__db_t *sdb,
> > > +                                    apr_pool_t *scratch_pool)
> > >  {
> > ...
> > > +  /* If we removed the DB row, then remove the file. */
> > >    if (affected_rows > 0)
> > >      {
> > > -      /* Remove the file. */
> > > -      SVN_ERR(get_pristine_fname(&pristine_abspath, wcroot->abspath,
> > > -                                 sha1_checksum, TRUE /* create_subdir */,
> > > -                                 scratch_pool, scratch_pool));
> > > -      SVN_ERR(svn_io_remove_file2(pristine_abspath, TRUE /* 
> > > ignore_enoent */,
> > > +      /* ### TODO: If file not present, log a consistency error but 
> > > return
> > > +       * success. */
> > > +      SVN_ERR(svn_io_remove_file2(b->pristine_abspath, FALSE /* 
> > > ignore_enoent */,
> > >                                    scratch_pool));
> > 
> > Shouldn't it be ignore_enoent=TRUE at least in release builds?
> 
> Yes.  Thanks.  I'll do it like this:
> 
> #ifdef SVN_DEBUG
>   /* Consistency check: If file not present, log an error. */
>   SVN_ERR(svn_io_remove_file2(b->pristine_abspath,
>                               FALSE /* ignore_enoent */,
>                               scratch_pool));
> #else
>   /* In release mode, if file not present, ignore and return success. */
>   SVN_ERR(svn_io_remove_file2(b->pristine_abspath,
>                               TRUE /* ignore_enoent */,
>                               scratch_pool));
> #endif
> 

+1

Reply via email to