Author: gdusbabek
Date: Wed May 5 15:34:07 2010
New Revision: 941349
URL: http://svn.apache.org/viewvc?rev=941349&view=rev
Log:
restrict how and when CFMetaData objects are added to the static cfid map.
Patch by Gary Dusbabek, reviewed by Jonthan Ellis.
Modified:
cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddColumnFamily.java
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddKeyspace.java
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameColumnFamily.java
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameKeyspace.java
cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java
cassandra/trunk/test/unit/org/apache/cassandra/db/commitlog/CommitLogHeaderTest.java
cassandra/trunk/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Wed
May 5 15:34:07 2010
@@ -65,7 +65,7 @@ public final class CFMetaData
public static final void fixMaxId()
{
// never set it to less than 1000. this ensures that we have enough
system CFids for future use.
- idGen.set(Math.max(Collections.max(cfIdMap.values()) + 1, 1000));
+ idGen.set(cfIdMap.size() == 0 ? 1000 :
Math.max(Collections.max(cfIdMap.values()) + 1, 1000));
}
public final String tableName; // name of table which has this
column family
@@ -94,8 +94,19 @@ public final class CFMetaData
this.keyCacheSize = keyCacheSize;
this.readRepairChance = readRepairChance;
this.cfId = cfId;
- currentCfNames.put(cfId, cfName);
- cfIdMap.put(new Pair<String, String>(tableName, cfName), cfId);
+ }
+
+ /** adds this cfm to the map. */
+ public static void map(CFMetaData cfm) throws ConfigurationException
+ {
+ Pair<String, String> key = new Pair<String, String>(cfm.tableName,
cfm.cfName);
+ if (cfIdMap.containsKey(key))
+ throw new ConfigurationException("Attempt to assign id to existing
column family.");
+ else
+ {
+ cfIdMap.put(key, cfm.cfId);
+ currentCfNames.put(cfm.cfId, cfm.cfName);
+ }
}
public CFMetaData(String tableName, String cfName, String columnType,
AbstractType comparator, AbstractType subcolumnComparator, String comment,
double rowCacheSize, boolean preloadRowCache, double keyCacheSize)
@@ -111,8 +122,8 @@ public final class CFMetaData
/** clones an existing CFMetaData using the same id. */
public static CFMetaData rename(CFMetaData cfm, String newName)
{
- purge(cfm);
- return new CFMetaData(cfm.tableName, newName, cfm.columnType,
cfm.comparator, cfm.subcolumnComparator, cfm.comment, cfm.rowCacheSize,
cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance, cfm.cfId);
+ CFMetaData newCfm = new CFMetaData(cfm.tableName, newName,
cfm.columnType, cfm.comparator, cfm.subcolumnComparator, cfm.comment,
cfm.rowCacheSize, cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance,
cfm.cfId);
+ return newCfm;
}
/** clones existing CFMetaData. keeps the id but changes the table name.*/
Modified:
cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
Wed May 5 15:34:07 2010
@@ -43,6 +43,7 @@ import org.yaml.snakeyaml.error.YAMLExce
import java.io.File;
import java.io.FileInputStream;
+import java.io.IOError;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
@@ -298,6 +299,8 @@ public class DatabaseDescriptor
0.01)
};
KSMetaData systemMeta = new KSMetaData(Table.SYSTEM_TABLE, null,
-1, systemCfDefs);
+ CFMetaData.map(systemCfDefs[0]);
+ CFMetaData.map(systemCfDefs[1]);
tables.put(Table.SYSTEM_TABLE, systemMeta);
CFMetaData[] definitionCfDefs = new CFMetaData[]
@@ -305,10 +308,15 @@ public class DatabaseDescriptor
new CFMetaData(Table.DEFINITIONS, Migration.MIGRATIONS_CF,
"Standard", new TimeUUIDType(), null, "individual schema mutations", 0, false,
0),
new CFMetaData(Table.DEFINITIONS, Migration.SCHEMA_CF,
"Standard", new UTF8Type(), null, "current state of the schema", 0, false, 0)
};
+ CFMetaData.map(definitionCfDefs[0]);
+ CFMetaData.map(definitionCfDefs[1]);
tables.put(Table.DEFINITIONS, new KSMetaData(Table.DEFINITIONS,
null, -1, definitionCfDefs));
// NOTE: make sure that all system CFMs defined by now. calling
fixMaxId at this point will set the base id
// to a value that leaves room for future system cfms.
+ // TODO: I've left quite a bit of space for more system CFMs to be
defined (up to 1000). However, there is no
+ // way to guarantee the assignment of the right IDS to the system
CFMs other than rigidly controlling the order
+ // they ar map()ed in. It might be a good idea to explicitly set
the ids in a static initializer somewhere.
CFMetaData.fixMaxId();
/* Load the seeds for node contact points */
@@ -395,6 +403,17 @@ public class DatabaseDescriptor
Collection<KSMetaData> tableDefs =
DefsTable.loadFromStorage(uuid);
for (KSMetaData def : tableDefs)
{
+ for (CFMetaData cfm : def.cfMetaData().values())
+ {
+ try
+ {
+ CFMetaData.map(cfm);
+ }
+ catch (ConfigurationException ex)
+ {
+ throw new IOError(ex);
+ }
+ }
DatabaseDescriptor.setTableDefinition(def, uuid);
// this part creates storage and jmx objects.
Table.open(def.name);
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/KSMetaData.java Wed
May 5 15:34:07 2010
@@ -51,20 +51,6 @@ public final class KSMetaData
this.cfMetaData = Collections.<String,
CFMetaData>unmodifiableMap(cfmap);
}
- public static KSMetaData rename(KSMetaData ksm, String newName, boolean
purgeOldCfs)
- {
- // cfs will need to have their tablenames reset. CFMetaData are
immutable, so new ones get created with the
- // same ids.
- List<CFMetaData> newCfs = new
ArrayList<CFMetaData>(ksm.cfMetaData().size());
- for (CFMetaData oldCf : ksm.cfMetaData().values())
- {
- if (purgeOldCfs)
- CFMetaData.purge(oldCf);
- newCfs.add(CFMetaData.renameTable(oldCf, newName));
- }
- return new KSMetaData(newName, ksm.strategyClass,
ksm.replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
- }
-
public boolean equals(Object obj)
{
if (obj == null)
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddColumnFamily.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddColumnFamily.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddColumnFamily.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddColumnFamily.java
Wed May 5 15:34:07 2010
@@ -72,11 +72,19 @@ public class AddColumnFamily extends Mig
return new KSMetaData(ksm.name, ksm.strategyClass,
ksm.replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
}
- public void applyModels()
+ public void applyModels() throws IOException
{
// reinitialize the table.
KSMetaData ksm = DatabaseDescriptor.getTableDefinition(cfm.tableName);
ksm = makeNewKeyspaceDefinition(ksm);
+ try
+ {
+ CFMetaData.map(cfm);
+ }
+ catch (ConfigurationException ex)
+ {
+ throw new IOException(ex);
+ }
if (!clientMode)
Table.open(ksm.name).initCf(cfm.cfId, cfm.cfName);
DatabaseDescriptor.setTableDefinition(ksm, newVersion);
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddKeyspace.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddKeyspace.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddKeyspace.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/migration/AddKeyspace.java
Wed May 5 15:34:07 2010
@@ -66,6 +66,19 @@ public class AddKeyspace extends Migrati
@Override
public void applyModels() throws IOException
{
+ for (CFMetaData cfm : ksm.cfMetaData().values())
+ {
+ try
+ {
+ CFMetaData.map(cfm);
+ }
+ catch (ConfigurationException ex)
+ {
+ // throw RTE since this indicates a table,cf maps to an
existing ID. It shouldn't if this is really a
+ // new keyspace.
+ throw new RuntimeException(ex);
+ }
+ }
DatabaseDescriptor.setTableDefinition(ksm, newVersion);
// these definitions could have come from somewhere else.
CFMetaData.fixMaxId();
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameColumnFamily.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameColumnFamily.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameColumnFamily.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameColumnFamily.java
Wed May 5 15:34:07 2010
@@ -109,7 +109,19 @@ public class RenameColumnFamily extends
renameCfStorageFiles(tableName, oldName, newName);
// reset defs.
+ KSMetaData oldKsm = DatabaseDescriptor.getTableDefinition(tableName);
+ CFMetaData.purge(oldKsm.cfMetaData().get(oldName));
KSMetaData ksm =
makeNewKeyspaceDefinition(DatabaseDescriptor.getTableDefinition(tableName));
+ try
+ {
+ CFMetaData.map(ksm.cfMetaData().get(newName));
+ }
+ catch (ConfigurationException ex)
+ {
+ // throwing RTE since this this means that the table,cf already
maps to a different ID, which has already
+ // been checked in the constructor and shouldn't happen.
+ throw new RuntimeException(ex);
+ }
DatabaseDescriptor.setTableDefinition(ksm, newVersion);
if (!clientMode)
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameKeyspace.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameKeyspace.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameKeyspace.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/migration/RenameKeyspace.java
Wed May 5 15:34:07 2010
@@ -18,6 +18,7 @@
package org.apache.cassandra.db.migration;
+import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.KSMetaData;
@@ -36,6 +37,8 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
public class RenameKeyspace extends Migration
@@ -66,10 +69,24 @@ public class RenameKeyspace extends Migr
throw new ConfigurationException("Keyspace already exists.");
// clone the ksm, replacing thename.
- KSMetaData newKsm = KSMetaData.rename(oldKsm, newName, false);
+ KSMetaData newKsm = rename(oldKsm, newName, false);
rm = makeDefinitionMutation(newKsm, oldKsm, newVersion);
}
+
+ private static KSMetaData rename(KSMetaData ksm, String newName, boolean
purgeOldCfs)
+ {
+ // cfs will need to have their tablenames reset. CFMetaData are
immutable, so new ones get created with the
+ // same ids.
+ List<CFMetaData> newCfs = new
ArrayList<CFMetaData>(ksm.cfMetaData().size());
+ for (CFMetaData oldCf : ksm.cfMetaData().values())
+ {
+ if (purgeOldCfs)
+ CFMetaData.purge(oldCf);
+ newCfs.add(CFMetaData.renameTable(oldCf, newName));
+ }
+ return new KSMetaData(newName, ksm.strategyClass,
ksm.replicationFactor, newCfs.toArray(new CFMetaData[newCfs.size()]));
+ }
@Override
public ICompactSerializer getSerializer()
@@ -84,7 +101,22 @@ public class RenameKeyspace extends Migr
renameKsStorageFiles(oldName, newName);
KSMetaData oldKsm = DatabaseDescriptor.getTableDefinition(oldName);
- KSMetaData newKsm = KSMetaData.rename(oldKsm, newName, true);
+ for (CFMetaData cfm : oldKsm.cfMetaData().values())
+ CFMetaData.purge(cfm);
+ KSMetaData newKsm = rename(oldKsm, newName, true);
+ for (CFMetaData cfm : newKsm.cfMetaData().values())
+ {
+ try
+ {
+ CFMetaData.map(cfm);
+ }
+ catch (ConfigurationException ex)
+ {
+ // throwing RTE since this this means that the table,cf
already maps to a different ID, which it can't
+ // since we've already checked for an existing table with the
same name.
+ throw new RuntimeException(ex);
+ }
+ }
// ^^ at this point, the static methods in CFMetaData will start
returning references to the new table, so
// it helps if the node is reasonably quiescent with respect to this
ks.
DatabaseDescriptor.clearTableDefinition(oldKsm, newVersion);
Modified: cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/SchemaLoader.java Wed May 5
15:34:07 2010
@@ -18,6 +18,7 @@
package org.apache.cassandra;
+import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.KSMetaData;
@@ -33,7 +34,11 @@ public class SchemaLoader
try
{
for (KSMetaData ksm : DatabaseDescriptor.readTablesFromYaml())
+ {
+ for (CFMetaData cfm : ksm.cfMetaData().values())
+ CFMetaData.map(cfm);
DatabaseDescriptor.setTableDefinition(ksm,
DatabaseDescriptor.getDefsVersion());
+ }
}
catch (ConfigurationException e)
{
Modified:
cassandra/trunk/test/unit/org/apache/cassandra/db/commitlog/CommitLogHeaderTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/commitlog/CommitLogHeaderTest.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/test/unit/org/apache/cassandra/db/commitlog/CommitLogHeaderTest.java
(original)
+++
cassandra/trunk/test/unit/org/apache/cassandra/db/commitlog/CommitLogHeaderTest.java
Wed May 5 15:34:07 2010
@@ -84,7 +84,6 @@ public class CommitLogHeaderTest extends
@Test
public void byteArray() throws IOException
{
- SchemaLoader.loadSchemaFromYaml();
CommitLogHeader clh = new CommitLogHeader();
assert clh.getCfIdMap().size() > 0;
CommitLogHeader clh2 = CommitLogHeader.serializer.deserialize(new
DataInputStream(new ByteArrayInputStream(clh.toByteArray())));
Modified:
cassandra/trunk/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java?rev=941349&r1=941348&r2=941349&view=diff
==============================================================================
---
cassandra/trunk/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java
(original)
+++
cassandra/trunk/test/unit/org/apache/cassandra/service/EmbeddedCassandraServiceTest.java
Wed May 5 15:34:07 2010
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
+import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.KSMetaData;
@@ -79,7 +80,11 @@ public class EmbeddedCassandraServiceTes
// Manually load tables from the test configuration file.
for (KSMetaData table : DatabaseDescriptor.readTablesFromYaml())
+ {
+ for (CFMetaData cfm : table.cfMetaData().values())
+ CFMetaData.map(cfm);
DatabaseDescriptor.setTableDefinition(table,
DatabaseDescriptor.getDefsVersion());
+ }
cassandra = new EmbeddedCassandraService();
cassandra.init();