Index: subversion/libsvn_fs_fs/fs_fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs_fs.c	(revision 20792)
+++ subversion/libsvn_fs_fs/fs_fs.c	(working copy)
@@ -53,6 +53,10 @@
  * by giving us arbitrarily large paths. */
 #define FSFS_MAX_PATH_LEN 4096
 
+/* Minimum size an object has to be before we will put it in
+   memcache.  */
+#define MEMCACHE_MIN_SIZE 10240
+
 /* Following are defines that specify the textual elements of the
    native filesystem directories and revision files. */
 
@@ -293,6 +297,7 @@ svn_fs_fs__open(svn_fs_t *fs, const char
   int format;
   char buf[APR_UUID_FORMATTED_LENGTH + 2];
   apr_size_t limit;
+  apr_memcache_server_t *mcs;
 
   fs->path = apr_pstrdup(fs->pool, path);
 
@@ -317,6 +322,11 @@ svn_fs_fs__open(svn_fs_t *fs, const char
   limit = sizeof(buf);
   SVN_ERR(svn_io_read_length_line(uuid_file, buf, &limit, pool));
   ffd->uuid = apr_pstrdup(fs->pool, buf);
+
+  apr_memcache_create(fs->pool, 5, 0, &ffd->memcache);
+  apr_memcache_server_create(fs->pool, "localhost", 11211, 0,
+                             5, 10, 60, &mcs);
+  apr_memcache_add_server(ffd->memcache, mcs);
   
   SVN_ERR(svn_io_file_close(uuid_file, pool));
 
@@ -1305,13 +1315,23 @@ struct rep_read_baton
   unsigned char checksum[APR_MD5_DIGESTSIZE];
   svn_filesize_t len;
   svn_filesize_t off;
+  
+  /* String we are going to send to the memcache */
+  svn_stringbuf_t *for_memcache;
+
+  /* True if we have added the item to the memcache already. */
+  svn_boolean_t memcache_added;
 
+  /* The actual representation we are trying to read.  */
+  representation_t *rep;
+  
   /* Used for temporary allocations during the read. */
   apr_pool_t *pool;
-
+  
   /* Pool used to store file handles and other data that is persistant
      for the entire stream read. */
   apr_pool_t *filehandle_pool;
+  
 };
 
 /* Create a rep_read_baton structure for node revision NODEREV in
@@ -1326,6 +1346,7 @@ rep_read_get_baton(struct rep_read_baton
   struct rep_read_baton *b;
 
   b = apr_pcalloc(pool, sizeof(*b));
+  b->rep = rep;
   b->fs = fs;
   b->chunk_index = 0;
   b->buf = NULL;
@@ -1336,6 +1357,8 @@ rep_read_get_baton(struct rep_read_baton
   b->off = 0;
   b->pool = svn_pool_create(pool);
   b->filehandle_pool = svn_pool_create(pool);
+  b->for_memcache = svn_stringbuf_create("", b->filehandle_pool);
+  b->memcache_added = FALSE;
   
   SVN_ERR(build_rep_list(&b->rs_list, &b->src_state, fs, rep,
                          b->filehandle_pool));
@@ -1429,10 +1452,32 @@ static svn_error_t *
 rep_read_contents_close(void *baton)
 {
   struct rep_read_baton *rb = baton;
-  
+#if 0
+  fs_fs_data_t *ffd = rb->fs->fsap_data;
+  const char *key;
+
+  /* Make sure we actually reached the end, and thus, have all the
+     data. */
+  if ((rb->len && rb->off == rb->len && rb->len > MEMCACHE_MIN_SIZE)
+      && !rb->memcache_added && ffd->memcache)
+    {
+      key = apr_psprintf(rb->filehandle_pool,
+                         "%s:%ld:%ld:%ld:%ld",
+                         ffd->uuid,
+                         rb->rep->revision,
+                         rb->rep->offset,
+                         rb->rep->size,
+                         rb->rep->expanded_size);
+
+      apr_memcache_add(ffd->memcache, key, rb->for_memcache->data,
+                       rb->for_memcache->len, 0, 0);
+      rb->memcache_added = TRUE;
+    }
+#endif
   svn_pool_destroy(rb->pool);
   svn_pool_destroy(rb->filehandle_pool);
   
+
   return SVN_NO_ERROR;
 }
 
@@ -1586,10 +1631,14 @@ rep_read_contents(void *baton,
                   apr_size_t *len)
 {
   struct rep_read_baton *rb = baton;
+  apr_status_t res;
 
   /* Get the next block of data. */
   SVN_ERR(get_contents(rb, buf, len));
 
+  if (rb->len != 0 && rb->len > MEMCACHE_MIN_SIZE)
+    svn_stringbuf_appendbytes(rb->for_memcache, buf, *len);
+  
   /* Perform checksumming.  We want to check the checksum as soon as
      the last byte of data is read, in case the caller never performs
      a short read, but we don't want to finalize the MD5 context
@@ -1614,6 +1663,26 @@ rep_read_contents(void *baton,
                svn_md5_digest_to_cstring_display(checksum, rb->pool));
         }
     }
+
+  if (!rb->memcache_added && rb->len && rb->off == rb->len
+      && rb->len > MEMCACHE_MIN_SIZE)
+    {
+      fs_fs_data_t *ffd = rb->fs->fsap_data;
+      const char *key;
+      /* Add it to the memcache */
+      key = apr_psprintf(rb->filehandle_pool,
+                         "%s:%ld:%ld:%ld:%ld",
+                         ffd->uuid,
+                         rb->rep->revision,
+                         rb->rep->offset,
+                         rb->rep->size,
+                         rb->rep->expanded_size);
+
+      res = apr_memcache_add(ffd->memcache, key, rb->for_memcache->data,
+                             rb->for_memcache->len, 0, 0);
+      rb->memcache_added = TRUE;
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -1640,6 +1709,31 @@ read_representation(svn_stream_t **conte
     }
   else
     {
+      fs_fs_data_t *ffd = fs->fsap_data;
+
+      if (!rep->txn_id && ffd->memcache 
+          && rep->expanded_size > MEMCACHE_MIN_SIZE)
+        {
+          apr_pool_t *temppool;
+          svn_stringbuf_t *result;
+          const char *key;
+          apr_status_t err;
+          apr_uint16_t flags;
+          
+          temppool = svn_pool_create (pool);
+          key = apr_psprintf(temppool, "%s:%ld:%ld:%ld:%ld", ffd->uuid,
+                             rep->revision,
+                             rep->offset, rep->size, rep->expanded_size);
+          result = svn_stringbuf_create("", temppool);
+          err = apr_memcache_getp(ffd->memcache, temppool, key,
+                                  &result->data, &result->len, &flags);
+          if (err == APR_SUCCESS)
+            {
+              *contents_p = svn_stream_from_stringbuf(result, temppool);
+              return SVN_NO_ERROR;
+            }
+        }
+      
       SVN_ERR(rep_read_get_baton(&rb, fs, rep, pool));
       *contents_p = svn_stream_create(rb, pool);
       svn_stream_set_read(*contents_p, rep_read_contents);
@@ -4099,7 +4193,9 @@ svn_fs_fs__create(svn_fs_t *fs,
                   apr_pool_t *pool)
 {
   int format = SVN_FS_FS__FORMAT_NUMBER;
-  
+  fs_fs_data_t *ffd;
+  apr_memcache_server_t *mcs;
+
   fs->path = apr_pstrdup(pool, path);
 
   SVN_ERR(svn_io_make_dir_recursively(svn_path_join(path, PATH_REVS_DIR,
@@ -4126,7 +4222,14 @@ svn_fs_fs__create(svn_fs_t *fs,
   /* This filesystem is ready.  Stamp it with a format number. */
   SVN_ERR(svn_io_write_version_file
           (path_format(fs, pool), format, pool));
-  ((fs_fs_data_t *) fs->fsap_data)->format = format;
+  
+  ffd = fs->fsap_data;
+  ffd->format = format;
+  
+  apr_memcache_create(fs->pool, 5, 0, &ffd->memcache);
+  apr_memcache_server_create(fs->pool, "localhost", 11211, 0,
+                             5, 10, 60, &mcs);
+  apr_memcache_add_server(ffd->memcache, mcs);
 
   return SVN_NO_ERROR;
 }
Index: subversion/libsvn_fs_fs/fs.h
===================================================================
--- subversion/libsvn_fs_fs/fs.h	(revision 20792)
+++ subversion/libsvn_fs_fs/fs.h	(working copy)
@@ -22,6 +22,7 @@
 #include <apr_hash.h>
 #include <apr_md5.h>
 #include <apr_thread_mutex.h>
+#include <apr_memcache.h>
 #include "svn_fs.h"
 
 #ifdef __cplusplus
@@ -64,6 +65,9 @@ typedef struct
      uuid; discovered using the serialized_init function. */
   apr_thread_mutex_t *lock;
 #endif
+  
+  /* Associated memcache context.  */
+  apr_memcache_t *memcache;
 } fs_fs_data_t;
 
 


