Repository: cassandra Updated Branches: refs/heads/cassandra-2.0 b9bb2c886 -> 871a6030b
Fix CFMetaData#getColumnDefinitionFromColumnName() patch by Benedict Elliott Smith; reviewed by Aleksey Yeschenko for CASSANDRA-7074 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/72203c50 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/72203c50 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/72203c50 Branch: refs/heads/cassandra-2.0 Commit: 72203c503767618ba89c6ed03c0ed091dc6e701b Parents: 9359b7a Author: belliottsmith <git...@sub.laerad.com> Authored: Fri Apr 25 03:01:41 2014 +0300 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Fri Apr 25 03:14:56 2014 +0300 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cassandra/cache/SerializingCache.java | 52 +++++++++++++++----- 2 files changed, 42 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/72203c50/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 69e9d37..b3470bf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -11,6 +11,7 @@ * Require nodetool rebuild_index to specify index names (CASSANDRA-7038) * Ensure that batchlog and hint timeouts do not produce hints (CASSANDRA-7058) * Don't shut MessagingService down when replacing a node (CASSANDRA-6476) + * Always clean up references in SerializingCache (CASSANDRA-6994) 1.2.16 http://git-wip-us.apache.org/repos/asf/cassandra/blob/72203c50/src/java/org/apache/cassandra/cache/SerializingCache.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cache/SerializingCache.java b/src/java/org/apache/cassandra/cache/SerializingCache.java index c7430d2..58da56b 100644 --- a/src/java/org/apache/cassandra/cache/SerializingCache.java +++ b/src/java/org/apache/cassandra/cache/SerializingCache.java @@ -20,6 +20,7 @@ package org.apache.cassandra.cache; import java.io.IOException; import java.util.Set; +import com.google.common.base.Throwables; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,7 +93,7 @@ public class SerializingCache<K, V> implements ICache<K, V> } catch (IOException e) { - logger.debug("Cannot fetch in memory data, we will failback to read from disk ", e); + logger.debug("Cannot fetch in memory data, we will fallback to read from disk ", e); return null; } } @@ -119,6 +120,7 @@ public class SerializingCache<K, V> implements ICache<K, V> } catch (IOException e) { + freeableMemory.unreference(); throw new RuntimeException(e); } return freeableMemory; @@ -177,7 +179,17 @@ public class SerializingCache<K, V> implements ICache<K, V> if (mem == null) return; // out of memory. never mind. - RefCountedMemory old = map.put(key, mem); + RefCountedMemory old; + try + { + old = map.put(key, mem); + } + catch (Throwable t) + { + mem.unreference(); + throw Throwables.propagate(t); + } + if (old != null) old.unreference(); } @@ -188,7 +200,17 @@ public class SerializingCache<K, V> implements ICache<K, V> if (mem == null) return false; // out of memory. never mind. - RefCountedMemory old = map.putIfAbsent(key, mem); + RefCountedMemory old; + try + { + old = map.putIfAbsent(key, mem); + } + catch (Throwable t) + { + mem.unreference(); + throw Throwables.propagate(t); + } + if (old != null) // the new value was not put, we've uselessly allocated some memory, free it mem.unreference(); @@ -202,24 +224,32 @@ public class SerializingCache<K, V> implements ICache<K, V> if (old == null) return false; + V oldValue; + // reference old guy before de-serializing + if (!old.reference()) + return false; // we have already freed hence noop. + + oldValue = deserialize(old); + old.unreference(); + + if (!oldValue.equals(oldToReplace)) + return false; + // see if the old value matches the one we want to replace RefCountedMemory mem = serialize(value); if (mem == null) return false; // out of memory. never mind. - V oldValue; - // reference old guy before de-serializing - if (!old.reference()) - return false; // we have already freed hence noop. + boolean success; try { - oldValue = deserialize(old); + success = map.replace(key, old, mem); } - finally + catch (Throwable t) { - old.unreference(); + mem.unreference(); + throw Throwables.propagate(t); } - boolean success = oldValue.equals(oldToReplace) && map.replace(key, old, mem); if (success) old.unreference(); // so it will be eventually be cleaned