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/14 20:57:52 UTC

svn commit: r1081546 - in /cassandra/branches/cassandra-0.7: CHANGES.txt src/java/org/apache/cassandra/db/ColumnFamilyStore.java test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java

Author: jbellis
Date: Mon Mar 14 19:57:52 2011
New Revision: 1081546

URL: http://svn.apache.org/viewvc?rev=1081546&view=rev
Log:
clear Built flag in system table when dropping an index
patch by jbellis; reviewed by mdennis for CASSANDRA-2320

Modified:
    cassandra/branches/cassandra-0.7/CHANGES.txt
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java

Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1081546&r1=1081545&r2=1081546&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Mon Mar 14 19:57:52 2011
@@ -1,6 +1,7 @@
 0.7.5
  * Avoid seeking when sstable2json exports the entire file (CASSANDRA-2318)
  * fix tombstone handling in repair and sstable2json (CASSANDRA-2279)
+ * clear Built flag in system table when dropping an index (CASSANDRA-2320)
 
 
 0.7.4

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1081546&r1=1081545&r2=1081546&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Mon Mar 14 19:57:52 2011
@@ -26,7 +26,6 @@ import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
-import javax.management.JMX;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
@@ -172,20 +171,10 @@ public class ColumnFamilyStore implement
         
         // figure out what needs to be added and dropped.
         // future: if/when we have modifiable settings for secondary indexes, they'll need to be handled here.
-        for (ByteBuffer indexName : indexedColumns.keySet())
+        for (ByteBuffer indexedColumn : indexedColumns.keySet())
         {
-            if (!metadata.getColumn_metadata().containsKey(indexName))
-            {
-                ColumnFamilyStore indexCfs = indexedColumns.remove(indexName);
-                if (indexCfs == null)
-                {
-                    logger.debug("index {} already removed; ignoring", ByteBufferUtil.bytesToHex(indexName));
-                    continue;
-                }
-                indexCfs.unregisterMBean();
-                SystemTable.setIndexRemoved(metadata.tableName, metadata.cfName);
-                indexCfs.removeAllSSTables();
-            }
+            if (!metadata.getColumn_metadata().containsKey(indexedColumn))
+                removeIndex(indexedColumn);
         }
 
         for (ColumnDefinition cdef : metadata.getColumn_metadata().values())
@@ -193,6 +182,19 @@ public class ColumnFamilyStore implement
                 addIndex(cdef);
     }
 
+    void removeIndex(ByteBuffer indexedColumn)
+    {
+        ColumnFamilyStore indexCfs = indexedColumns.remove(indexedColumn);
+        if (indexCfs == null)
+        {
+            logger.debug("index {} already removed; ignoring", ByteBufferUtil.bytesToHex(indexedColumn));
+            return;
+        }
+        indexCfs.unregisterMBean();
+        SystemTable.setIndexRemoved(metadata.tableName, indexCfs.columnFamily);
+        indexCfs.removeAllSSTables();
+    }
+
     private ColumnFamilyStore(Table table, String columnFamilyName, IPartitioner partitioner, int generation, CFMetaData metadata)
     {
         assert metadata != null : "null metadata for " + table + ":" + columnFamilyName;
@@ -309,7 +311,7 @@ public class ColumnFamilyStore implement
         return keys;
     }
 
-    public void addIndex(final ColumnDefinition info)
+    public Future<?> addIndex(final ColumnDefinition info)
     {
         assert info.getIndexType() != null;
 
@@ -328,11 +330,11 @@ public class ColumnFamilyStore implement
         // so we don't have to lock everything while we do the build.  it's up to the operator to wait
         // until the index is actually built before using in queries.
         if (indexedColumns.putIfAbsent(info.name, indexedCfs) != null)
-            return;
+            return null;
 
         // if we're just linking in the index to indexedColumns on an already-built index post-restart, we're done
         if (indexedCfs.isIndexBuilt())
-            return;
+            return null;
 
         // build it asynchronously; addIndex gets called by CFS open and schema update, neither of which
         // we want to block for a long period.  (actual build is serialized on CompactionManager.)
@@ -356,7 +358,9 @@ public class ColumnFamilyStore implement
                 SystemTable.setIndexBuilt(table.name, indexedCfMetadata.cfName);
             }
         };
-        new Thread(runnable, "Create index " + indexedCfMetadata.cfName).start();
+        FutureTask<?> f = new FutureTask<Object>(runnable, null);
+        new Thread(f, "Create index " + indexedCfMetadata.cfName).start();
+        return f;
     }
 
     public void buildSecondaryIndexes(Collection<SSTableReader> sstables, SortedSet<ByteBuffer> columns)

Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java?rev=1081546&r1=1081545&r2=1081546&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java (original)
+++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java Mon Mar 14 19:57:52 2011
@@ -21,17 +21,11 @@ package org.apache.cassandra.db;
 import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Random;
+import java.nio.charset.CharacterCodingException;
+import java.util.*;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
 
-import org.apache.cassandra.db.marshal.LongType;
-import org.apache.cassandra.thrift.SlicePredicate;
-import org.apache.cassandra.thrift.SliceRange;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.junit.Test;
@@ -43,14 +37,13 @@ import org.apache.cassandra.config.Confi
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.columniterator.IdentityQueryFilter;
 import org.apache.cassandra.db.filter.*;
+import org.apache.cassandra.db.marshal.LongType;
 import org.apache.cassandra.dht.IPartitioner;
 import org.apache.cassandra.dht.Range;
 import org.apache.cassandra.io.sstable.SSTableReader;
 import org.apache.cassandra.service.StorageService;
-import org.apache.cassandra.thrift.IndexClause;
-import org.apache.cassandra.thrift.IndexExpression;
-import org.apache.cassandra.thrift.IndexOperator;
-import org.apache.cassandra.thrift.IndexType;
+import org.apache.cassandra.thrift.*;
+import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.WrappedRunnable;
 
 import static junit.framework.Assert.assertEquals;
@@ -58,7 +51,6 @@ import static junit.framework.Assert.ass
 import static org.apache.cassandra.Util.column;
 import static org.apache.cassandra.Util.getBytes;
 import static org.junit.Assert.assertNull;
-import org.apache.cassandra.utils.ByteBufferUtil;
 
 public class ColumnFamilyStoreTest extends CleanupHelper
 {
@@ -323,13 +315,26 @@ public class ColumnFamilyStoreTest exten
         ColumnFamilyStore cfs = table.getColumnFamilyStore("Indexed2");
         ColumnDefinition old = cfs.metadata.getColumn_metadata().get(ByteBufferUtil.bytes("birthdate"));
         ColumnDefinition cd = new ColumnDefinition(old.name, old.validator.getClass().getName(), IndexType.KEYS, "birthdate_index");
-        cfs.addIndex(cd);
-        while (!SystemTable.isIndexBuilt("Keyspace1", cfs.getIndexedColumnFamilyStore(ByteBufferUtil.bytes("birthdate")).columnFamily))
-            TimeUnit.MILLISECONDS.sleep(100);
-
-        // we had a bug (CASSANDRA-2244) where index would get created but not flushed -- check for that  
+        Future<?> future = cfs.addIndex(cd);
+        future.get();
+        // we had a bug (CASSANDRA-2244) where index would get created but not flushed -- check for that
         assert cfs.getIndexedColumnFamilyStore(cd.name).getSSTables().size() > 0;
 
+        queryBirthdate(table);
+
+        // validate that drop clears it out & rebuild works (CASSANDRA-2320)
+        ColumnFamilyStore indexedCfs = cfs.getIndexedColumnFamilyStore(ByteBufferUtil.bytes("birthdate"));
+        cfs.removeIndex(ByteBufferUtil.bytes("birthdate"));
+        assert !indexedCfs.isIndexBuilt();
+
+        // rebuild & re-query
+        future = cfs.addIndex(cd);
+        future.get();
+        queryBirthdate(table);
+    }
+
+    private void queryBirthdate(Table table) throws CharacterCodingException
+    {
         IndexExpression expr = new IndexExpression(ByteBufferUtil.bytes("birthdate"), IndexOperator.EQ, ByteBufferUtil.bytes(1L));
         IndexClause clause = new IndexClause(Arrays.asList(expr), ByteBufferUtil.EMPTY_BYTE_BUFFER, 100);
         IFilter filter = new IdentityQueryFilter();
@@ -337,9 +342,9 @@ public class ColumnFamilyStoreTest exten
         Range range = new Range(p.getMinimumToken(), p.getMinimumToken());
         List<Row> rows = table.getColumnFamilyStore("Indexed2").scan(clause, range, filter);
         assert rows.size() == 1 : StringUtils.join(rows, ",");
-        assertEquals("k1", ByteBufferUtil.string(rows.get(0).key.key));        
+        assertEquals("k1", ByteBufferUtil.string(rows.get(0).key.key));
     }
-    
+
     @Test
     public void testDeleteSuperRowSticksAfterFlush() throws Throwable
     {