Simplify algorithm in NullSafeConcurrentHashMap; change SizedConcurrentHashMap's algorithms to remove overflow before putting new records into cache instead of after to avoid removing the very instances that were put.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.1.x@652930 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Patrick Linskey 2008-05-02 22:21:51 +00:00
parent d8b82311f5
commit c9fd781007
2 changed files with 31 additions and 20 deletions

View File

@ -83,20 +83,21 @@ public class NullSafeConcurrentHashMap extends ConcurrentHashMap {
// as other threads remove the same entries, whereas the random
// iterator may return values that have been removed.
while (!isEmpty()) {
while (!randomKeys.isEmpty()) {
// randomKeys contains null-masked data
Iterator iter = randomKeys.iterator();
Object key = iter.next();
if (key != null && randomKeys.remove(key)) {
Object val = super.remove(key);
if (val != null)
return new EntryImpl(unmaskNull(key), unmaskNull(val));
}
for (Iterator iter = randomKeys.iterator(); iter.hasNext(); ) {
// randomKeys contains null-masked data
Object key = iter.next();
if (key != null && randomKeys.remove(key)) {
Object val = super.remove(key);
if (val != null)
return new EntryImpl(unmaskNull(key), unmaskNull(val));
}
}
// if randomKeys is empty, fall back to non-random behavior.
Object key = super.keySet().iterator().next();
// if randomKeys is empty, fall back to non-random behavior.
for (Iterator iter = super.keySet().iterator(); iter.hasNext(); ) {
Object key = iter.next();
if (key == null)
continue;
Object val = super.remove(key);
if (val != null)
return new EntryImpl(unmaskNull(key), unmaskNull(val));

View File

@ -56,18 +56,16 @@ public class SizedConcurrentHashMap
@Override
public Object putIfAbsent(Object key, Object value) {
Object o = super.putIfAbsent(key, value);
if (maxSize != Integer.MAX_VALUE)
removeOverflow();
return o;
removeOverflow(true);
return super.putIfAbsent(key, value);
}
@Override
public Object put(Object key, Object value) {
Object o = super.put(key, value);
if (maxSize != Integer.MAX_VALUE)
removeOverflow();
return o;
removeOverflow(true);
return super.put(key, value);
}
public int getMaxSize() {
@ -79,11 +77,23 @@ public class SizedConcurrentHashMap
throw new IllegalArgumentException(String.valueOf(max));
maxSize = max;
removeOverflow();
removeOverflow(false);
}
/**
* Equivalent to <code>removeOverflow(false)</code>.
*/
protected void removeOverflow() {
while (size() > maxSize) {
removeOverflow(false);
}
/**
* Removes overflow. If <code>forPut</code> is <code>true</code>, then
* this uses <code>size() + 1</code> when computing size.
*/
protected void removeOverflow(boolean forPut) {
int sizeToCompareTo = forPut ? maxSize - 1 : maxSize;
while (size() > sizeToCompareTo) {
Entry entry = removeRandom();
// if removeRandom() returns null, break out of the loop. Of course,
// since we're not locking, the size might not actually be null