You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2011/03/04 15:52:23 UTC

svn commit: r1077980 - in /cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db: ColumnFamily.java SuperColumn.java

Author: jbellis
Date: Fri Mar  4 14:52:23 2011
New Revision: 1077980

URL: http://svn.apache.org/viewvc?rev=1077980&view=rev
Log:
make {SuperColumn,ColumnFamily}.addColumn() correct in the face of concurrent removals
patch by Peter Schuller and slebresne; reviewed by jbellis for CASSANDRA-1559

Modified:
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamily.java
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/SuperColumn.java

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamily.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamily.java?rev=1077980&r1=1077979&r2=1077980&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamily.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamily.java Fri Mar  4 14:52:23 2011
@@ -212,25 +212,23 @@ public class ColumnFamily implements ICo
     public void addColumn(IColumn column)
     {
         ByteBuffer name = column.name();
-        IColumn oldColumn = columns.putIfAbsent(name, column);
-        if (oldColumn != null)
+        IColumn oldColumn;
+        while ((oldColumn = columns.putIfAbsent(name, column)) != null)
         {
             if (oldColumn instanceof SuperColumn)
             {
                 ((SuperColumn) oldColumn).putColumn(column);
+                break;  // Delegated to SuperColumn
             }
             else
             {
                 // calculate reconciled col from old (existing) col and new col
                 IColumn reconciledColumn = column.reconcile(oldColumn);
-                while (!columns.replace(name, oldColumn, reconciledColumn))
-                {
-                    // if unable to replace, then get updated old (existing) col
-                    oldColumn = columns.get(name);
-                    // re-calculate reconciled col from updated old col and original new col
-                    reconciledColumn = column.reconcile(oldColumn);
-                    // try to re-update value, again
-                }
+                if (columns.replace(name, oldColumn, reconciledColumn))
+                    break;
+
+                // We failed to replace column due to a concurrent update or a concurrent removal. Keep trying.
+                // (Currently, concurrent removal should not happen (only updates), but let us support that anyway.)
             }
         }
     }

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/SuperColumn.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/SuperColumn.java?rev=1077980&r1=1077979&r2=1077980&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/SuperColumn.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/SuperColumn.java Fri Mar  4 14:52:23 2011
@@ -167,19 +167,16 @@ public class SuperColumn implements ICol
         assert column instanceof Column : "A super column can only contain simple columns";
 
         ByteBuffer name = column.name();
-        IColumn oldColumn = columns_.putIfAbsent(name, column);
-        if (oldColumn != null)
+        IColumn oldColumn;
+        while ((oldColumn = columns_.putIfAbsent(name, column)) != null)
         {
             IColumn reconciledColumn = column.reconcile(oldColumn);
-            while (!columns_.replace(name, oldColumn, reconciledColumn))
-            {
-                // if unable to replace, then get updated old (existing) col
-                oldColumn = columns_.get(name);
-                // re-calculate reconciled col from updated old col and original new col
-                reconciledColumn = column.reconcile(oldColumn);
-                // try to re-update value, again
-            }
-    	}
+            if (columns_.replace(name, oldColumn, reconciledColumn))
+                break;
+
+            // We failed to replace column due to a concurrent update or a concurrent removal. Keep trying.
+            // (Currently, concurrent removal should not happen (only updates), but let us support that anyway.)
+        }
     }
 
     /*