subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1681963 [1/2] - in /subversion/branches/1.10-cache-improvements: ./ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_diff/ subversion/libsvn_fs_fs/ subversion/libsvn_subr/ subversion/libsvn_wc/ su...
Date Wed, 27 May 2015 10:47:55 GMT
Author: stefan2
Date: Wed May 27 10:47:54 2015
New Revision: 1681963

URL: http://svn.apache.org/r1681963
Log:
On the 1.10-cache-improvements branch:
Catch up with /trunk up to and including r1681961.
Resolve a trivial text conflict in cache-membuffer.c .

Modified:
    subversion/branches/1.10-cache-improvements/   (props changed)
    subversion/branches/1.10-cache-improvements/CHANGES
    subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
    subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h
    subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
    subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c
    subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
    subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
    subversion/branches/1.10-cache-improvements/subversion/svn/svn.c
    subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
    subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/   (props changed)
    subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
    subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
    subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
    subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_fs.c

Propchange: subversion/branches/1.10-cache-improvements/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 27 10:47:54 2015
@@ -90,4 +90,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1669166-1679916
+/subversion/trunk:1669166-1681961

Modified: subversion/branches/1.10-cache-improvements/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/CHANGES?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/CHANGES (original)
+++ subversion/branches/1.10-cache-improvements/CHANGES Wed May 27 10:47:54 2015
@@ -192,6 +192,10 @@ http://svn.apache.org/repos/asf/subversi
     * status: now accept '-r' argument (r1671164, 1672578, 1673228)
     * ls: improve performance of '-v' on tag directories (r1673153)
     * resolve: improve conflict prompts for binary files (r1667228 et al)
+    * fsfs: improve error messages for parsing errors (r1678147, r1678149)
+    * warn when the '--config-option' FILE:SECTION:OPTION combination may
+      be invalid. (r1674301 et al)
+    * ensure full key matching in membuffer cache (r1678950 et al)
 
   - Client-side bugfixes:
     * export: fix problem exporting symlinks on windows (r1476093)
@@ -245,8 +249,6 @@ http://svn.apache.org/repos/asf/subversi
     * windows: avoid delay when user profile isn't writable (r1617926)
     * merge: display the correct node kinds for tree conflicts (r1618024,
       r1619418, r1619717)
-    * diff: show properties of a copied dir as diffs against copy, rather than
-      as adds (r1619380)
     * diff: show the correct revisions in the header (r1619452)
     * diff: fix missing header for files with only property changes (r1619476)
     * update: raise a tree conflict rather than an obstruction when an
@@ -280,12 +282,7 @@ http://svn.apache.org/repos/asf/subversi
     * update: fix a case where we reported an error rather than a tree conflict
       (r1655017)
     * info: Use local platform style paths in all cases (r1659283)
-    * ra_serf: don't abort commits that have already succeeded in some corner
-      cases (r1659867)
-    * delete conflict markers of a moved file in the right location (r1660220)
     * handle lack of a configuration file properly (r1660369)
-    * wc: don't treat foreign repos copy as an intra-repos copy (r1660593)
-    * upgrade: fix corner cases found in wc upgrades (r1660646 et al)
     * update: resolve issues with tree conflicts caused by an incoming
       delete removing a mixed revision tree (r1660742)
     * don't hold onto locks of deleted paths in the client on commit (r1661363)
@@ -307,6 +304,8 @@ http://svn.apache.org/repos/asf/subversi
       status (r1663671, r1666832)
     * update: allow a real file to replace a file external (r1664035)
     * merge: raise a tree conflict on root of obstructing dir (r1666690)
+    * cp: fix 'svn cp ^/A/D/H@1 ^/A' to properly create A (r1674455, r1674456)
+    * status: fix incorrect output with file externals (issue #4580)
 
   - Server-side bugfixes:
     * svnserve: don't ignore socket initialization errors (r1544253)
@@ -330,8 +329,6 @@ http://svn.apache.org/repos/asf/subversi
     * mod_dav_svn: fix some pool lifetime issues with error messages (r1553868)
     * mod_dav_svn: avoid setting option headers multiple times (r1557103)
     * fsfs: prevent some commits that could cause future corruption (r1560673)
-    * fsfs: fix a problem verifying pre-1.4 repos used with 1.8 (r1561419)
-    * fsfs: fix hotcopy for pre-1.4 repositories (r1561427)
     * cache: fix premature eviction due to 64-bit underflows (r1567996 et al)
     * svnserve: fix potential integer overflow in Cyrus SASL support (r1570434)
     * bdb: fix potential integer overflow and underflow (r1570701)
@@ -390,6 +387,9 @@ http://svn.apache.org/repos/asf/subversi
     * mod_dav_svn: emit the first few log items as soon as they are available
       (r1666965, r1667120)
     * mod_dav_svn: prevent a tree walk on copy sources (issue #4351)
+    * fsfs: fix 'EOF found' error when reading repo (issue #4577)
+    * svnadmin freeze: unlock rep-cache.db as part of unfreezing
+      (r1679169, r1679287)
 
   - Client-side and server-side bugfixes:
     * use less memory when retrieving extension from filename (r1548480)
@@ -455,7 +455,6 @@ http://svn.apache.org/repos/asf/subversi
     * improve windows build to use pre-built dependencies
     * optimize ramdrive usage in the windows test runner (r1504511)
     * SVN_CMDLINE_DISABLE_CRASH_HANDLER env var added for Windows (r1506507)
-    * stop including some headers in win32 resource compile (r1532287)
     * gen-make.py: support Visual Studio 2013 by --vsnet-version=2013 (r1533907)
     * windows: don't require APR source when building (r1534037, et al)
     * don't compile SQLite amalgamation twice (r1536364)
@@ -709,7 +708,6 @@ http://svn.apache.org/repos/asf/subversi
     * javahl: expose whitespace diff parameters to blame method (issue #4475)
     * javahl: update ConflictDescriptor (r1655842)
     * javahl: update FileRevision to provide textDelta (r1656911)
-    * swig: partial fix for complication problems wigh SWIG 3.0.x (r1658347)
     * swig-pl: install into prefix (r1658459)
     * javahl: expose the metadataOnly option to copy support (r1661451)
     * swig-py: add support for svn_fs_lock_many(), svn_fs_unlock_many(),
@@ -718,6 +716,10 @@ http://svn.apache.org/repos/asf/subversi
     * javahl: allow java callbacks to throw errors back to the svn code
       (r1664938, r1664939, r1664940, r1664978, r1664984)
     * swig-pl: fix some stack memory problems (r1668618, 1671388)
+    * swig: warn on using SWIG 3.x as we have compatibility problems
+      with newer versions of SWIG (1675149)
+    * javahl: requires Java 1.6 (r1677003)
+    * javahl: on OS X use /usr/libexec/java_home to find the JDK (r1675774)
 
 
 Version 1.8.13

Modified: subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h Wed May 27 10:47:54 2015
@@ -82,6 +82,8 @@ svn_wc__get_file_external_editor(const s
                                  const char *recorded_url,
                                  const svn_opt_revision_t *recorded_peg_rev,
                                  const svn_opt_revision_t *recorded_rev,
+                                 svn_wc_conflict_resolver_func2_t conflict_func,
+                                 void *conflict_baton,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  svn_wc_notify_func2_t notify_func,

Modified: subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h Wed May 27 10:47:54 2015
@@ -2175,6 +2175,18 @@ svn_io_file_info_get(apr_finfo_t *finfo,
                      apr_pool_t *pool);
 
 
+/** Set @a *filesize_p to the size of @a file. Use @a pool for temporary
+  * allocations.
+  *
+  * @note Use svn_io_file_info_get() to get more information about
+  * apr_file_t.
+  *
+  * @since New in 1.10
+  */
+svn_error_t *
+svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file,
+                     apr_pool_t *pool);
+
 /** Wrapper for apr_file_read(). */
 svn_error_t *
 svn_io_file_read(apr_file_t *file,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c Wed May 27 10:47:54 2015
@@ -538,6 +538,8 @@ switch_file_external(const char *local_a
                                              record_url,
                                              record_peg_revision,
                                              record_revision,
+                                             ctx->conflict_func2,
+                                             ctx->conflict_baton2,
                                              ctx->cancel_func,
                                              ctx->cancel_baton,
                                              ctx->notify_func2,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c Wed May 27 10:47:54 2015
@@ -56,7 +56,7 @@ create_compressed(apr_file_t **result,
   if (original_stream)
     do
     {
-      char buffer[SVN_STREAM_CHUNK_SIZE];
+      char buffer[SVN__STREAM_CHUNK_SIZE];
       rd = sizeof(buffer);
 
       if (cancel_func)
@@ -67,7 +67,7 @@ create_compressed(apr_file_t **result,
       bytes_read += rd;
       SVN_ERR(svn_stream_write(compressed, buffer, &rd));
     }
-    while(rd == SVN_STREAM_CHUNK_SIZE);
+    while(rd == SVN__STREAM_CHUNK_SIZE);
   else
     {
       apr_size_t zero = 0;

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c Wed May 27 10:47:54 2015
@@ -777,7 +777,6 @@ datasources_open(void *baton,
 {
   svn_diff__file_baton_t *file_baton = baton;
   struct file_info files[4];
-  apr_finfo_t finfo[4];
   apr_off_t length[4];
 #ifndef SVN_DISABLE_PREFIX_SUFFIX_SCANNING
   svn_boolean_t reached_one_eof;
@@ -792,14 +791,15 @@ datasources_open(void *baton,
   /* Open datasources and read first chunk */
   for (i = 0; i < datasources_len; i++)
     {
+      apr_finfo_t finfo;
       struct file_info *file
           = &file_baton->files[datasource_to_index(datasources[i])];
       SVN_ERR(svn_io_file_open(&file->file, file->path,
                                APR_READ, APR_OS_DEFAULT, file_baton->pool));
-      SVN_ERR(svn_io_file_info_get(&finfo[i], APR_FINFO_SIZE,
-                                   file->file, file_baton->pool));
-      file->size = finfo[i].size;
-      length[i] = finfo[i].size > CHUNK_SIZE ? CHUNK_SIZE : finfo[i].size;
+      SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, file->file,
+                                   file_baton->pool));
+      file->size = finfo.size;
+      length[i] = finfo.size > CHUNK_SIZE ? CHUNK_SIZE : finfo.size;
       file->buffer = apr_palloc(file_baton->pool, (apr_size_t) length[i]);
       SVN_ERR(read_chunk(file->file, file->buffer,
                          length[i], 0, file_baton->pool));

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c Wed May 27 10:47:54 2015
@@ -2524,11 +2524,43 @@ read_dir_entries(apr_array_header_t *ent
   return SVN_NO_ERROR;
 }
 
-/* Fetch the contents of a directory into ENTRIES.  Values are stored
+/* For directory NODEREV in FS, return the *FILENAME and *FILESIZE of its
+ * in-txn representation.  If the directory representation is comitted data,
+ * set *FILENAME to NULL and *FILESIZE to SVN_INVALID_FILESIZE.  Allocate
+ * *FILENAME in RESULT_POOL and use SCRATCH_POOL for temporaries. */
+static svn_error_t *
+get_txn_dir_info(const char **filename,
+                 svn_filesize_t *filesize,
+                 svn_fs_t *fs,
+                 node_revision_t *noderev,
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
+{
+  const svn_io_dirent2_t *dirent;
+
+  if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
+    {
+      *filename = svn_fs_fs__path_txn_node_children(fs, noderev->id,
+                                                    result_pool);
+
+      SVN_ERR(svn_io_stat_dirent2(&dirent, *filename, FALSE, FALSE,
+                                  scratch_pool, scratch_pool));
+      *filesize = dirent->filesize;
+    }
+  else
+    {
+      *filename = NULL;
+      *filesize = SVN_INVALID_FILESIZE;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* Fetch the contents of a directory into DIR.  Values are stored
    as filename to string mappings; further conversion is necessary to
    convert them into svn_fs_dirent_t values. */
 static svn_error_t *
-get_dir_contents(apr_array_header_t **entries,
+get_dir_contents(svn_fs_fs__dir_data_t *dir,
                  svn_fs_t *fs,
                  node_revision_t *noderev,
                  apr_pool_t *result_pool,
@@ -2536,18 +2568,24 @@ get_dir_contents(apr_array_header_t **en
 {
   svn_stream_t *contents;
 
-  *entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+  /* Initialize the result. */
+  dir->entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+  dir->txn_filesize = SVN_INVALID_FILESIZE;
+
+  /* Read dir contents - unless there is none in which case we are done. */
   if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
     {
-      const char *filename
-        = svn_fs_fs__path_txn_node_children(fs, noderev->id, scratch_pool);
+      /* Get location & current size of the directory representation. */
+      const char *filename;
+      SVN_ERR(get_txn_dir_info(&filename, &dir->txn_filesize, fs, noderev,
+                               scratch_pool, scratch_pool));
 
       /* The representation is mutable.  Read the old directory
          contents from the mutable children file, followed by the
          changes we've made in this transaction. */
       SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
                                        scratch_pool));
-      SVN_ERR(read_dir_entries(*entries, contents, TRUE, noderev->id,
+      SVN_ERR(read_dir_entries(dir->entries, contents, TRUE, noderev->id,
                                result_pool, scratch_pool));
       SVN_ERR(svn_stream_close(contents));
     }
@@ -2567,7 +2605,7 @@ get_dir_contents(apr_array_header_t **en
 
       /* de-serialize hash */
       contents = svn_stream_from_stringbuf(text, scratch_pool);
-      SVN_ERR(read_dir_entries(*entries, contents, FALSE,  noderev->id,
+      SVN_ERR(read_dir_entries(dir->entries, contents, FALSE, noderev->id,
                                result_pool, scratch_pool));
     }
 
@@ -2623,6 +2661,7 @@ svn_fs_fs__rep_contents_dir(apr_array_he
 {
   pair_cache_key_t pair_key = { 0 };
   const void *key;
+  svn_fs_fs__dir_data_t *dir;
 
   /* find the cache we may use */
   svn_cache__t *cache = locate_dir_cache(fs, &key, &pair_key, noderev,
@@ -2631,19 +2670,34 @@ svn_fs_fs__rep_contents_dir(apr_array_he
     {
       svn_boolean_t found;
 
-      SVN_ERR(svn_cache__get((void **)entries_p, &found, cache, key,
+      SVN_ERR(svn_cache__get((void **)&dir, &found, cache, key,
                              result_pool));
       if (found)
-        return SVN_NO_ERROR;
+        {
+          /* Verify that the cached dir info is not stale
+           * (no-op for committed data). */
+          const char *filename;
+          svn_filesize_t filesize;
+          SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+                                   scratch_pool, scratch_pool));
+
+          if (filesize == dir->txn_filesize)
+            {
+              /* Still valid. Done. */
+              *entries_p = dir->entries;
+              return SVN_NO_ERROR;
+            }
+        }
     }
 
   /* Read in the directory contents. */
-  SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_pool,
-                           scratch_pool));
+  dir = apr_pcalloc(scratch_pool, sizeof(*dir));
+  SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
+  *entries_p = dir->entries;
 
   /* Update the cache, if we are to use one. */
   if (cache)
-    SVN_ERR(svn_cache__set(cache, key, *entries_p, scratch_pool));
+    SVN_ERR(svn_cache__set(cache, key, dir, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2675,13 +2729,22 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
                                          scratch_pool);
   if (cache)
     {
+      extract_dir_entry_baton_t baton;
+
+      const char *filename;
+      svn_filesize_t filesize;
+      SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+                               scratch_pool, scratch_pool));
+
       /* Cache lookup. */
+      baton.txn_filesize = filesize;
+      baton.name = name;
       SVN_ERR(svn_cache__get_partial((void **)dirent,
                                      &found,
                                      cache,
                                      key,
                                      svn_fs_fs__extract_dir_entry,
-                                     (void*)name,
+                                     &baton,
                                      result_pool));
     }
 

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h Wed May 27 10:47:54 2015
@@ -623,6 +623,18 @@ typedef struct change_t
   svn_fs_path_change2_t info;
 } change_t;
 
+
+/*** Directory (only used at the cache interface) ***/
+typedef struct svn_fs_fs__dir_data_t
+{
+  /* Contents, i.e. all directory entries, sorted by name. */
+  apr_array_header_t *entries;
+
+  /* SVN_INVALID_FILESIZE for committed data, otherwise the length of the
+   * in-txn on-disk representation of that directory. */
+  svn_filesize_t txn_filesize;
+} svn_fs_fs__dir_data_t;
+
 
 #ifdef __cplusplus
 }

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c Wed May 27 10:47:54 2015
@@ -189,6 +189,19 @@ svn_fs_fs__unparse_revision_trailer(apr_
                                changes_offset);
 }
 
+/* If ERR is not NULL, wrap it MESSAGE.  The latter must have an %ld
+ * format parameter that will be filled with REV. */
+static svn_error_t *
+wrap_footer_error(svn_error_t *err,
+                  const char *message,
+                  svn_revnum_t rev)
+{
+  if (err)
+    return svn_error_quick_wrapf(err, message, rev);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_fs__parse_footer(apr_off_t *l2p_offset,
                         svn_checksum_t **l2p_checksum,
@@ -196,6 +209,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
                         svn_checksum_t **p2l_checksum,
                         svn_stringbuf_t *footer,
                         svn_revnum_t rev,
+                        apr_off_t footer_offset,
                         apr_pool_t *result_pool)
 {
   apr_int64_t val;
@@ -204,17 +218,20 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
   /* Get the L2P offset. */
   const char *str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
-  SVN_ERR(svn_cstring_atoi64(&val, str));
+  SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+                                                 footer_offset - 1, 10),
+                            "Invalid L2P offset in r%ld footer",
+                            rev));
   *l2p_offset = (apr_off_t)val;
 
   /* Get the L2P checksum. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
   SVN_ERR(svn_checksum_parse_hex(l2p_checksum, svn_checksum_md5, str,
                                  result_pool));
@@ -222,17 +239,33 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
   /* Get the P2L offset. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
-  SVN_ERR(svn_cstring_atoi64(&val, str));
+  SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+                                                 footer_offset - 1, 10),
+                            "Invalid P2L offset in r%ld footer",
+                            rev));
   *p2l_offset = (apr_off_t)val;
 
+  /* The P2L indes follows the L2P index */
+  if (*p2l_offset <= *l2p_offset)
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "P2L offset %s must be larger than L2P offset %s"
+                             " in r%ld footer",
+                             apr_psprintf(result_pool,
+                                          "%" APR_UINT64_T_HEX_FMT,
+                                          (apr_uint64_t)*p2l_offset),
+                             apr_psprintf(result_pool,
+                                          "%" APR_UINT64_T_HEX_FMT,
+                                          (apr_uint64_t)*l2p_offset),
+                             rev);
+
   /* Get the P2L checksum. */
   str = svn_cstring_tokenize(" ", &last_str);
   if (str == NULL)
-    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                            _("Invalid revision footer"));
+    return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                             "Invalid r%ld footer", rev);
 
   SVN_ERR(svn_checksum_parse_hex(p2l_checksum, svn_checksum_md5, str,
                                  result_pool));

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h Wed May 27 10:47:54 2015
@@ -67,6 +67,8 @@ svn_fs_fs__unparse_revision_trailer(apr_
  * *P2L_OFFSET, respectively.  Also, return the expected checksums in
  * in *L2P_CHECKSUM and *P2L_CHECKSUM.
  *
+ * FOOTER_OFFSET is used for validation.
+ *
  * Note that REV is only used to construct nicer error objects that
  * mention this revision.  Allocate the checksums in RESULT_POOL.
  */
@@ -77,6 +79,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
                         svn_checksum_t **p2l_checksum,
                         svn_stringbuf_t *footer,
                         svn_revnum_t rev,
+                        apr_off_t footer_offset,
                         apr_pool_t *result_pool);
 
 /* Given the offset of the L2P index data in L2P_OFFSET, the content

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c Wed May 27 10:47:54 2015
@@ -259,6 +259,7 @@ svn_fs_fs__auto_read_footer(svn_fs_fs__r
       SVN_ERR(svn_fs_fs__parse_footer(&file->l2p_offset, &file->l2p_checksum,
                                       &file->p2l_offset, &file->p2l_checksum,
                                       footer, file->start_revision,
+                                      filesize - footer_length - 1,
                                       file->pool));
       file->footer_offset = filesize - footer_length - 1;
     }

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c Wed May 27 10:47:54 2015
@@ -36,11 +36,6 @@
 
 #include "svn_private_config.h"
 
-/* Give writing processes 10 seconds to replace an existing revprop
-   file with a new one. After that time, we assume that the writing
-   process got aborted and that we have re-read revprops. */
-#define REVPROP_CHANGE_TIMEOUT (10 * 1000000)
-
 svn_error_t *
 svn_fs_fs__upgrade_pack_revprops(svn_fs_t *fs,
                                  svn_fs_upgrade_notify_t notify_func,
@@ -657,17 +652,23 @@ write_non_packed_revprop(const char **fi
                          apr_hash_t *proplist,
                          apr_pool_t *pool)
 {
+  apr_file_t *file;
   svn_stream_t *stream;
   *final_path = svn_fs_fs__path_revprops(fs, rev, pool);
 
   /* ### do we have a directory sitting around already? we really shouldn't
      ### have to get the dirname here. */
-  SVN_ERR(svn_stream_open_unique(&stream, tmp_path,
-                                 svn_dirent_dirname(*final_path, pool),
-                                 svn_io_file_del_none, pool, pool));
+  SVN_ERR(svn_io_open_unique_file3(&file, tmp_path,
+                                   svn_dirent_dirname(*final_path, pool),
+                                   svn_io_file_del_none, pool, pool));
+  stream = svn_stream_from_aprfile2(file, TRUE, pool);
   SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool));
   SVN_ERR(svn_stream_close(stream));
 
+  /* Flush temporary file to disk and close it. */
+  SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+  SVN_ERR(svn_io_file_close(file, pool));
+
   return SVN_NO_ERROR;
 }
 
@@ -750,7 +751,7 @@ serialize_revprops_header(svn_stream_t *
   return SVN_NO_ERROR;
 }
 
-/* Writes the a pack file to FILE_STREAM.  It copies the serialized data
+/* Writes the a pack file to FILE.  It copies the serialized data
  * from REVPROPS for the indexes [START,END) except for index CHANGED_INDEX.
  *
  * The data for the latter is taken from NEW_SERIALIZED.  Note, that
@@ -768,7 +769,7 @@ repack_revprops(svn_fs_t *fs,
                 int changed_index,
                 svn_stringbuf_t *new_serialized,
                 apr_off_t new_total_size,
-                svn_stream_t *file_stream,
+                apr_file_t *file,
                 apr_pool_t *pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
@@ -816,9 +817,11 @@ repack_revprops(svn_fs_t *fs,
                           ? SVN_DELTA_COMPRESSION_LEVEL_DEFAULT
                           : SVN_DELTA_COMPRESSION_LEVEL_NONE));
 
-  /* finally, write the content to the target stream and close it */
-  SVN_ERR(svn_stream_write(file_stream, compressed->data, &compressed->len));
-  SVN_ERR(svn_stream_close(file_stream));
+  /* finally, write the content to the target file, flush and close it */
+  SVN_ERR(svn_io_file_write_full(file, compressed->data, compressed->len,
+                                 NULL, pool));
+  SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+  SVN_ERR(svn_io_file_close(file, pool));
 
   return SVN_NO_ERROR;
 }
@@ -826,23 +829,22 @@ repack_revprops(svn_fs_t *fs,
 /* Allocate a new pack file name for revisions
  *     [REVPROPS->START_REVISION + START, REVPROPS->START_REVISION + END - 1]
  * of REVPROPS->MANIFEST.  Add the name of old file to FILES_TO_DELETE,
- * auto-create that array if necessary.  Return an open file stream to
- * the new file in *STREAM allocated in POOL.
+ * auto-create that array if necessary.  Return an open file *FILE that is
+ * allocated in POOL.
  */
 static svn_error_t *
-repack_stream_open(svn_stream_t **stream,
-                   svn_fs_t *fs,
-                   packed_revprops_t *revprops,
-                   int start,
-                   int end,
-                   apr_array_header_t **files_to_delete,
-                   apr_pool_t *pool)
+repack_file_open(apr_file_t **file,
+                 svn_fs_t *fs,
+                 packed_revprops_t *revprops,
+                 int start,
+                 int end,
+                 apr_array_header_t **files_to_delete,
+                 apr_pool_t *pool)
 {
   apr_int64_t tag;
   const char *tag_string;
   svn_string_t *new_filename;
   int i;
-  apr_file_t *file;
   int manifest_offset
     = (int)(revprops->start_revision - revprops->manifest_start);
 
@@ -874,12 +876,11 @@ repack_stream_open(svn_stream_t **stream
     APR_ARRAY_IDX(revprops->manifest, i + manifest_offset, const char*)
       = new_filename->data;
 
-  /* create a file stream for the new file */
-  SVN_ERR(svn_io_file_open(&file, svn_dirent_join(revprops->folder,
-                                                  new_filename->data,
-                                                  pool),
+  /* open the file */
+  SVN_ERR(svn_io_file_open(file, svn_dirent_join(revprops->folder,
+                                                 new_filename->data,
+                                                 pool),
                            APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
-  *stream = svn_stream_from_aprfile2(file, FALSE, pool);
 
   return SVN_NO_ERROR;
 }
@@ -903,6 +904,7 @@ write_packed_revprop(const char **final_
   packed_revprops_t *revprops;
   apr_int64_t generation = 0;
   svn_stream_t *stream;
+  apr_file_t *file;
   svn_stringbuf_t *serialized;
   apr_off_t new_total_size;
   int changed_index;
@@ -933,11 +935,11 @@ write_packed_revprop(const char **final_
 
       *final_path = svn_dirent_join(revprops->folder, revprops->filename,
                                     pool);
-      SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
-                                     svn_io_file_del_none, pool, pool));
+      SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+                                       svn_io_file_del_none, pool, pool));
       SVN_ERR(repack_revprops(fs, revprops, 0, revprops->sizes->nelts,
                               changed_index, serialized, new_total_size,
-                              stream, pool));
+                              file, pool));
     }
   else
     {
@@ -983,50 +985,53 @@ write_packed_revprop(const char **final_
       /* write the new, split files */
       if (left_count)
         {
-          SVN_ERR(repack_stream_open(&stream, fs, revprops, 0,
-                                     left_count, files_to_delete, pool));
+          SVN_ERR(repack_file_open(&file, fs, revprops, 0,
+                                   left_count, files_to_delete, pool));
           SVN_ERR(repack_revprops(fs, revprops, 0, left_count,
                                   changed_index, serialized, new_total_size,
-                                  stream, pool));
+                                  file, pool));
         }
 
       if (left_count + right_count < revprops->sizes->nelts)
         {
-          SVN_ERR(repack_stream_open(&stream, fs, revprops, changed_index,
-                                     changed_index + 1, files_to_delete,
-                                     pool));
+          SVN_ERR(repack_file_open(&file, fs, revprops, changed_index,
+                                   changed_index + 1, files_to_delete,
+                                   pool));
           SVN_ERR(repack_revprops(fs, revprops, changed_index,
                                   changed_index + 1,
                                   changed_index, serialized, new_total_size,
-                                  stream, pool));
+                                  file, pool));
         }
 
       if (right_count)
         {
-          SVN_ERR(repack_stream_open(&stream, fs, revprops,
-                                     revprops->sizes->nelts - right_count,
-                                     revprops->sizes->nelts,
-                                     files_to_delete, pool));
+          SVN_ERR(repack_file_open(&file, fs, revprops,
+                                   revprops->sizes->nelts - right_count,
+                                   revprops->sizes->nelts,
+                                   files_to_delete, pool));
           SVN_ERR(repack_revprops(fs, revprops,
                                   revprops->sizes->nelts - right_count,
                                   revprops->sizes->nelts, changed_index,
-                                  serialized, new_total_size, stream,
+                                  serialized, new_total_size, file,
                                   pool));
         }
 
       /* write the new manifest */
       *final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
-      SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
-                                     svn_io_file_del_none, pool, pool));
+      SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+                                       svn_io_file_del_none, pool, pool));
 
       for (i = 0; i < revprops->manifest->nelts; ++i)
         {
           const char *filename = APR_ARRAY_IDX(revprops->manifest, i,
                                                const char*);
-          SVN_ERR(svn_stream_printf(stream, pool, "%s\n", filename));
+          SVN_ERR(svn_io_file_write_full(file, filename, strlen(filename),
+                                         NULL, pool));
+          SVN_ERR(svn_io_file_putc('\n', file, pool));
         }
 
-      SVN_ERR(svn_stream_close(stream));
+      SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+      SVN_ERR(svn_io_file_close(file, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c Wed May 27 10:47:54 2015
@@ -153,6 +153,10 @@ typedef struct dir_data_t
    * (it's int because the directory is an APR array) */
   int count;
 
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown (i.e. committed data). */
+  svn_filesize_t txn_filesize;
+
   /* number of unused dir entry buckets in the index */
   apr_size_t over_provision;
 
@@ -198,15 +202,16 @@ serialize_dir_entry(svn_temp_serializer_
   svn_temp_serializer__pop(context);
 }
 
-/* Utility function to serialize the ENTRIES into a new serialization
+/* Utility function to serialize the DIR into a new serialization
  * context to be returned. Allocation will be made form POOL.
  */
 static svn_temp_serializer__context_t *
-serialize_dir(apr_array_header_t *entries, apr_pool_t *pool)
+serialize_dir(svn_fs_fs__dir_data_t *dir, apr_pool_t *pool)
 {
   dir_data_t dir_data;
   int i = 0;
   svn_temp_serializer__context_t *context;
+  apr_array_header_t *entries = dir->entries;
 
   /* calculate sizes */
   int count = entries->nelts;
@@ -216,6 +221,7 @@ serialize_dir(apr_array_header_t *entrie
 
   /* copy the hash entries to an auxiliary struct of known layout */
   dir_data.count = count;
+  dir_data.txn_filesize = dir->txn_filesize;
   dir_data.over_provision = over_provision;
   dir_data.operations = 0;
   dir_data.entries = apr_palloc(pool, entries_len);
@@ -252,24 +258,29 @@ serialize_dir(apr_array_header_t *entrie
   return context;
 }
 
-/* Utility function to reconstruct a dir entries array from serialized data
+/* Utility function to reconstruct a dir entries struct from serialized data
  * in BUFFER and DIR_DATA. Allocation will be made form POOL.
  */
-static apr_array_header_t *
+static svn_fs_fs__dir_data_t *
 deserialize_dir(void *buffer, dir_data_t *dir_data, apr_pool_t *pool)
 {
-  apr_array_header_t *result
-    = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+  svn_fs_fs__dir_data_t *result;
   apr_size_t i;
   apr_size_t count;
   svn_fs_dirent_t *entry;
   svn_fs_dirent_t **entries;
 
+  /* Construct empty directory object. */
+  result = apr_pcalloc(pool, sizeof(*result));
+  result->entries
+    = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+  result->txn_filesize = dir_data->txn_filesize;
+
   /* resolve the reference to the entries array */
   svn_temp_deserializer__resolve(buffer, (void **)&dir_data->entries);
   entries = dir_data->entries;
 
-  /* fixup the references within each entry and add it to the hash */
+  /* fixup the references within each entry and add it to the RESULT */
   for (i = 0, count = dir_data->count; i < count; ++i)
     {
       svn_temp_deserializer__resolve(entries, (void **)&entries[i]);
@@ -280,7 +291,7 @@ deserialize_dir(void *buffer, dir_data_t
       svn_fs_fs__id_deserialize(entry, (svn_fs_id_t **)&entry->id);
 
       /* add the entry to the hash */
-      APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = entry;
+      APR_ARRAY_PUSH(result->entries, svn_fs_dirent_t *) = entry;
     }
 
   /* return the now complete hash */
@@ -764,7 +775,7 @@ svn_fs_fs__serialize_dir_entries(void **
                                  void *in,
                                  apr_pool_t *pool)
 {
-  apr_array_header_t *dir = in;
+  svn_fs_fs__dir_data_t *dir = in;
 
   /* serialize the dir content into a new serialization context
    * and return the serialized data */
@@ -803,6 +814,20 @@ svn_fs_fs__get_sharded_offset(void **out
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+                                const void *data,
+                                apr_size_t data_len,
+                                void *baton,
+                                apr_pool_t *pool)
+{
+  const dir_data_t *dir_data = data;
+
+  *(svn_filesize_t *)out = dir_data->txn_filesize;
+
+  return SVN_NO_ERROR;
+}
+
 /* Utility function that returns the lowest index of the first entry in
  * *ENTRIES that points to a dir entry with a name equal or larger than NAME.
  * If an exact match has been found, *FOUND will be set to TRUE. COUNT is
@@ -857,7 +882,7 @@ svn_fs_fs__extract_dir_entry(void **out,
                              apr_pool_t *pool)
 {
   const dir_data_t *dir_data = data;
-  const char* name = baton;
+  const extract_dir_entry_baton_t *entry_baton = baton;
   svn_boolean_t found;
 
   /* resolve the reference to the entries array */
@@ -870,13 +895,14 @@ svn_fs_fs__extract_dir_entry(void **out,
 
   /* binary search for the desired entry by name */
   apr_size_t pos = find_entry((svn_fs_dirent_t **)entries,
-                              name,
+                              entry_baton->name,
                               dir_data->count,
                               &found);
 
-  /* de-serialize that entry or return NULL, if no match has been found */
+  /* de-serialize that entry or return NULL, if no match has been found.
+   * Be sure to check that the directory contents is still up-to-date. */
   *out = NULL;
-  if (found)
+  if (found && dir_data->txn_filesize == entry_baton->txn_filesize)
     {
       const svn_fs_dirent_t *source =
           svn_temp_deserializer__ptr(entries, (const void *const *)&entries[pos]);
@@ -911,31 +937,34 @@ slowly_replace_dir_entry(void **data,
 {
   replace_baton_t *replace_baton = (replace_baton_t *)baton;
   dir_data_t *dir_data = (dir_data_t *)*data;
-  apr_array_header_t *dir;
+  svn_fs_fs__dir_data_t *dir;
   int idx = -1;
   svn_fs_dirent_t *entry;
+  apr_array_header_t *entries;
 
   SVN_ERR(svn_fs_fs__deserialize_dir_entries((void **)&dir,
                                              *data,
                                              dir_data->len,
                                              pool));
 
-  entry = svn_fs_fs__find_dir_entry(dir, replace_baton->name, &idx);
+  entries = dir->entries;
+  entry = svn_fs_fs__find_dir_entry(entries, replace_baton->name, &idx);
 
   /* Replacement or removal? */
   if (replace_baton->new_entry)
     {
       /* Replace ENTRY with / insert the NEW_ENTRY */
       if (entry)
-        APR_ARRAY_IDX(dir, idx, svn_fs_dirent_t *) = replace_baton->new_entry;
+        APR_ARRAY_IDX(entries, idx, svn_fs_dirent_t *)
+          = replace_baton->new_entry;
       else
-        svn_sort__array_insert(dir, &replace_baton->new_entry, idx);
+        svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
     }
   else
     {
       /* Remove the old ENTRY. */
       if (entry)
-        svn_sort__array_delete(dir, idx, 1);
+        svn_sort__array_delete(entries, idx, 1);
     }
 
   return svn_fs_fs__serialize_dir_entries(data, data_len, dir, pool);
@@ -957,6 +986,12 @@ svn_fs_fs__replace_dir_entry(void **data
 
   svn_temp_serializer__context_t *context;
 
+  /* update the cached file length info.
+   * Because we are writing to the cache, it is fair to assume that the
+   * caller made sure that the current contents is consistent with the
+   * previous state of the directory file. */
+  dir_data->txn_filesize = replace_baton->txn_filesize;
+
   /* after quite a number of operations, let's re-pack everything.
    * This is to limit the number of wasted space as we cannot overwrite
    * existing data but must always append. */

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h Wed May 27 10:47:54 2015
@@ -192,7 +192,7 @@ svn_fs_fs__deserialize_node_revision(voi
                                      apr_pool_t *pool);
 
 /**
- * Implements #svn_cache__serialize_func_t for a directory contents array
+ * Implements #svn_cache__serialize_func_t for a #svn_fs_fs__dir_data_t
  */
 svn_error_t *
 svn_fs_fs__serialize_dir_entries(void **data,
@@ -201,7 +201,7 @@ svn_fs_fs__serialize_dir_entries(void **
                                  apr_pool_t *pool);
 
 /**
- * Implements #svn_cache__deserialize_func_t for a directory contents array
+ * Implements #svn_cache__deserialize_func_t for a #svn_fs_fs__dir_data_t
  */
 svn_error_t *
 svn_fs_fs__deserialize_dir_entries(void **out,
@@ -221,9 +221,38 @@ svn_fs_fs__get_sharded_offset(void **out
                               apr_pool_t *pool);
 
 /**
+ * Implements #svn_cache__partial_getter_func_t.
+ * Set (svn_filesize_t) @a *out to the filesize info stored with the
+ * serialized directory in @a data of @a data_len.  @a baton is unused.
+ */
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+                                const void *data,
+                                apr_size_t data_len,
+                                void *baton,
+                                apr_pool_t *pool);
+
+/**
+ * Describes the entry to be found in a directory: Identifies the entry
+ * by @a name and requires the directory file size to be @a filesize.
+ */
+typedef struct extract_dir_entry_baton_t
+{
+  /** name of the directory entry to return */
+  const char *name;
+
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown. */
+  svn_filesize_t txn_filesize;
+} extract_dir_entry_baton_t;
+
+
+/**
  * Implements #svn_cache__partial_getter_func_t for a single
  * #svn_fs_dirent_t within a serialized directory contents hash,
- * identified by its name (const char @a *baton).
+ * identified by its name (in (extract_dir_entry_baton_t *) @a *baton).
+ * If the filesize specified in the baton does not match the cached
+ * value for this directory, @a *out will be NULL as well.
  */
 svn_error_t *
 svn_fs_fs__extract_dir_entry(void **out,
@@ -236,7 +265,10 @@ svn_fs_fs__extract_dir_entry(void **out,
  * Describes the change to be done to a directory: Set the entry
  * identify by @a name to the value @a new_entry. If the latter is
  * @c NULL, the entry shall be removed if it exists. Otherwise it
- * will be replaced or automatically added, respectively.
+ * will be replaced or automatically added, respectively.  The
+ * @a filesize allows readers to identify stale cache data (e.g.
+ * due to concurrent access to txns); writers use it to update the
+ * cached file size info.
  */
 typedef struct replace_baton_t
 {
@@ -245,6 +277,10 @@ typedef struct replace_baton_t
 
   /** directory entry to insert instead */
   svn_fs_dirent_t *new_entry;
+
+  /** Current length of the in-txn in-disk representation of the directory.
+   * SVN_INVALID_FILESIZE if unknown. */
+  svn_filesize_t txn_filesize;
 } replace_baton_t;
 
 /**

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c Wed May 27 10:47:54 2015
@@ -1524,22 +1524,80 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
     }
   else
     {
+      const svn_io_dirent2_t *dirent;
+
       /* The directory rep is already mutable, so just open it for append. */
       SVN_ERR(svn_io_file_open(&file, filename, APR_WRITE | APR_APPEND,
-                               APR_OS_DEFAULT, pool));
-      out = svn_stream_from_aprfile2(file, TRUE, pool);
+                               APR_OS_DEFAULT, subpool));
+      out = svn_stream_from_aprfile2(file, TRUE, subpool);
+
+      /* If the cache contents is stale, drop it.
+       *
+       * Note that the directory file is append-only, i.e. if the size
+       * did not change, the contents didn't either. */
+      if (ffd->txn_dir_cache)
+        {
+          const char *key
+            = svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
+          svn_boolean_t found;
+          svn_filesize_t filesize;
+
+          /* Get the file size that corresponds to the cached contents
+           * (if any). */
+          SVN_ERR(svn_cache__get_partial((void **)&filesize, &found,
+                                         ffd->txn_dir_cache, key,
+                                         svn_fs_fs__extract_dir_filesize,
+                                         NULL, subpool));
+
+          /* File size info still matches?
+           * If not, we need to drop the cache entry. */
+          if (found)
+            {
+              SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+                                          subpool, subpool));
+
+              if (filesize != dirent->filesize)
+                SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, NULL,
+                                       subpool));
+            }
+        }
     }
 
+  /* Append an incremental hash entry for the entry change. */
+  if (id)
+    {
+      svn_fs_dirent_t entry;
+      entry.name = name;
+      entry.id = id;
+      entry.kind = kind;
+
+      SVN_ERR(unparse_dir_entry(&entry, out, subpool));
+    }
+  else
+    {
+      SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
+                                strlen(name), name));
+    }
+
+  /* Flush APR buffers. */
+  SVN_ERR(svn_io_file_close(file, subpool));
+  svn_pool_clear(subpool);
+
   /* if we have a directory cache for this transaction, update it */
   if (ffd->txn_dir_cache)
     {
-      /* build parameters: (name, new entry) pair */
+      /* build parameters: name, new entry, new file size  */
       const char *key =
           svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
       replace_baton_t baton;
 
+      const svn_io_dirent2_t *dirent;
+      SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+                                  subpool, subpool));
+
       baton.name = name;
       baton.new_entry = NULL;
+      baton.txn_filesize = dirent->filesize;
 
       if (id)
         {
@@ -1554,25 +1612,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
                                      svn_fs_fs__replace_dir_entry, &baton,
                                      subpool));
     }
-  svn_pool_clear(subpool);
 
-  /* Append an incremental hash entry for the entry change. */
-  if (id)
-    {
-      svn_fs_dirent_t entry;
-      entry.name = name;
-      entry.id = id;
-      entry.kind = kind;
-
-      SVN_ERR(unparse_dir_entry(&entry, out, subpool));
-    }
-  else
-    {
-      SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
-                                strlen(name), name));
-    }
-
-  SVN_ERR(svn_io_file_close(file, subpool));
   svn_pool_destroy(subpool);
   return SVN_NO_ERROR;
 }
@@ -2225,7 +2265,7 @@ get_shared_rep(representation_t **old_re
     {
       /* Make the problem show up in the server log.
 
-         Because not sharing reps is always a save option,
+         Because not sharing reps is always a safe option,
          terminating the request would be inappropriate.
        */
       svn_checksum_t checksum;

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c Wed May 27 10:47:54 2015
@@ -2882,8 +2882,15 @@ combine_key(svn_membuffer_cache_t *cache
       memcpy(data, key, key_len);
     }
 
-  /* scramble key DATA.  All of this must be reversible to prevent key
-   * collisions.  So, we limit ourselves to xor and permutations. */
+  /* Scramble key DATA to spread the key space more evenly across the
+   * cache segments and entry buckets.  All of this shall be reversible
+   * to prevent key collisions.  So, we limit ourselves to xor and
+   * permutations.
+   *
+   * As long as we compare the full combined key, the additional
+   * fingerprint collisions introduced by a non-reversible scramble
+   * would simply reduce the cache effectiveness.
+   */
   data[1] = (data[1] << 27) | (data[1] >> 37);
   data[1] ^= data[0] & 0xffff;
   data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c Wed May 27 10:47:54 2015
@@ -3582,6 +3582,16 @@ svn_io_file_info_get(apr_finfo_t *finfo,
              pool);
 }
 
+svn_error_t *
+svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file,
+                     apr_pool_t *pool)
+{
+  apr_finfo_t finfo;
+  SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, file, pool));
+
+  *filesize_p = finfo.size;
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_io_file_read(apr_file_t *file, void *buf,

Modified: subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c Wed May 27 10:47:54 2015
@@ -462,9 +462,10 @@ struct edit_baton
   const apr_array_header_t *ext_patterns;
   const char *diff3cmd;
 
-  const char *url;
   const char *repos_root_url;
   const char *repos_uuid;
+  const char *old_repos_relpath;
+  const char *new_repos_relpath;
 
   const char *record_ancestor_abspath;
   const char *recorded_repos_relpath;
@@ -474,6 +475,8 @@ struct edit_baton
   /* Introducing a new file external */
   svn_boolean_t added;
 
+  svn_wc_conflict_resolver_func2_t conflict_func;
+  void *conflict_baton;
   svn_cancel_func_t cancel_func;
   void *cancel_baton;
   svn_wc_notify_func2_t notify_func;
@@ -572,7 +575,8 @@ open_file(const char *path,
 
   *file_baton = eb;
   SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision,
-                                   NULL, NULL, NULL, &eb->changed_rev,
+                                   &eb->old_repos_relpath, NULL, NULL,
+                                   &eb->changed_rev,
                                    &eb->changed_date, &eb->changed_author,
                                    NULL, &eb->original_checksum, NULL, NULL,
                                    &eb->had_props, NULL, NULL,
@@ -733,8 +737,6 @@ close_file(void *file_baton,
     const svn_checksum_t *original_checksum = NULL;
 
     svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision);
-    const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
-                                                      eb->url, pool);
 
     if (! added)
       {
@@ -908,14 +910,14 @@ close_file(void *file_baton,
                             svn_wc_conflict_version_create2(
                                     eb->repos_root_url,
                                     eb->repos_uuid,
-                                    repos_relpath,
+                                    eb->old_repos_relpath,
                                     eb->original_revision,
                                     svn_node_file,
                                     pool),
                             svn_wc_conflict_version_create2(
                                     eb->repos_root_url,
                                     eb->repos_uuid,
-                                    repos_relpath,
+                                    eb->new_repos_relpath,
                                     *eb->target_revision,
                                     svn_node_file,
                                     pool),
@@ -933,7 +935,7 @@ close_file(void *file_baton,
                         eb->db,
                         eb->local_abspath,
                         eb->wri_abspath,
-                        repos_relpath,
+                        eb->new_repos_relpath,
                         eb->repos_root_url,
                         eb->repos_uuid,
                         *eb->target_revision,
@@ -963,6 +965,18 @@ close_file(void *file_baton,
     /* Run the work queue to complete the installation */
     SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath,
                            eb->cancel_func, eb->cancel_baton, pool));
+
+    if (conflict_skel && eb->conflict_func)
+      SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db,
+                                               eb->local_abspath,
+                                               svn_node_file,
+                                               conflict_skel,
+                                               NULL /* merge_options */,
+                                               eb->conflict_func,
+                                               eb->conflict_baton,
+                                               eb->cancel_func,
+                                               eb->cancel_baton,
+                                               pool));
   }
 
   /* Notify */
@@ -1002,6 +1016,7 @@ close_edit(void *edit_baton,
 
   if (!eb->file_closed)
     {
+      apr_hash_t *wcroot_iprops = NULL;
       /* The file wasn't updated, but its url or revision might have...
          e.g. switch between branches for relative externals.
 
@@ -1009,53 +1024,26 @@ close_edit(void *edit_baton,
          investigating when we should and shouldn't update it...
          and avoid hard to debug edge cases */
 
-      svn_node_kind_t kind;
-      const char *old_repos_relpath;
-      svn_revnum_t changed_rev;
-      apr_time_t changed_date;
-      const char *changed_author;
-      const svn_checksum_t *checksum;
-      apr_hash_t *pristine_props;
-      const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
-                                                        eb->url, pool);
-
-      SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
-                                       NULL, NULL, &changed_rev, &changed_date,
-                                       &changed_author, NULL, &checksum, NULL,
-                                       NULL, NULL, &pristine_props, NULL,
-                                       eb->db, eb->local_abspath,
-                                       pool, pool));
+      if (eb->iprops)
+        {
+          wcroot_iprops = apr_hash_make(pool);
+          svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
+        }
 
-      if (kind != svn_node_file)
-        return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
-                                   _("Node '%s' is no existing file external"),
-                                   svn_dirent_local_style(eb->local_abspath,
-                                                          pool));
-
-      SVN_ERR(svn_wc__db_external_add_file(
-                    eb->db,
-                    eb->local_abspath,
-                    eb->wri_abspath,
-                    repos_relpath,
-                    eb->repos_root_url,
-                    eb->repos_uuid,
-                    *eb->target_revision,
-                    pristine_props,
-                    eb->iprops,
-                    eb->changed_rev,
-                    eb->changed_date,
-                    eb->changed_author,
-                    checksum,
-                    NULL /* clear dav props */,
-                    eb->record_ancestor_abspath,
-                    eb->recorded_repos_relpath,
-                    eb->recorded_peg_revision,
-                    eb->recorded_revision,
-                    FALSE, NULL,
-                    TRUE /* keep_recorded_info */,
-                    NULL /* conflict_skel */,
-                    NULL /* work_items */,
-                    pool));
+      SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
+                                                       eb->local_abspath,
+                                                       svn_depth_infinity,
+                                                       eb->new_repos_relpath,
+                                                       eb->repos_root_url,
+                                                       eb->repos_uuid,
+                                                       *eb->target_revision,
+                                                       apr_hash_make(pool)
+                                                       /* exclude_relpaths */,
+                                                       wcroot_iprops,
+                                                       TRUE /* empty update */,
+                                                       eb->notify_func,
+                                                       eb->notify_baton,
+                                                       pool));
     }
 
   return SVN_NO_ERROR;
@@ -1079,6 +1067,8 @@ svn_wc__get_file_external_editor(const s
                                  const char *recorded_url,
                                  const svn_opt_revision_t *recorded_peg_rev,
                                  const svn_opt_revision_t *recorded_rev,
+                                 svn_wc_conflict_resolver_func2_t conflict_func,
+                                 void *conflict_baton,
                                  svn_cancel_func_t cancel_func,
                                  void *cancel_baton,
                                  svn_wc_notify_func2_t notify_func,
@@ -1101,9 +1091,12 @@ svn_wc__get_file_external_editor(const s
   eb->name = svn_dirent_basename(eb->local_abspath, NULL);
   eb->target_revision = target_revision;
 
-  eb->url = apr_pstrdup(edit_pool, url);
   eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
   eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
+  eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url, edit_pool);
+  eb->old_repos_relpath = eb->new_repos_relpath;
+
+  eb->original_revision = SVN_INVALID_REVNUM;
 
   eb->iprops = iprops;
 
@@ -1127,6 +1120,8 @@ svn_wc__get_file_external_editor(const s
   else
     eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */
 
+  eb->conflict_func = conflict_func;
+  eb->conflict_baton = conflict_baton;
   eb->cancel_func = cancel_func;
   eb->cancel_baton = cancel_baton;
   eb->notify_func = notify_func;

Modified: subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c Wed May 27 10:47:54 2015
@@ -1130,6 +1130,8 @@ handle_tree_conflict(svn_wc_conflict_res
                      apr_pool_t *scratch_pool)
 {
   const char *readable_desc;
+  const char *src_left_version;
+  const char *src_right_version;
   apr_pool_t *iterpool;
 
   SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
@@ -1142,6 +1144,21 @@ handle_tree_conflict(svn_wc_conflict_res
                                                  scratch_pool),
                readable_desc));
 
+  src_left_version =
+              svn_cl__node_description(desc->src_left_version,
+                                       desc->src_left_version->repos_url,
+                                       scratch_pool);
+  if (src_left_version)
+    SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+                                _("Source  left"), src_left_version));
+  src_right_version =
+              svn_cl__node_description(desc->src_right_version,
+                                       desc->src_right_version->repos_url,
+                                       scratch_pool);
+  if (src_right_version)
+    SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+                                _("Source right"), src_right_version));
+
   iterpool = svn_pool_create(scratch_pool);
   while (1)
     {

Modified: subversion/branches/1.10-cache-improvements/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/svn/svn.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/svn/svn.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/svn/svn.c Wed May 27 10:47:54 2015
@@ -398,7 +398,7 @@ const apr_getopt_option_t svn_cl__option
                        "                             "
                        "svn:externals properties")},
   {"show-inherited-props", opt_show_inherited_props, 0,
-                       N_("retrieve target's inherited properties")},
+                       N_("retrieve properties set on parents of the target")},
   {"search", opt_search, 1,
                        N_("use ARG as search pattern (glob syntax)")},
   {"search-and", opt_search_and, 1,
@@ -1445,8 +1445,13 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  directory:\n"
      "    svn:ignore         - A list of file glob patterns to ignore, one per line.\n"
      "    svn:global-ignores - Like svn:ignore, but inheritable.\n"
-     "    svn:auto-props     - A list of file glob patterns and properties to set\n"
-     "       when adding such files; like [auto-props] in the client configuration.\n"
+     "    svn:auto-props     - Automatically set properties on files when they are\n"
+     "      added or imported. Contains key-value pairs, one per line, in the format:\n"
+     "        PATTERN = PROPNAME=VALUE[;PROPNAME=VALUE ...]\n"
+     "      Example (where a literal ';' is escaped by adding another ';'):\n"
+     "        *.html = svn:eol-style=native;svn:mime-type=text/html;; charset=UTF8\n"
+     "      Applies recursively to all files added or imported under the directory\n"
+     "      it is set on.  See also [auto-props] in the client configuration file.\n"
      "    svn:externals      - A list of module specifiers, one per line, in the\n"
      "      following format similar to the syntax of 'svn checkout':\n"
      "        [-r REV] URL[@PEG] LOCALPATH\n"

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py Wed May 27 10:47:54 2015
@@ -4155,6 +4155,153 @@ def file_external_to_normal_file(sbox):
   svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
                                         expected_status)
 
+@Issue(4580)
+def file_external_recorded_info(sbox):
+  "check file external recorded info"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # r2 - Create file external
+  svntest.actions.run_and_verify_svnmucc(None, [],
+                                         '-U', sbox.repo_url,
+                                         '-m', '',
+                                         'propset', 'svn:externals',
+                                         '^/iota i', '')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    ''                  : Item(status=' U'),
+    'i'                 : Item(status='A '),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+    'i'                 : Item(status='  ', wc_rev='2', switched='X')
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status, [], False,
+                                        '-r', 2, wc_dir)
+
+  expected_infos = [{
+    'Path': re.escape(sbox.ospath('i')),
+    'Relative URL': re.escape('^/iota'),
+    'Revision': '2',
+    'Last Changed Rev': '1',
+    'Last Changed Author': 'jrandom'
+  }]
+  svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+  # r3 - No-op change
+  svntest.actions.run_and_verify_svnmucc(None, [],
+                                         '-U', sbox.repo_url,
+                                         '-m', '',
+                                         'cp', '1', 'iota', 'iotb')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'iotb'              : Item(status='A '),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+  expected_status.add({
+    'i'                 : Item(status='  ', wc_rev='3', switched='X'),
+    'iotb'              : Item(status='  ', wc_rev='3')
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status, [], False,
+                                        '-r', 3, wc_dir)
+
+  expected_infos = [{
+    'Path': re.escape(sbox.ospath('i')),
+    'Relative URL': re.escape('^/iota'),
+    'Revision': '3',
+    'Last Changed Rev': '1',
+    'Last Changed Author': 'jrandom'
+  }]
+  svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+  # r4 - Update url
+  svntest.actions.run_and_verify_svnmucc(None, [],
+                                         '-U', sbox.repo_url,
+                                         '-m', '',
+                                         'propset', 'svn:externals',
+                                         '^/iotb i', '')
+
+
+  expected_output = svntest.wc.State(wc_dir, {
+    ''                  : Item(status=' U'),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 4)
+  expected_status.add({
+    'i'                 : Item(status='  ', wc_rev='4', switched='X'),
+    'iotb'              : Item(status='  ', wc_rev='4')
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status, [], False,
+                                        '-r', 4, wc_dir)
+
+  expected_infos = [{
+    'Path': re.escape(sbox.ospath('i')),
+    'Relative URL': re.escape('^/iotb'),
+    'Revision': '4',
+    'Last Changed Rev': '3',
+    'Last Changed Author': 'jrandom'
+  }]
+  svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+  # r5 - Replace file
+  svntest.actions.run_and_verify_svnmucc(None, [],
+                                         '-U', sbox.repo_url,
+                                         '-m', '',
+                                         'rm', 'iotb',
+                                         'cp', '3', 'A/mu', 'iotb')
+
+  expected_output = svntest.wc.State(wc_dir, {
+    'i'                 : Item(status='U '),
+    'iotb'              : Item(status='A ', prev_status='D '),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 5)
+  expected_status.add({
+    'i'                 : Item(status='  ', wc_rev='5', switched='X'),
+    'iotb'              : Item(status='  ', wc_rev='5')
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status, [], False,
+                                        '-r', 5, wc_dir)
+
+  expected_infos = [{
+    'Path': re.escape(sbox.ospath('i')),
+    'Relative URL': re.escape('^/iotb'),
+    'Revision': '5',
+    'Last Changed Rev': '5',
+    'Last Changed Author': 'jrandom'
+  }]
+  svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+  # Back to r2. But with a conflict
+  sbox.simple_append('i', 'i')
+  expected_output = svntest.wc.State(wc_dir, {
+    ''                  : Item(status=' U'),
+    'iotb'              : Item(status='D '),
+    'i'                 : Item(status='C '),
+  })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+  expected_status.add({
+    'i'                 : Item(status='C ', wc_rev='5', switched='X'),
+  })
+  svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+                                        expected_status, [], False,
+                                        '-r', 2, wc_dir)
+
+  expected_infos = [{
+    'Path': re.escape(sbox.ospath('i')),
+    'Relative URL': re.escape('^/iota'),
+    'Revision': '5',
+    'Last Changed Rev': '1',
+    'Last Changed Author': 'jrandom',
+    'Conflict Details': re.escape('incoming file edit upon switch'
+                                  ' Source  left: (file) ^/iotb@5'
+                                  ' Source right: (file) ^/iota@5')
+  }]
+  svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
 
 ########################################################################
 # Run the tests
@@ -4229,6 +4376,7 @@ test_list = [ None,
               copy_pin_externals_whitespace_dir,
               nested_notification,
               file_external_to_normal_file,
+              file_external_recorded_info,
              ]
 
 if __name__ == '__main__':

Propchange: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed May 27 10:47:54 2015
@@ -1,7 +1,7 @@
 .libs
 test-*
 locks-test
-fs-test
+fs-*test
 *.o
 *.lo
 *~

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c Wed May 27 10:47:54 2015
@@ -251,9 +251,8 @@ static int max_threads = 1;  /* Run test
 static struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,
-    SVN_TEST_OPTS_XFAIL_OTOH(reopen_modify,
-                             "test reopen and modify txn",
-                             SVN_TEST_PASS_IF_FS_TYPE_IS_NOT("fsfs")),
+    SVN_TEST_OPTS_PASS(reopen_modify,
+                       "test reopen and modify txn"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c Wed May 27 10:47:54 2015
@@ -6939,7 +6939,7 @@ freeze_and_commit(const svn_test_opts_t
   /* Make some commit using same FS instance. */
   SVN_ERR(svn_fs_begin_txn(&txn, fs, new_rev, pool));
   SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_change_node_prop(txn_root, "/", "temperature",
+  SVN_ERR(svn_fs_change_node_prop(txn_root, "", "temperature",
                                   svn_string_create("310.05", pool),
                                   pool));
   SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c Wed May 27 10:47:54 2015
@@ -782,7 +782,47 @@ test_install_stream_to_longpath(apr_pool
 
   return SVN_NO_ERROR;
 }
-
+
+static svn_error_t *
+test_file_size_get(apr_pool_t *pool)
+{
+  const char *tmp_dir, *path;
+  apr_file_t *file;
+  svn_filesize_t filesize;
+
+  /* Create an empty directory. */
+  SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "test_file_size_get", pool));
+  SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
+  SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
+  svn_test_add_dir_cleanup(tmp_dir);
+
+  /* Path does not exist. */
+  path = svn_dirent_join(tmp_dir, "file", pool);
+
+  /* Create a file.*/
+  SVN_ERR(svn_io_file_open(&file, path,
+                           APR_WRITE | APR_CREATE | APR_BUFFERED,
+                           APR_OS_DEFAULT, pool));
+  SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+  SVN_TEST_ASSERT(filesize == 0);
+
+  /* Write 8 bytes and check new size. */
+  SVN_ERR(svn_io_file_write_full(file, "12345678", 8, NULL, pool));
+
+  SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+  SVN_TEST_ASSERT(filesize == 8);
+
+  /* Truncate to 2 bytes. */
+  SVN_ERR(svn_io_file_trunc(file, 2, pool));
+
+  SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+  SVN_TEST_ASSERT(filesize == 2);
+
+  /* Close the file. */
+  SVN_ERR(svn_io_file_close(file, pool));
+  return SVN_NO_ERROR;
+}
+
 /* The test table.  */
 
 static int max_threads = 3;
@@ -806,6 +846,8 @@ static struct svn_test_descriptor_t test
                    "test ignore-enoent"),
     SVN_TEST_PASS2(test_install_stream_to_longpath,
                    "test svn_stream__install_stream to long path"),
+    SVN_TEST_PASS2(test_file_size_get,
+                   "test svn_io_file_size_get"),
     SVN_TEST_NULL
   };
 



Mime
View raw message