subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1660839 - in /subversion/trunk/subversion: include/private/svn_cache.h libsvn_subr/cache-membuffer.c tests/libsvn_subr/cache-test.c
Date Thu, 19 Feb 2015 10:52:58 GMT
Author: stefan2
Date: Thu Feb 19 10:52:58 2015
New Revision: 1660839

URL: http://svn.apache.org/r1660839
Log:
Add a function to clear a membuffer cache instance.

That is very useful if you want to replace repositories on disk and must
make sure that there is no residual data from the old repository contents
in your caches.

* subversion/include/private/svn_cache.h
  (svn_cache__membuffer_clear): Declare new private API function.

* subversion/libsvn_subr/cache-membuffer.c
  (svn_cache__membuffer_clear): Implement it.

* subversion/tests/libsvn_subr/cache-test.c
  (test_membuffer_cache_clearing): New test.
  (test_funcs): Register new test.

Modified:
    subversion/trunk/subversion/include/private/svn_cache.h
    subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
    subversion/trunk/subversion/tests/libsvn_subr/cache-test.c

Modified: subversion/trunk/subversion/include/private/svn_cache.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_cache.h?rev=1660839&r1=1660838&r2=1660839&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_cache.h (original)
+++ subversion/trunk/subversion/include/private/svn_cache.h Thu Feb 19 10:52:58 2015
@@ -542,6 +542,15 @@ svn_cache__get_global_membuffer_cache(vo
 svn_cache__info_t *
 svn_cache__membuffer_get_global_info(apr_pool_t *pool);
 
+/**
+ * Remove all current contents from CACHE.
+ *
+ * NOTE:  In a multi-threaded environment, new contents may have been put
+ * into the cache by the time this function returns.
+ */
+svn_error_t *
+svn_cache__membuffer_clear(svn_membuffer_t *cache);
+
 /** @} */
 
 

Modified: subversion/trunk/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/cache-membuffer.c?rev=1660839&r1=1660838&r2=1660839&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/trunk/subversion/libsvn_subr/cache-membuffer.c Thu Feb 19 10:52:58 2015
@@ -1819,6 +1819,61 @@ svn_cache__membuffer_cache_create(svn_me
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_cache__membuffer_clear(svn_membuffer_t *cache)
+{
+  apr_size_t seg;
+  apr_size_t segment_count = cache->segment_count;
+
+  /* Length of the group_initialized array in bytes.
+     See also svn_cache__membuffer_cache_create(). */
+  apr_size_t group_init_size
+    = 1 + (cache->group_count + cache->spare_group_count)
+            / (8 * GROUP_INIT_GRANULARITY);
+
+  /* Clear segment by segment.  This implies that other thread may read
+     and write to other segments after we cleared them and before the
+     last segment is done.
+
+     However, that is no different from a write request coming through
+     right after we cleared all segments because dependencies between
+     cache entries (recursive lookup / access locks) are not allowed.
+   */
+  for (seg = 0; seg < segment_count; ++seg)
+    {
+      /* Unconditionally acquire the write lock. */
+      SVN_ERR(force_write_lock_cache(&cache[seg]));
+
+      /* Mark all groups as "not initialized", which implies "empty". */
+      cache[seg].first_spare_group = NO_INDEX;
+      cache[seg].max_spare_used = 0;
+
+      memset(cache[seg].group_initialized, 0, group_init_size);
+
+      /* Unlink L1 contents. */
+      cache[seg].l1.first = NO_INDEX;
+      cache[seg].l1.last = NO_INDEX;
+      cache[seg].l1.next = NO_INDEX;
+      cache[seg].l1.current_data = cache[seg].l1.start_offset;
+
+      /* Unlink L2 contents. */
+      cache[seg].l2.first = NO_INDEX;
+      cache[seg].l2.last = NO_INDEX;
+      cache[seg].l2.next = NO_INDEX;
+      cache[seg].l2.current_data = cache[seg].l2.start_offset;
+
+      /* Reset content counters. */
+      cache[seg].data_used = 0;
+      cache[seg].used_entries = 0;
+
+      /* Segment may be used again. */
+      SVN_ERR(unlock_cache(&cache[seg], SVN_NO_ERROR));
+    }
+
+  /* done here */
+  return SVN_NO_ERROR;
+}
+
 /* Look for the cache entry in group GROUP_INDEX of CACHE, identified
  * by the hash value TO_FIND and set *FOUND accordingly.
  *

Modified: subversion/trunk/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_subr/cache-test.c?rev=1660839&r1=1660838&r2=1660839&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_subr/cache-test.c Thu Feb 19 10:52:58 2015
@@ -354,6 +354,74 @@ test_memcache_long_key(const svn_test_op
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_membuffer_cache_clearing(apr_pool_t *pool)
+{
+  svn_cache__t *cache;
+  svn_membuffer_t *membuffer;
+  svn_boolean_t found;
+  svn_revnum_t *value;
+  svn_revnum_t valueA = 12345;
+  svn_revnum_t valueB = 67890;
+
+  /* Create a simple cache for strings, keyed by strings. */
+  SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1, 0,
+                                            TRUE, TRUE, pool));
+  SVN_ERR(svn_cache__create_membuffer_cache(&cache,
+                                            membuffer,
+                                            serialize_revnum,
+                                            deserialize_revnum,
+                                            APR_HASH_KEY_STRING,
+                                            "cache:",
+                                            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
+                                            FALSE,
+                                            pool, pool));
+
+  /* Initially, the cache is empty. */
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key A", pool));
+  SVN_TEST_ASSERT(!found);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key B", pool));
+  SVN_TEST_ASSERT(!found);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key C", pool));
+  SVN_TEST_ASSERT(!found);
+
+  /* Add entries. */
+  SVN_ERR(svn_cache__set(cache, "key A", &valueA, pool));
+  SVN_ERR(svn_cache__set(cache, "key B", &valueB, pool));
+
+  /* Added entries should be cached (too small to get evicted already). */
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key A", pool));
+  SVN_TEST_ASSERT(found);
+  SVN_TEST_ASSERT(*value == valueA);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key B", pool));
+  SVN_TEST_ASSERT(found);
+  SVN_TEST_ASSERT(*value == valueB);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key C", pool));
+  SVN_TEST_ASSERT(!found);
+
+  /* Clear the cache. */
+  SVN_ERR(svn_cache__membuffer_clear(membuffer));
+
+  /* The cache is empty again. */
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key A", pool));
+  SVN_TEST_ASSERT(!found);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key B", pool));
+  SVN_TEST_ASSERT(!found);
+  SVN_ERR(svn_cache__get((void **) &value, &found, cache, "key C", pool));
+  SVN_TEST_ASSERT(!found);
+
+  /* But still functional: */
+  SVN_ERR(svn_cache__set(cache, "key B", &valueB, pool));
+  SVN_ERR(svn_cache__has_key(&found, cache, "key A", pool));
+  SVN_TEST_ASSERT(!found);
+  SVN_ERR(svn_cache__has_key(&found, cache, "key B", pool));
+  SVN_TEST_ASSERT(found);
+  SVN_ERR(svn_cache__has_key(&found, cache, "key C", pool));
+  SVN_TEST_ASSERT(!found);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -372,6 +440,8 @@ static struct svn_test_descriptor_t test
                    "basic membuffer svn_cache test"),
     SVN_TEST_PASS2(test_membuffer_serializer_error_handling,
                    "test for error handling in membuffer svn_cache"),
+    SVN_TEST_PASS2(test_membuffer_cache_clearing,
+                   "test clearing a membuffer svn_cache"),
     SVN_TEST_NULL
   };
 



Mime
View raw message