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 2012/09/22 15:35:07 UTC

svn commit: r1388810 - /subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c

Author: stefan2
Date: Sat Sep 22 13:35:07 2012
New Revision: 1388810

URL: http://svn.apache.org/viewvc?rev=1388810&view=rev
Log:
On the 10Gb branch: improve cache retention rate in overload situations.

* subversion/libsvn_subr/cache-membuffer.c
  (find_entry): amoungst the least hit entries, evict a random one
  (ensure_data_insertable): if hit rates are now, keep all that got hit

Modified:
    subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c

Modified: subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c?rev=1388810&r1=1388809&r2=1388810&view=diff
==============================================================================
--- subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/10Gb/subversion/libsvn_subr/cache-membuffer.c Sat Sep 22 13:35:07 2012
@@ -806,7 +806,12 @@ find_entry(svn_membuffer_t *cache,
        */
       if (entry == NULL)
         {
-          entry = &group[0];
+          /* every entry gets the same chance of being removed.
+           * Otherwise, we free the first entry, fill it and
+           * remove it again on the next occasion without considering
+           * the other entries in this group.
+           */
+          entry = &group[rand() % GROUP_SIZE];
           for (i = 1; i < GROUP_SIZE; ++i)
             if (entry->hit_count > group[i].hit_count)
               entry = &group[i];
@@ -950,22 +955,38 @@ ensure_data_insertable(svn_membuffer_t *
             }
           else
             {
-              /* Roll the dice and determine a threshold somewhere from 0 up
-               * to 2 times the average hit count.
-               */
-              average_hit_value = cache->hit_count / cache->used_entries;
-              threshold = (average_hit_value+1) * (rand() % 4096) / 2048;
+              svn_boolean_t keep;
 
-              /* Drop the entry from the end of the insertion window, if it
-               * has been hit less than the threshold. Otherwise, keep it and
-               * move the insertion window one entry further.
-               */
-              if (entry->hit_count >= threshold)
+              if (cache->hit_count > cache->used_entries)
+                {
+                  /* Roll the dice and determine a threshold somewhere from 0 up
+                   * to 2 times the average hit count.
+                   */
+                  average_hit_value = cache->hit_count / cache->used_entries;
+                  threshold = (average_hit_value+1) * (rand() % 4096) / 2048;
+
+                  keep = entry->hit_count >= threshold;
+                }
+              else
+                {
+                  /* general hit count is low. Keep everything that got hit
+                   * at all and assign some 50% survival chance to everything
+                   * else.
+                   */
+                  keep = (entry->hit_count > 0) || (rand() & 1);
+                }
+
+              /* keepers or destroyers? */
+              if (keep)
                 {
                   move_entry(cache, entry);
                 }
               else
                 {
+                 /* Drop the entry from the end of the insertion window, if it
+                  * has been hit less than the threshold. Otherwise, keep it and
+                  * move the insertion window one entry further.
+                  */
                   drop_size += entry->size;
                   drop_entry(cache, entry);
                 }