You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by gd...@apache.org on 2010/08/17 21:14:49 UTC
svn commit: r986456 - in /cassandra/trunk:
src/java/org/apache/cassandra/avro/ src/java/org/apache/cassandra/config/
src/java/org/apache/cassandra/db/ src/java/org/apache/cassandra/db/clock/
src/java/org/apache/cassandra/hadoop/ src/java/org/apache/cas...
Author: gdusbabek
Date: Tue Aug 17 19:14:49 2010
New Revision: 986456
URL: http://svn.apache.org/viewvc?rev=986456&view=rev
Log:
make TimestampReconciler a singleton. patch by Folke Behrens, reviewed by Gary Dusbabek. CASSANDRA-1319
Modified:
cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
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/db/ColumnFamilyStore.java
cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
cassandra/trunk/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java
cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
cassandra/trunk/test/unit/org/apache/cassandra/db/SuperColumnTest.java
cassandra/trunk/test/unit/org/apache/cassandra/db/clock/TimestampReconcilerTest.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java Tue Aug 17 19:14:49 2010
@@ -74,6 +74,7 @@ public class CassandraServer implements
private final static String D_CF_CFCLOCKTYPE = "Timestamp";
private final static String D_CF_COMPTYPE = "BytesType";
private final static String D_CF_SUBCOMPTYPE = "";
+ private final static String D_CF_RECONCILER = null;
private ThreadLocal<AccessLevel> loginDone = new ThreadLocal<AccessLevel>()
{
@@ -600,13 +601,13 @@ public class CassandraServer implements
ClockType clockType = ClockType.create(cfDef.clock_type == null ? D_CF_CFCLOCKTYPE : cfDef.clock_type.toString());
compare = cfDef.comparator_type == null ? D_CF_COMPTYPE : cfDef.comparator_type.toString();
subCompare = cfDef.subcomparator_type == null ? D_CF_SUBCOMPTYPE : cfDef.subcomparator_type.toString();
- reconcilerName = cfDef.reconciler == null ? null : cfDef.reconciler.toString();
+ reconcilerName = cfDef.reconciler == null ? D_CF_RECONCILER : cfDef.reconciler.toString();
AbstractReconciler reconciler = DatabaseDescriptor.getReconciler(reconcilerName);
if (reconciler == null)
{
if (clockType == ClockType.Timestamp)
- reconciler = new TimestampReconciler(); // default
+ reconciler = TimestampReconciler.instance; // default
else
throw new ConfigurationException("No reconciler specified for column family " + cfDef.name.toString());
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=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Tue Aug 17 19:14:49 2010
@@ -61,11 +61,11 @@ public final class CFMetaData
private static final BiMap<Pair<String, String>, Integer> cfIdMap = HashBiMap.<Pair<String, String>, Integer>create();
- public static final CFMetaData StatusCf = new CFMetaData(Table.SYSTEM_TABLE, SystemTable.STATUS_CF, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "persistent metadata for the local node", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 0, Collections.<byte[],ColumnDefinition>emptyMap());
- public static final CFMetaData HintsCf = new CFMetaData(Table.SYSTEM_TABLE, HintedHandOffManager.HINTS_CF, ColumnFamilyType.Super, ClockType.Timestamp, BytesType.instance, BytesType.instance, new TimestampReconciler(), "hinted handoff data", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 1, Collections.<byte[], ColumnDefinition>emptyMap());
- public static final CFMetaData MigrationsCf = new CFMetaData(Table.SYSTEM_TABLE, Migration.MIGRATIONS_CF, ColumnFamilyType.Standard, ClockType.Timestamp, TimeUUIDType.instance, null, new TimestampReconciler(), "individual schema mutations", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 2, Collections.<byte[], ColumnDefinition>emptyMap());
- public static final CFMetaData SchemaCf = new CFMetaData(Table.SYSTEM_TABLE, Migration.SCHEMA_CF, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "current state of the schema", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 3, Collections. <byte[], ColumnDefinition>emptyMap());
- public static final CFMetaData StatisticsCf = new CFMetaData(Table.SYSTEM_TABLE, StatisticsTable.STATISTICS_CF, ColumnFamilyType.Super, ClockType.Timestamp, UTF8Type.instance, BytesType.instance, new TimestampReconciler(), "persistent CF statistics for the local node", 0, false, 0.01, DEFAULT_GC_GRACE_SECONDS, 0, 4, Collections.<byte[], ColumnDefinition>emptyMap());
+ public static final CFMetaData StatusCf = new CFMetaData(Table.SYSTEM_TABLE, SystemTable.STATUS_CF, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "persistent metadata for the local node", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 0, Collections.<byte[],ColumnDefinition>emptyMap());
+ public static final CFMetaData HintsCf = new CFMetaData(Table.SYSTEM_TABLE, HintedHandOffManager.HINTS_CF, ColumnFamilyType.Super, ClockType.Timestamp, BytesType.instance, BytesType.instance, TimestampReconciler.instance, "hinted handoff data", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 1, Collections.<byte[], ColumnDefinition>emptyMap());
+ public static final CFMetaData MigrationsCf = new CFMetaData(Table.SYSTEM_TABLE, Migration.MIGRATIONS_CF, ColumnFamilyType.Standard, ClockType.Timestamp, TimeUUIDType.instance, null, TimestampReconciler.instance, "individual schema mutations", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 2, Collections.<byte[], ColumnDefinition>emptyMap());
+ public static final CFMetaData SchemaCf = new CFMetaData(Table.SYSTEM_TABLE, Migration.SCHEMA_CF, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "current state of the schema", 0, false, 0.01, 0, DEFAULT_GC_GRACE_SECONDS, 3, Collections. <byte[], ColumnDefinition>emptyMap());
+ public static final CFMetaData StatisticsCf = new CFMetaData(Table.SYSTEM_TABLE, StatisticsTable.STATISTICS_CF, ColumnFamilyType.Super, ClockType.Timestamp, UTF8Type.instance, BytesType.instance, TimestampReconciler.instance, "persistent CF statistics for the local node", 0, false, 0.01, DEFAULT_GC_GRACE_SECONDS, 0, 4, Collections.<byte[], ColumnDefinition>emptyMap());
/**
* @return An immutable mapping of (ksname,cfname) to id.
@@ -241,7 +241,7 @@ public final class CFMetaData
comparator = DatabaseDescriptor.getComparator(cf.comparator_type.toString());
if (cf.subcomparator_type != null)
subcolumnComparator = DatabaseDescriptor.getComparator(cf.subcomparator_type.toString());
- reconciler = (AbstractReconciler)Class.forName(cf.reconciler.toString()).newInstance();
+ reconciler = DatabaseDescriptor.getReconciler(cf.reconciler.toString());
}
catch (Exception ex)
{
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=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java Tue Aug 17 19:14:49 2010
@@ -588,7 +588,7 @@ public class DatabaseDescriptor
if (reconciler == null)
{
if (cf.clock_type == ClockType.Timestamp)
- reconciler = new TimestampReconciler(); // default
+ reconciler = TimestampReconciler.instance; // default
else
throw new ConfigurationException("No reconciler specified for column family " + cf.name);
}
@@ -668,38 +668,34 @@ public class DatabaseDescriptor
public static AbstractReconciler getReconciler(String reconcileWith) throws ConfigurationException
{
- if (reconcileWith == null || "".equals(reconcileWith))
+ if (reconcileWith == null || reconcileWith.length() == 0)
{
return null;
}
-
+
+ String className = reconcileWith.indexOf('.') >= 0 ? reconcileWith : TimestampReconciler.class.getPackage().getName() + '.' + reconcileWith;
Class<? extends AbstractReconciler> reconcilerClass;
+ try
{
- String className = reconcileWith.contains(".") ? reconcileWith : TimestampReconciler.class.getPackage().getName() + "." + reconcileWith;
- try
- {
- reconcilerClass = (Class<? extends AbstractReconciler>)Class.forName(className);
- }
- catch (ClassNotFoundException e)
- {
- throw new ConfigurationException("Unable to load class " + className);
- }
+ reconcilerClass = (Class<? extends AbstractReconciler>) Class.forName(className);
}
+ catch (ClassNotFoundException e)
+ {
+ throw new ConfigurationException("Unable to load class " + className);
+ }
+
try
{
- return reconcilerClass.getConstructor().newInstance();
+ Field field = reconcilerClass.getDeclaredField("instance");
+ return (AbstractReconciler) field.get(null);
}
- catch (InstantiationException e)
+ catch (NoSuchFieldException e)
{
- ConfigurationException ex = new ConfigurationException(e.getMessage());
- ex.initCause(e);
- throw ex;
+ throw new ConfigurationException("Invalid reconciler: must define a public static instance field.", e);
}
- catch (Exception e)
+ catch (IllegalAccessException e)
{
- ConfigurationException ex = new ConfigurationException(e.getMessage());
- ex.initCause(e);
- throw ex;
+ throw new ConfigurationException("Invalid reconciler: must define a public static instance field.", e);
}
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Tue Aug 17 19:14:49 2010
@@ -202,7 +202,7 @@ public class ColumnFamilyStore implement
ClockType.Timestamp,
columnComparator,
null,
- new TimestampReconciler(),
+ TimestampReconciler.instance,
"",
0,
false,
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java Tue Aug 17 19:14:49 2010
@@ -24,8 +24,12 @@ import org.apache.cassandra.db.IClock.Cl
* Keeps the column with the highest timestamp. If both are equal
* return the left column.
*/
-public class TimestampReconciler extends AbstractReconciler
+public final class TimestampReconciler extends AbstractReconciler
{
+ public static final TimestampReconciler instance = new TimestampReconciler();
+
+ private TimestampReconciler()
+ {/* singleton */}
public Column reconcile(Column left, Column right)
{
Modified: cassandra/trunk/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/hadoop/ColumnFamilyRecordReader.java Tue Aug 17 19:14:49 2010
@@ -303,7 +303,7 @@ public class ColumnFamilyRecordReader ex
private IColumn unthriftifySuper(SuperColumn super_column)
{
ClockType clockType = ClockType.Timestamp; // TODO generalize
- AbstractReconciler reconciler = new TimestampReconciler(); // TODO generalize
+ AbstractReconciler reconciler = TimestampReconciler.instance; // TODO generalize
org.apache.cassandra.db.SuperColumn sc = new org.apache.cassandra.db.SuperColumn(super_column.name, subComparator, clockType, reconciler);
for (Column column : super_column.columns)
{
Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Tue Aug 17 19:14:49 2010
@@ -948,7 +948,7 @@ public class CassandraServer implements
if (reconciler == null)
{
if (clockType == ClockType.Timestamp)
- reconciler = new TimestampReconciler(); // default
+ reconciler = TimestampReconciler.instance; // default
else
throw new ConfigurationException("No reconciler specified for column family " + cf_def.name);
Modified: cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/config/DatabaseDescriptorTest.java Tue Aug 17 19:14:49 2010
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNot
import org.apache.avro.specific.SpecificRecord;
import org.apache.cassandra.CleanupHelper;
+import org.apache.cassandra.db.clock.TimestampReconciler;
import org.apache.cassandra.db.migration.AddKeyspace;
import org.apache.cassandra.locator.SimpleStrategy;
import org.apache.cassandra.io.SerDeUtils;
@@ -42,6 +43,13 @@ public class DatabaseDescriptorTest
assert actual.equals(record) : actual + " != " + record;
return actual;
}
+
+ @Test
+ public void testGetReconciler() throws ConfigurationException
+ {
+ assert DatabaseDescriptor.getReconciler("TimestampReconciler") == TimestampReconciler.instance;
+ assert DatabaseDescriptor.getReconciler(TimestampReconciler.class.getName()) == TimestampReconciler.instance;
+ }
@Test
public void testShouldHaveConfigFileNameAvailable()
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Tue Aug 17 19:14:49 2010
@@ -81,7 +81,7 @@ public class DefsTest extends CleanupHel
@Test
public void addNewCfToBogusTable() throws InterruptedException
{
- CFMetaData newCf = new CFMetaData("MadeUpKeyspace", "NewCF", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "new cf", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
+ CFMetaData newCf = new CFMetaData("MadeUpKeyspace", "NewCF", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "new cf", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
try
{
new AddColumnFamily(newCf).apply();
@@ -106,7 +106,7 @@ public class DefsTest extends CleanupHel
assert DatabaseDescriptor.getDefsVersion().equals(prior);
// add a cf.
- CFMetaData newCf1 = new CFMetaData("Keyspace1", "MigrationCf_1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "Migration CF ", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
+ CFMetaData newCf1 = new CFMetaData("Keyspace1", "MigrationCf_1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "Migration CF ", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
Migration m1 = new AddColumnFamily(newCf1);
m1.apply();
UUID ver1 = m1.getVersion();
@@ -156,7 +156,7 @@ public class DefsTest extends CleanupHel
final String cf = "BrandNewCf";
KSMetaData original = DatabaseDescriptor.getTableDefinition(ks);
- CFMetaData newCf = new CFMetaData(original.name, cf, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "A New Column Family", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
+ CFMetaData newCf = new CFMetaData(original.name, cf, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A New Column Family", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
assert !DatabaseDescriptor.getTableDefinition(ks).cfMetaData().containsKey(newCf.cfName);
new AddColumnFamily(newCf).apply();
@@ -271,7 +271,7 @@ public class DefsTest extends CleanupHel
public void addNewKS() throws ConfigurationException, IOException, ExecutionException, InterruptedException
{
DecoratedKey dk = Util.dk("key0");
- CFMetaData newCf = new CFMetaData("NewKeyspace1", "AddedStandard1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "A new cf for a new ks", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
+ CFMetaData newCf = new CFMetaData("NewKeyspace1", "AddedStandard1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new cf for a new ks", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
KSMetaData newKs = new KSMetaData(newCf.tableName, SimpleStrategy.class, null, 5, newCf);
new AddKeyspace(newKs).apply();
@@ -429,7 +429,7 @@ public class DefsTest extends CleanupHel
new AddKeyspace(newKs).apply();
assert DatabaseDescriptor.getTableDefinition("EmptyKeyspace") != null;
- CFMetaData newCf = new CFMetaData("EmptyKeyspace", "AddedLater", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, new TimestampReconciler(), "A new CF to add to an empty KS", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
+ CFMetaData newCf = new CFMetaData("EmptyKeyspace", "AddedLater", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new CF to add to an empty KS", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap());
//should not exist until apply
assert !DatabaseDescriptor.getTableDefinition(newKs.name).cfMetaData().containsKey(newCf.cfName);
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/SuperColumnTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/SuperColumnTest.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/SuperColumnTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/SuperColumnTest.java Tue Aug 17 19:14:49 2010
@@ -29,7 +29,7 @@ public class SuperColumnTest
{
@Test
public void testMissingSubcolumn() {
- SuperColumn sc = new SuperColumn("sc1".getBytes(), LongType.instance, ClockType.Timestamp, new TimestampReconciler());
+ SuperColumn sc = new SuperColumn("sc1".getBytes(), LongType.instance, ClockType.Timestamp, TimestampReconciler.instance);
sc.addColumn(new Column(getBytes(1), "value".getBytes(), new TimestampClock(1)));
assertNotNull(sc.getSubColumn(getBytes(1)));
assertNull(sc.getSubColumn(getBytes(2)));
Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/clock/TimestampReconcilerTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/clock/TimestampReconcilerTest.java?rev=986456&r1=986455&r2=986456&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/clock/TimestampReconcilerTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/clock/TimestampReconcilerTest.java Tue Aug 17 19:14:49 2010
@@ -30,7 +30,7 @@ import org.junit.Test;
public class TimestampReconcilerTest
{
- private static final TimestampReconciler reconciler = new TimestampReconciler();
+ private static final TimestampReconciler reconciler = TimestampReconciler.instance;
@Test
public void testReconcileNormal()