You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2011/12/18 13:29:02 UTC

svn commit: r1220381 - /subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c

Author: stefan2
Date: Sun Dec 18 12:29:02 2011
New Revision: 1220381

URL: http://svn.apache.org/viewvc?rev=1220381&view=rev
Log:
On file_handle_cache branch:
Optimize file data pre-fetching to be more suitable to our typical access patterns.
During a c/o, this saves >10% of lseek() and read() operations in FSFS.

* subversion/libsvn_subr/svn_file_handle_cache.c
  (aligned_seek): new utility function
  (svn_file_handle_cache__open_internal): use the new function; use SVN_ERR throughout

Modified:
    subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c

Modified: subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c
URL: http://svn.apache.org/viewvc/subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c?rev=1220381&r1=1220380&r2=1220381&view=diff
==============================================================================
--- subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c (original)
+++ subversion/branches/file-handle-cache/subversion/libsvn_subr/svn_file_handle_cache.c Sun Dec 18 12:29:02 2011
@@ -608,6 +608,29 @@ pointer_is_closer(const cache_entry_t *e
   return old_delta > new_delta ? TRUE : FALSE;
 }
 
+/* Set file pointer of ENTRY->file to OFFSET. As an optimization, make sure
+ * that a few hundred bytes before that OFFSET are also pre-fetched as SVN
+ * tends to read data "backwards".
+ */
+static svn_error_t *
+aligned_seek(cache_entry_t *entry, apr_off_t offset)
+{
+  char dummy;
+
+  /* (try to) access a position aligned to 1KB. Since we align most files
+   * like this, repeated accesses will use the same alignment. As a result,
+   * "close-by" access will lie within the same pre-fetched block */
+  apr_off_t aligned_offset = offset & (-(FILE_BUFFER_SIZE / 4));
+  
+  /* do the seek and force data to be prefetched. Ignore the results as
+   * this is merely meant to help APR make the right decissions later on. */
+  apr_file_seek(entry->file, APR_SET, &aligned_offset);
+  apr_file_getc(&dummy, entry->file);
+  
+  /* the actual seek that was requested */
+  return svn_io_file_seek(entry->file, APR_SET, &offset, entry->pool);
+}
+
 /* Get an open file handle in F, for the file named FNAME with the open
  * flag(s) in FLAG and permissions in PERM. These parameters are the same
  * as in svn_io_file_open(). The file pointer will be moved to the specified
@@ -676,28 +699,27 @@ svn_file_handle_cache__open_internal
 
       /* move the file pointer to the desired position */
       if (offset != -1)
-        err = svn_io_file_seek(entry->file, APR_SET, &offset, entry->pool);
+        SVN_ERR(aligned_seek(entry, offset));
     }
   else
     {
       /* we need a new entry. Make room for it */
-      err = auto_close_oldest(cache);
+      SVN_ERR(auto_close_oldest(cache));
 
       /* create a suitable idle entry */
-      if (!err)
-        err = internal_file_open(&entry, cache, fname, flag, perm, cookie);
+      SVN_ERR(internal_file_open(&entry, cache, fname));
 
       /* move the file pointer to the desired position */
-      if (!err && offset > 0)
-        err = svn_io_file_seek(entry->file, APR_SET, &offset, entry->pool);
+      if (offset > 0)
+        SVN_ERR(aligned_seek(entry, offset));
     }
 
-  assert(err || entry->file);
+  assert(entry->file);
 
   /* pass the cached file handle to the application 
    * (if there was no previous error).
    */
-  return err ? err : open_entry(f, cache, entry, pool);
+  return open_entry(f, cache, entry, pool);
 }
 
 /* Same as svn_file_handle_cache__open_internal but using the mutex to