You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2008/03/30 16:53:12 UTC
svn commit: r642755 - in
/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache:
ClockPolicy.java ConcurrentCache.java ReplacementPolicy.java
Author: kahatlen
Date: Sun Mar 30 07:53:11 2008
New Revision: 642755
URL: http://svn.apache.org/viewvc?rev=642755&view=rev
Log:
DERBY-2911: Implement a buffer manager using java.util.concurrent classes
Removed ClockPolicy.trimMe() since it adds complexity without adding
any obvious benefit.
Modified:
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
db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
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=642755&r1=642754&r2=642755&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 Sun Mar 30 07:53:11 2008
@@ -115,9 +115,9 @@
private final AtomicInteger freeEntries = new AtomicInteger();
/**
- * Tells whether there currently is a thread in the <code>doShrink()</code>
- * or <code>trimToSize()</code> methods. If this variable is
- * <code>true</code> a call to any one of those methods will be a no-op.
+ * Tells whether there currently is a thread in the {@code doShrink()}
+ * method. If this variable is {@code true} a call to {@code doShrink()}
+ * will be a no-op.
*/
private final AtomicBoolean isShrinking = new AtomicBoolean();
@@ -549,31 +549,14 @@
public void doShrink() {
// If we're already performing a shrink, ignore this request. We'll get
// a new call later by someone else if the current shrink operation is
- // not enough.
+ // not enough. If we manage to change isShrinking atomically from false
+ // to true, no one else is currently inside shrinkMe(), and others will
+ // be blocked from entering it until we reset isShrinking to false.
if (isShrinking.compareAndSet(false, true)) {
try {
- if (shrinkMe()) {
- // the clock shrunk, try to trim it too
- trimMe();
- }
- } finally {
- isShrinking.set(false);
- }
- }
- }
-
- /**
- * Try to reduce the size of the clock as much as possible by removing
- * invalid entries. In most cases, this method will do nothing.
- *
- * @see #trimMe()
- */
- public void trimToSize() {
- // ignore this request if we're already performing trim or shrink
- if (isShrinking.compareAndSet(false, true)) {
- try {
- trimMe();
+ shrinkMe();
} finally {
+ // allow others to call shrinkMe()
isShrinking.set(false);
}
}
@@ -581,13 +564,9 @@
/**
* Perform the shrinking of the clock. This method should only be called
- * by a single thread at a time, and should not be called concurrently
- * with <code>trimMe()</code>.
- *
- * @return {@code true} if the clock shrunk as a result of calling this
- * method
+ * by a single thread at a time.
*/
- private boolean shrinkMe() {
+ private void shrinkMe() {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(isShrinking.get(),
@@ -604,8 +583,6 @@
pos = hand;
}
- boolean shrunk = false;
-
while (maxLooks-- > 0) {
final Holder h;
@@ -641,7 +618,6 @@
// The holder does not hold an entry. Try to remove it.
if (h.evictIfFree()) {
removeHolder(index, h);
- shrunk = true;
// move position back because of the removal so that we
// don't skip one clock element
pos = index;
@@ -677,88 +653,9 @@
// skip one clock element
pos = index;
- shrunk = true;
-
} finally {
e.unlock();
}
- }
-
- return shrunk;
- }
-
- /**
- * The number of times <code>trimMe()</code> has been called since the last
- * time <code>trimMe()</code> tried to do some real work. This variable is
- * used by <code>trimMe()</code> to decide whether it's about time to
- * actually do something.
- */
- private int trimRequests;
-
- /**
- * Perform the trimming of the clock. This method should only be called by
- * a single thread at a time, and should not be called concurrently with
- * <code>shrinkMe()</code>.
- *
- * This method will not do anything unless it has been called a substantial
- * number of times. Also, it won't do anything if less than 25% of the
- * clock entries are unused.
- */
- private void trimMe() {
-
- if (SanityManager.DEBUG) {
- SanityManager.ASSERT(isShrinking.get(),
- "Called trimMe() without ensuring exclusive access");
- }
-
- // Only trim the clock occasionally, as it's an expensive operation.
- if (++trimRequests < maxSize / 8) {
- return;
- }
- trimRequests = 0;
-
- // Get the current size of the clock.
- final int size;
- synchronized (clock) {
- size = clock.size();
- }
-
- // no need to trim a small clock
- if (size < 32) {
- return;
- }
-
- final int unused = freeEntries.get();
-
- if (unused < size / 4) {
- // don't trim unless more than 25% of the entries are unused
- return;
- }
-
- // We still want 10% unused entries as a pool for new objects.
- final int minUnused = (size - unused) / 10;
-
- // Search for unused entries from the end since it's cheaper to remove
- // elements near the end of an ArrayList. Since no one else can shrink
- // the cache while we are in this method, we know that the size of the
- // clock still must be the same as or greater than the size variable,
- // so it's OK to search from position (size-1).
- for (int i = size - 1; i >= 0 && freeEntries.get() > minUnused; i--) {
- final Holder h;
- synchronized (clock) {
- h = clock.get(i);
- }
- // Index will be stable since no one else is allowed to remove
- // elements from the list, and new elements will be appended at the
- // end of the list.
- if (h.evictIfFree()) {
- removeHolder(i, h);
- }
- }
-
- // Finally, trim the underlying array.
- synchronized (clock) {
- clock.trimToSize();
}
}
}
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=642755&r1=642754&r2=642755&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 Sun Mar 30 07:53:11 2008
@@ -571,7 +571,6 @@
* Remove all objects that are not kept and not dirty.
*/
public void ageOut() {
- boolean shrunk = false;
for (CacheEntry entry : cache.values()) {
entry.lock();
try {
@@ -582,16 +581,12 @@
// to remove it. If c is dirty, we can't remove it yet.
if (c != null && !c.isDirty()) {
removeEntry(c.getIdentity());
- shrunk = true;
}
}
} finally {
entry.unlock();
}
}
- if (shrunk) {
- replacementPolicy.trimToSize();
- }
}
/**
@@ -637,7 +632,6 @@
*/
public boolean discard(Matchable partialKey) {
boolean allRemoved = true;
- boolean shrunk = false;
for (CacheEntry entry : cache.values()) {
entry.lock();
try {
@@ -656,13 +650,9 @@
continue;
}
removeEntry(c.getIdentity());
- shrunk = true;
} finally {
entry.unlock();
}
- }
- if (shrunk) {
- replacementPolicy.trimToSize();
}
return allRemoved;
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java?rev=642755&r1=642754&r2=642755&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/cache/ReplacementPolicy.java Sun Mar 30 07:53:11 2008
@@ -56,15 +56,6 @@
void doShrink();
/**
- * Try to reduce the size of the cache as much as possible by removing
- * invalid entries. Depending on the underlying data structure, this might
- * be a very expensive operation. The implementations are therefore allowed
- * to ignore calls to this method when they think the cost outweighs the
- * benefit.
- */
- void trimToSize();
-
- /**
* The interface for the callback objects that <code>ConcurrentCache</code>
* uses to notify the replacement algorithm about events such as look-ups
* and removals. Each <code>Callback</code> object is associated with a