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()