db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r636670 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache: CacheEntry.java ClockPolicy.java ConcurrentCache.java
Date Thu, 13 Mar 2008 08:49:08 GMT
Author: kahatlen
Date: Thu Mar 13 01:48:57 2008
New Revision: 636670

URL: http://svn.apache.org/viewvc?rev=636670&view=rev
Log:
DERBY-2911: Implement a buffer manager using java.util.concurrent classes

Addressed some review comments:

  - Split calls to CacheEntry.lockWhenIdentityIsSet() into to separate steps
    (lock and wait) to make it easier to follow the code.

  - Created named constants for some of the heuristics in ClockPolicy

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/CacheEntry.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/CacheEntry.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/CacheEntry.java?rev=636670&r1=636669&r2=636670&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/CacheEntry.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/CacheEntry.java Thu
Mar 13 01:48:57 2008
@@ -119,11 +119,16 @@
 
     /**
      * Block until this entry's cacheable has been initialized (that is, until
-     * <code>settingIdentityComplete()</code> has been called on this object)
-     * and the current thread is granted exclusive access to the entry.
+     * {@code settingIdentityComplete()} has been called on this object). If
+     * the cacheable has been initialized before this method is called, it will
+     * return immediately. The entry must have been locked for exclusive access
+     * before this method is called. If the method needs to wait, it will
+     * release the lock and reobtain it when it wakes up again.
      */
-    void lockWhenIdentityIsSet() {
-        lock();
+    void waitUntilIdentityIsSet() {
+        if (SanityManager.DEBUG) {
+            SanityManager.ASSERT(mutex.isHeldByCurrentThread());
+        }
         while (settingIdentity != null) {
             settingIdentity.awaitUninterruptibly();
         }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java?rev=636670&r1=636669&r2=636670&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ClockPolicy.java
Thu Mar 13 01:48:57 2008
@@ -76,6 +76,18 @@
      */
     private static final int MIN_ITEMS_TO_CHECK = 20;
 
+    /**
+     * How large part of the clock to look at before giving up in
+     * {@code rotateClock()}.
+     */
+    private static final float MAX_ROTATION = 0.2f;
+
+    /**
+     * How large part of the clock to look at before giving up finding
+     * an evictable entry in {@code shrinkMe()}.
+     */
+    private static final float PART_OF_CLOCK_FOR_SHRINK = 0.1f;
+
     /** The cache manager for which this replacement policy is used. */
     private final ConcurrentCache cacheManager;
 
@@ -161,7 +173,7 @@
         // find free space for the entry. Only allow evictions if the cache
         // has reached its maximum size. Otherwise, we only look for invalid
         // entries and rather grow the cache than evict valid entries.
-        Holder h = rotateClock(entry, (float) 0.2, size >= maxSize);
+        Holder h = rotateClock(entry, size >= maxSize);
 
         if (h == null) {
             // didn't find a victim, so we need to grow
@@ -359,21 +371,18 @@
      * object might be evicted to make room for the new entry. Otherwise, only
      * unused entries are searched for. When evictions are allowed, entries are
      * marked as not recently used when the clock hand sweeps over them. The
-     * search stops when a reusable entry is found, or when as many entries as
-     * specified by <code>partOfClock</code> have been checked. If there are
+     * search stops when a reusable entry is found, or when more than a certain
+     * percentage of the entries have been visited. If there are
      * free (unused) entries, the search will continue until a reusable entry
      * is found, regardless of how many entries that need to be checked.
      *
      * @param entry the entry to insert
-     * @param partOfClock how large part of the clock to look at before we give
-     * up
      * @param allowEvictions tells whether evictions are allowed (normally
      * <code>true</code> if the cache is full and <code>false</code>
otherwise)
      * @return a holder that we can reuse, or <code>null</code> if we didn't
      * find one
      */
-    private Holder rotateClock(CacheEntry entry, float partOfClock,
-                               boolean allowEvictions)
+    private Holder rotateClock(CacheEntry entry, boolean allowEvictions)
             throws StandardException {
 
         // Calculate how many items we need to check before we give up
@@ -384,7 +393,7 @@
         if (allowEvictions) {
             synchronized (clock) {
                 itemsToCheck = Math.max(MIN_ITEMS_TO_CHECK,
-                                        (int) (clock.size() * partOfClock));
+                                        (int) (clock.size() * MAX_ROTATION));
             }
         }
 
@@ -585,8 +594,8 @@
                     "Called shrinkMe() without ensuring exclusive access");
         }
 
-        // Look at 10% of the cache to find candidates for shrinking
-        int maxLooks = Math.max(1, maxSize / 10);
+        // Max number of candidates to look at (always at least 1).
+        int maxLooks = Math.max(1, (int) (maxSize * PART_OF_CLOCK_FOR_SHRINK));
 
         // Since we don't scan the entire cache, start at the clock hand so
         // that we don't always scan the first 10% of the cache.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java?rev=636670&r1=636669&r2=636670&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ConcurrentCache.java
Thu Mar 13 01:48:57 2008
@@ -117,9 +117,11 @@
         CacheEntry entry = cache.get(key);
         while (true) {
             if (entry != null) {
-                // Found an entry in the cache. Lock it, but wait until its
-                // identity has been set.
-                entry.lockWhenIdentityIsSet();
+                // Found an entry in the cache, lock it.
+                entry.lock();
+                // If someone else is setting the identity of the Cacheable
+                // in this entry, we'll need to wait for them to complete.
+                entry.waitUntilIdentityIsSet();
                 if (entry.isValid()) {
                     // Entry is still valid. Return it.
                     return entry;
@@ -324,8 +326,12 @@
         }
 
         // Lock the entry, but wait until its identity has been set.
-        entry.lockWhenIdentityIsSet();
+        entry.lock();
         try {
+            // If the identity of the cacheable is being set, we need to wait
+            // for it to complete so that we don't return a cacheable that
+            // isn't fully initialized.
+            entry.waitUntilIdentityIsSet();
             // Return the cacheable. If the entry was removed right before we
             // locked it, getCacheable() returns null and so should we do.
             Cacheable item = entry.getCacheable();



Mime
View raw message